ラムダ計算ジェネレータ


10

他にこの質問をする場所がわからないので、ここがいい場所だといいのですが。

ラムダ計算ジェネレータを作成することが可能かどうか知りたいだけです。基本的に、無限の時間を与えられて、可能なあらゆるラムダ計算関数を生成するループ。(文字列の形のように)。

ラムダ計算は非常に単純であり、その表記にいくつかの要素しかないため、最も単純な組み合わせから始めて、その表記要素のすべての可能な組み合わせを生成し、それによってすべての可能なラムダを生成することは可能かもしれないと考えました微積分関数。

もちろん、ラムダ計算についてはほとんど何も知らないので、これが本当に可能かどうかはわかりません。

それは...ですか?もしそうなら、私が想像したようにそれはかなり簡単ですか、それとも技術的には可能ですが、実際には不可能であるほど難しいですか?

PS。私はベータ削減関数について話しているのではなく、すべてのラムダ計算関数のすべての有効な表記について話しているだけです。

回答:


19

確かに、これは標準的なエンコードの練習です。

p:N2N

p(n,m)=(n+m)(n+m+1)2+n

kn,mp(n,m)=k

x0,x1,x2,

ilambda(i)

  • ij=i/2xj
  • ij=(i1)/2
    • jk=j/2n,mp(n,m)=kN=lambda(n),M=lambda(m)(NM)
    • jk=(j1)/2n,mp(n,m)=kM=lambda(m)(λxn. M)

Λ

ΛN+(Λ2+N×Λ)

これは「構文上、ラムダ項として解釈されます。1)変数(自然として表される)、2)アプリケーション(2つのラムダ項で作成)、および3)抽象化(ペア変数/自然+ラムダ項) )」

N2NpN+NN

この手順は一般的であり、コンテキストフリーの文法によって生成されたほとんどすべての言語で機能します。これにより、上記のものと同様の同型が提供されます。


うわー、ありがとうございます。これが疑似コードであることを示すことができるでしょうか?私はcsの学位を持っていないので、私は間違いなくそれを理解するでしょう。
合法スタック

3
lambda(n)if n%2==0 ...n,mp(n,m)=kn,mn,mk

1
a=12(8k+11),b=12a(a+1),n=bk,m=an

12

はい。考えられるすべてのASCII文字列を列挙するものを取ります。各出力について、それが関数を定義する有効なラムダ計算構文であるかどうかを確認してください。そうでない場合は、スキップしてください。(そのチェックを行うことができます。)これはすべてのラムダ計算関数を列挙します。


4
基本的に、このような問題はすべてタイピングモンキーを呼び出すことで解決されます...
xuq01

5
または、ラムダ計算の項を直接列挙することもできます。すべての出力は適切にフォーマットされた用語であるため、ランダムな文字列よりもはるかに高速です。それはタイピングモンキーをシェイクスピアプレイジェネレーターに置き換えるようなものです。
Dan D.

11

すでに述べたように、これは文脈自由言語からの用語を列挙するだけなので、確実に実行可能です。しかし、背後にはもっと興味深い数学があり、分析的組み合わせ論の分野に入ります。

バイナリラムダ計算の用語カウントと生成の項」には、列挙問題の処理などが含まれています。物事を簡単にするために、バイナリラムダカルラスと呼ばれるものを使用します。これは、De Bruijnインデックスを使用したラムダ項の単なるエンコードであるため、変数に名前を付ける必要はありません。

その論文には、生成アルゴリズムを実装する具体的なHaskellコードも含まれています。それは間違いなく効果的に可能です。

私はたまたまジュリアで彼らのアプローチの実装を書きました。


5

承知しました。ラムダ項の定義に従って直接生成できます。

Haskellでは、最初に型を定義し、

data LC a = Var a | App (LC a) (LC a) | Lam a (LC a)

instance Show a => Show (LC a) where
    show (Var i)   = [c | c <- show i, c /= '\'']
    show (App m n) = "(" ++ show m ++ " " ++ show n ++ ")"
    show (Lam v b) = "(^" ++ show (Var v) ++ "." ++ show b ++ ")"

そして次に

lambda :: [a] -> [LC a]
lambda vars = terms 
  where
  terms = fjoin [ map Var vars ,
                  fjoin [[App t s | t <- terms] | s <- terms] ,
                  fjoin [[Lam v s | v <- vars ] | s <- terms] ]

  fjoin :: [[a]] -> [a]
  fjoin xs = go (take 1 xs) (drop 1 xs)      -- fair join
      where 
      go [] [] = []
      go a  b  = reverse (concatMap (take 1) a) ++ go 
                     (take 1 b ++ [t | (_:t) <- a]) (drop 1 b)

たとえば、次のように列挙します

> take 20 $ lambda "xyz"
[x,y,(x x),z,(y x),(^x.x),(x y),(^y.x),((x x) x),(^x.y),(y y),(^z.x),(x (x x)),
 (^y.y),(z x),(^x.(x x)),((x x) y),(^z.y),(y (x x)),(^y.(x x))]

> take 5 $ drop 960 $ lambda "xyz"
[(((x x) y) (z x)),(^y.(^x.((x x) (x x)))),((^x.(x x)) (^x.(x x))),(^x.((^z.x) y
)),((z x) ((x x) y))]

Ω=(λx.xx)(λx.xx)

fjoin等価であるオメガモナドさんdiagonal


0

正規表現からサンプル文字列を生成できるツールをオンラインで見つけました:https : //www.browserling.com/tools/text-from-regex。次のように入力すると、多数のサンプルラムダ項を生成できます。

(\( (lambda \w\. )* \w+ \))* 

もちろん、入れ子のレベルが任意の用語を取得するには、コンテキストフリー文法を使用する必要があります。これは、正規表現よりも言語を定義するためのより記述的なツールです。私は、文脈自由文法定義に基づいてサンプル言語文を生成するための既存のツールに出会ったことはありませんが、作成できない理由はありません。


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