フラットな式のための最も単純な完全なコンビネーター基底ペア


9

Chris Okasakiの論文「Flattening Combinators:Surviving withoutカッコなし」では、アプリケーション演算子や括弧を必要とせずに、チューリング完全式をエンコードするための基礎として2つのコンビネータで十分かつ必要であることを示しています。

アプリケーションオペレーターでプレフィックスコーディングのSおよびKコンビネーターを介した「バイナリラムダ計算と組み合わせロジック」のJohn Trumpの組み合わせロジックのエンコーディングと比較して、フラットな式に2つのコンビネーターを必要とするだけでコード密度が最適化されます。結果のGoedel番号付けは、すべての整数を有効な整形式の閉じた式にマップします。ほとんどの計算と最小の記述長に関連するesolangとは異なり、その正規表現は通常、構文的に無効なプログラムの記述を許可します。

ただし、岡崎のエンコーディングは、ラムダ計算の用語からビット文字列への一方向のマッピングで最も役立つことを意味していました。実際の置換命令として使用する場合、この削減で使用される2つのコンビネーターは比較的複雑であるため、必ずしも逆ではありません。

アプリケーションオペレーターを必要としない最も単純で完全なコンビネーターの基本ペアは何ですか?


1
該当するかどうかはわかりませんが、単一の用語で構成されるラムダ計算のベースがあることに注意してください。これにより、ゲーデルの番号付けがさらに簡単になります。cs.uu.nl/research/techreps/repo/CS-1989/1989-14.pdf
カイ

回答:


2

ほぼ1年後、これに戻ると、投稿する前にいくつかの重要な研究を見逃していたことに気付きました。

Jotは、コンパクトなゲーデル番号で表すことができる2つの比較的単純なコンビネーターB&Xで、私が求めていたものの案に合うようです。

私は彼のリファレンス実装をPythonで単純化しました:

def S(x): return lambda y: lambda z: x(z)(y(z))
def K(x): return lambda y: x
def X(x): return x(S)(K)
def B(x): return lambda y: lambda z: x(y(z))
def I(x): return x
def J(n): return (B if n & 1 else X)(J(n >> 1)) if n else I

J(n)は、ゲーデル番号nで表されるプログラムを示すビルドアップ関数を返します。

B(チャーチ符号化乗算と同等)は、機能アプリケーション(括弧)の機能を果たし、単一基底IotaコンビネーターXのS / K半分を分離できます。

私が(ほぼ)恥知らずに、この言語の発明者であるChris BarkerのWebサイトから2000年頃に盗んでいる、この言語のいくつかの重要な特性があります。

Jotは通常の構文言語ですが、チューリング完全です。J(n)の実装から、ホスト言語が末尾再帰をサポートしている場合、ビット文字列プログラム形式を解析するために必要なスタックスペースがないことがわかります。

チューリング完全性の証明は、Chrisのサイトにもあり、SおよびKコンビネーターを使用して既知のチューリング完全な組み合わせロジックを実装しています。

K  ==> 11100
S  ==> 11111000
AB ==> 1[A][B], where A & B are arbitrary CL combinators built up from K & S

Jotには構文エラーはありません。Goedel番号nが与えられたすべてのプログラムが有効なプログラムです。これは、構文解析を単純化するだけでなく、理論的には、不正なプログラムをスキップする必要のあるチューリング完全なエンコーディングよりもJotをはるかに節約できるため、私自身の研究にとっておそらく最も重要な側面です。

Jotで関数のコルモゴロフの複雑さを見つけるという半決定的な問題を、総当たりで「解決」するためのツールをいくつか書きました。プログラマーに依存して関数のマッピングの非常に特徴的なトレーニング例を指定し、すべてのトレーニング例が一致するまですべてのJotプログラムを列挙し、最後に、見つかった関数が元の冗長実装と等しいことの証明を試みます。

現在のところ、私の限られたリソースで最大40ビットまでしか機能しません。私はSATソルバーで書き換えを試みて、はるかに大きなプログラムを学習しています。バインドされたネストされたクロージャーをブール式としてアンロールする方法を知っている場合は、私の新しい質問を手伝ってください。

ここで、簡潔さで知られているJohn TrompのBinary Lambda Calculusとの興味深い比較について説明しますが、構文エラーの可能性があるという問題があります。次のプログラムは、私の学習プログラムによって数秒で生成されました。

Function    Jot       Binary Lambda Calculus   |J| |B|
--------|----------|--------------------------|---|---
SUCC      J(18400)  "000000011100101111011010" 15  24
CHURCH_0  J(154)    "000010"                    8   6
CHURCH_1  J(0)      "00000111010"               1  11
CHURCH_2  J(588826) "0000011100111010"         20  16
IS_ZERO   J(5)      "00010110000000100000110"   3  23
MUL       J(280)    "0000000111100111010"       9  19
EXP       J(18108)  "00000110110"              15  11
S         J(8)      "00000001011110100111010"   4  23
K         J(4)      "0000110"                   3   7
AND       J(16)     "0000010111010000010"       5  19
OR        J(9050)   "00000101110000011010"     14  20

私自身の実験から、Jotがより小さなプログラムにつながるという仮説は、私のプログラムが単純な関数を学習し、それらを構成し、改善された天井からより大きな関数を学習するにつれてゆっくりと確認されています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.