ラムダ計算( λ計算とも表記)は、変数の束縛と置換を用いた関数の抽象化と適用に基づく計算を表現する数理論理学の形式体系である。この記事のテーマである型なしラムダ計算は、あらゆるチューリングマシンをシミュレートするために使用できる(逆もまた同様)計算の汎用モデルである。これは、数学者アロンゾ・チャーチが1930年代に数学の基礎に関する研究の一環として導入した。1936年、チャーチは論理的に一貫した定式化を発見し、1940年にそれを文書化した。
ラムダ計算は、ラムダ項の構築とそれに対する簡約演算の実行から成ります。最も単純なラムダ計算では、項は以下の規則のみを使用して構築されます。[a]
- 変数はパラメータを表す文字または文字列です。
- : ラムダ抽象化は、境界変数(λ と点/ドット.の間) を入力として受け取り、本体を返す関数定義です。
- : 関数を引数に適用するアプリケーション。 と はどちらもラムダ項です。
削減操作には以下が含まれます。
- : α変換。式内のバインドされた変数の名前を変更します。名前の衝突を回避するために使用されます。
- : β-削減、[b]抽象化の本体内の引数式で束縛変数を置き換える。
De Bruijn インデックスを使用すると、名前の衝突がなくなるため、α 変換は不要になります。削減手順を繰り返し適用して最終的に終了すると、 Church–Rosser 定理によりβ 正規形が生成されます。
Iota や Jotなどのユニバーサル ラムダ関数を使用する場合、変数名は必要ありません。これらの関数は、さまざまな組み合わせで自分自身を呼び出すことで、任意の関数の動作を作成できます。
説明と応用
ラムダ計算はチューリング完全であり、つまりあらゆるチューリングマシンをシミュレートするために使用できる計算の汎用モデルです。[3]その名前の由来であるギリシャ文字のラムダ(λ)は、ラムダ式とラムダ項で関数内の変数のバインディングを示すために使用されます。
ラムダ計算は、型なしまたは型付きです。型付きラムダ計算では、関数は、与えられた入力の「型」のデータを受け入れられる場合にのみ適用できます。型付きラムダ計算は、型なしラムダ計算よりも表現できるものが少ないという意味で、この記事の主な主題である型なしラムダ計算よりも弱いです。一方、型付きラムダ計算では、より多くのことを証明できます。たとえば、単純型付きラムダ計算では、すべての評価戦略がすべての単純型付きラムダ項に対して終了するのに対し、型なしラムダ項の評価は終了する必要がないという定理があります (以下を参照)。さまざまな型付きラムダ計算が存在する理由の 1 つは、計算に関する強力な定理を証明できることを諦めずに、より多くのこと (型なし計算でできること) を実行したいという要望です。
ラムダ計算は、数学、哲学、[4] 言語学、[5] [6]コンピュータサイエンスのさまざまな分野で応用されています。[7] [8]ラムダ計算は、プログラミング言語の理論の発展に重要な役割を果たしてきました。関数型プログラミング言語はラムダ計算を実装しています。ラムダ計算は、圏論の現在の研究テーマでもあります。[9]
歴史
ラムダ計算は、1930年代に数学者アロンゾ・チャーチによって数学の基礎研究の一環として導入されました。[10] [c]元のシステムは、1935年にスティーブン・クリーネとJB・ロッサーがクリーネ・ロッサーのパラドックスを考案したときに論理的に矛盾していることが示されました。[11] [12]
その後、1936年にチャーチは計算に関連する部分だけを切り出して出版しました。これは現在では型なしラムダ計算と呼ばれています。 [13] 1940年には、計算的には弱いが論理的に一貫性のあるシステムも発表しました。これは単純型付きラムダ計算と呼ばれています。[14]
1960年代にプログラミング言語との関係が明らかになるまで、ラムダ計算は単なる形式論に過ぎなかった。リチャード・モンタギューや他の言語学者による自然言語の意味論への応用により、ラムダ計算は言語学[15]とコンピュータサイエンス[16]の両方で尊敬される地位を獲得し始めた。
の起源λシンボル
チャーチがラムダ計算における関数抽象化の表記としてギリシャ文字のラムダ(λ) を使用した理由については不明な点があるが、これはチャーチ自身の説明が矛盾しているからかもしれない。Cardone と Hindley (2006) によると、
ところで、チャーチはなぜ「λ」という表記法を選んだのでしょうか。[1964年にハラルド・ディクソンに宛てた未発表の手紙]で、チャーチは、それがホワイトヘッドとラッセルがクラス抽象化に使用した表記法「 」から来ており、関数抽象化とクラス抽象化を区別するために「 」を「 」に変更し、次に印刷しやすいように「 」を「λ」に変更したと明言しています。
この起源は[Rosser, 1984, p.338]でも報告されています。一方、チャーチは晩年、2人の質問者に対し、この選択はより偶然のものであり、記号が必要だったが、たまたまλが選ばれただけだと語っています。
ダナ・スコットも、さまざまな公開講演でこの問題に取り組んでいます。[17] スコットは、かつてチャーチの元教え子で義理の息子であるジョン・W・アディソン・ジュニアにラムダ記号の起源について質問したところ、アディソンは義父に次のようなポストカードを書いたと語っています。
チャーチ教授様
スコットによれば、チャーチの返答は、次のような注釈を付けてポストカードを返送することだけだった。「イニー、ミーニー、ミニー、モー」。
非公式な説明
モチベーション
計算可能な関数は、コンピュータ サイエンスと数学における基本的な概念です。ラムダ計算は、計算の特性を形式的に研究するのに役立つ、計算のシンプルなセマンティクスを提供します。ラムダ計算には、セマンティクスをシンプルにする 2 つの簡略化が組み込まれています。 最初の単純化は、ラムダ計算が関数を「匿名」で扱うことです。関数に明示的な名前は与えません。たとえば、関数
匿名形式では次のように 書き直すことができる。
(これは「 xとyのタプルが」にマッピングされるという意味です)。[d]同様に、関数
匿名形式では次のように書き直すことができる。
入力は単純にそれ自身にマッピングされます。[d]
2 つ目の単純化は、ラムダ計算では単一の入力の関数のみを使用するという点です。たとえば関数のように 2 つの入力を必要とする通常の関数は、単一の入力を受け取り、出力として別の関数を返す同等の関数に作り直すことができます。この関数も単一の入力を受け取ります。たとえば、
作り直すことができる
カリー化と呼ばれるこの方法は、複数の引数を取る関数を、それぞれが 1 つの引数を取る関数のチェーンに変換します。
関数を引数(5, 2)に 適用すると、次の式が得られます。
- 、
一方、カリー化されたバージョンの評価にはもう1つのステップが必要です
- // の定義は内部式で使用されています。これは β 削減のようなものです。
- // の定義はで使用されています。これも β 削減と同様です。
同じ結果に到達します。
ラムダ計算
ラムダ計算は、特定の形式構文で定義されるラムダ項の言語と、ラムダ項を操作するための一連の変換規則で構成されます。これらの変換規則は、方程式理論または操作的定義として見ることができます。
上で説明したように、ラムダ計算のすべての関数は名前がないため、無名関数です。これらは 1 つの入力変数のみを受け入れるため、複数の変数の関数を実装するにはカリー化が使用されます。
ラムダ項
ラムダ計算の構文では、一部の文字列がCプログラムとして有効で一部が無効であるのと同様に、一部の式は有効なラムダ計算式として定義され、一部は無効として定義されます。有効なラムダ計算式は、「ラムダ項」と呼ばれます。
次の3つの規則は、すべての構文的に有効なラムダ項を構築するために適用できる帰納的定義を与える: [e]
- 変数x自体は有効なラムダ項です。
- tがラムダ項でxが変数の場合、 [f] はラムダ項(抽象化と呼ばれる)になります。
- tとs がラムダ項である場合、 はラムダ項です(アプリケーションと呼ばれます)。
それ以外はラムダ項ではありません。つまり、ラムダ項は、これら 3 つの規則を繰り返し適用することで得られる場合にのみ有効です。便宜上、ラムダ項を書くときに一部の括弧を省略できます。たとえば、最も外側の括弧は通常は書きません。どの括弧が省略可能であるかを明示的に説明するには、以下の § 表記法 を参照してください。また、ここで紹介した構文を追加演算で拡張することも一般的であり、これにより、次のような用語の意味を理解できるようになります。この記事の焦点は、拡張のない純粋なラムダ計算ですが、算術演算で拡張されたラムダ項は説明目的で使用されています。
抽象化は、 単一の入力x を受け取り、tを返す§ 無名関数[g]を表します。たとえば、は、tの項を使用して定義された関数を表す抽象化です。抽象化を使用する場合、名前は不要です。構文は、t の項で変数x をバインドします。抽象化を使用した関数の定義は、関数を「設定」するだけで、関数を呼び出すことはありません。
アプリケーションは 、関数tを入力sに適用することを表します。つまり、入力sに対して関数t を呼び出してを生成するという動作を表します。
ラムダ項は、項(関数定義を表す)などの、バインドされていない変数を参照する場合があります。この項では、変数y は定義されておらず、未知数とみなされます。抽象化は構文的に有効な項であり、入力をまだ不明なyに追加する関数を表します。
括弧は用語の曖昧さを解消するために必要になる場合があります。例えば、
- は形式的であり、したがって抽象的であるが、
- 形式であるため、アプリケーションです。
例 1 と 2 は異なる用語を表し、括弧の位置のみが異なります。これらは意味が異なります。例 1 は関数定義ですが、例 2 は関数適用です。ラムダ変数x は、両方の例でプレースホルダーです。
ここで、例 1 は関数を定義します。ここで、 は入力 を持つ無名関数です。一方、例 2 は、 N に適用される M です。ここで、は入力 に適用されるラムダ項です。例 1 と例 2 はどちらも恒等関数に評価されます。
関数を操作する関数
ラムダ計算では、関数は「ファーストクラスの値」として扱われるため、関数は入力として使用されることもあれば、他の関数からの出力として返されることもあります。
たとえば、ラムダ項は恒等関数を表します。さらに、は定数関数 を表します。定数関数は、入力に関係なく常に を返す関数です。関数を操作する関数の例として、関数合成はと定義できます。
「同等性」と「削減」には、ラムダ項を「同等の」ラムダ項に「削減」できるようにする概念がいくつかあります。
アルファ等価性
ラムダ項で定義できる同値性の基本的な形式は、アルファ同値性です。これは、抽象化における束縛変数の特定の選択は(通常は)重要ではないという直感を捉えています。たとえば、およびはアルファ同値なラムダ項であり、どちらも同じ関数(恒等関数)を表します。項およびは抽象化で束縛されていないため、アルファ同値ではありません。多くのプレゼンテーションでは、アルファ同値なラムダ項を識別するのが一般的です。
β 減少を定義するには、次の定義が必要です。
自由変数
項の自由変数 [ h]は抽象化によって束縛されていない変数です。式の自由変数の集合は帰納的に定義されます。
たとえば、恒等式を表すラムダ項には自由変数はありませんが、関数には 1 つの自由変数があります。
キャプチャ回避の代替
、および がラムダ項であり、およびが変数であるとします。この表記は、キャプチャを回避する方法でを に置き換えることを示しています。これは次のように定義されます。
- ;をに置き換える と、
- ;を に置き換えた場合、( ではない)は残る
- ; 置換はアプリケーションの両側に分配されます
- ; 抽象化によって束縛された変数は置換の対象とならない。そのような変数を置換しても抽象化は変更されない。
- およびが の自由変数の中に現れない場合(は に対して「新鮮」であると言われる)、抽象化によって束縛されていない変数の置換は、抽象化された変数が置換項に対して「新鮮」である限り、抽象化の本体内で進行します。
たとえば、、 などです。
新鮮さの条件(が の自由変数に含まれていないことを要求する)は、置換によって関数の意味が変わらないようにするために重要です。
たとえば、鮮度条件を無視する置換はエラーを引き起こす可能性があります: 。この誤った置換により、定数関数が恒等関数 に変換されます。
一般に、新鮮さの条件を満たさない場合は、まず適切な新しい変数を使用してアルファ名前変更することで改善できます。たとえば、置換の正しい概念に戻ると、抽象化では、新しい変数 で名前を変更して を取得し、関数の意味は置換によって保持されます。
β還元
β-簡約規則[b] は、形式 を適用すると項 に簡約されると述べています。 表記は、 β-簡約されて になることを示すために使用されます。たとえば、任意の に対して、となります。これは、 が実際に恒等関数であることを示しています。同様に、は、 が定数関数であることを示しています。
ラムダ計算は、 HaskellやStandard MLのような関数型プログラミング言語の理想化されたバージョンとして見ることができます。この見方では、β 還元は計算ステップに対応します。このステップは、還元するアプリケーションがなくなるまで、追加の β 還元によって繰り返すことができます。ここで示す型なしラムダ計算では、この還元プロセスは終了しない場合があります。たとえば、項 を考えてみましょう。ここではです。つまり、項 は単一の β 還元でそれ自体に還元されるため、還元プロセスが終了することはありません。
型なしラムダ計算のもう 1 つの側面は、異なる種類のデータを区別しないことです。たとえば、数値のみを操作する関数を記述することが望ましい場合があります。ただし、型なしラムダ計算では、関数が真理値、文字列、またはその他の数値以外のオブジェクトに適用されることを防ぐ方法はありません。
正式な定義
意味
ラムダ式は次の要素で構成されます。
- 変数v 1、v 2、 ...;
- 抽象記号 λ (ラムダ) と . (ドット)
- 括弧()。
ラムダ式の集合Λは、帰納的に定義できます。
- xが変数の場合、 x ∈ Λ です。
- xが変数でM ∈ Λの場合、(λ x . M ) ∈ Λ です。
- M、N∈Λならば、( MN )∈Λです。
ルール2のインスタンスは抽象化と呼ばれ、ルール3のインスタンスは応用と呼ばれます。[18] § 還元可能な表現を参照
この規則セットは、バッカス・ナウア形式で次のように記述できます。
<式> :== <抽象> | <アプリケーション> | <変数>
<抽象> :== λ <変数> . <式>
<アプリケーション> :== ( <式> <式> )
<変数> :== v1 | v2 | ...
表記
ラムダ式の表記を整理するために、通常は次の規則が適用されます。
- 一番外側の括弧は削除されます: ( M N ) の代わりにM N になります。
- アプリケーションは左結合であると仮定されており、 ( ( MN ) P )の代わりにMNPと書くこともできる。 [ 19 ]
- 全ての変数が1文字の場合、応用部分のスペースは省略できる:MNPではなくMNP 。[20]
- 抽象化の本体は可能な限り右に拡張されます。つまり、λ x . MN はλ x .( MN ) を意味し、(λ x . M ) Nを意味するわけではありません。
- 抽象化のシーケンスは短縮される:λ x .λ y .λ z . Nはλ xyz . Nと略される。[21] [19]
自由変数と束縛変数
抽象化演算子 λ は、抽象化の本体のどこにあっても、その変数をバインドすると言われます。抽象化のスコープ内にある変数は、バインドされていると言われます。式 λ x . Mでは、 λ x の部分は、変数x がλ x をMの前に追加することによってバインドされることを示すヒントとして、バインダーと呼ばれることがよくあります。その他のすべての変数は、フリーと呼ばれます。たとえば、式 λ y . xxyでは、yはバインド変数で、xはフリー変数です。また、変数は最も近い抽象化によってバインドされます。次の例では、式内のxの単一の出現は、2 番目のラムダによってバインドされています: λ x . y (λ x . zx )。
ラムダ式の自由変数の集合Mは FV( M )と表され、項の構造の再帰によって次のように定義されます。
- FV( x ) = { x }、ここでxは変数です。
- FV(λ x . M ) = FV( M ) \ { x }. [i]
- FV( MN ) = FV( M ) ∪ FV( N )。[j]
自由変数を含まない式は閉じていると言われます。閉じたラムダ式はコンビネータとも呼ばれ、組み合わせ論理の項と同等です。
削減
ラムダ式の意味は、式をどのように簡約できるかによって定義されます。[22]
削減には3つの種類があります:
- α変換:結合変数の変更。
- β-削減: 関数をその引数に適用する;
- η-還元: 外延性の概念を捉えます。
また、結果として生じる同値性についても言及します。2 つの式が同じ式に α 変換できる場合、それらの式 はα 同値です。β 同値性と η 同値性も同様に定義されます。
redexという用語は、簡約可能な表現の略で、簡約規則の 1 つによって簡約できる部分項を指します。たとえば、 (λ x . M ) N は、 MのxをNに置き換えることを表す β-redex です。redex が簡約される式は、その縮約と呼ばれます。 (λ x . M ) Nの縮約はM [ x := N ]です。[b]
xがMにおいて自由でない場合、 λ x。M xも η-redex であり、Mの縮約を持つ。
α変換
α変換(アルファ変換)はα名前変更とも呼ばれ、[23]バインドされた変数名を変更することができます。たとえば、λ x . xのα変換はλ y . yを生成する可能性があります。α変換によってのみ異なる項はα同等と呼ばれます。ラムダ計算の使用では、α同等の項は同等であるとみなされることがよくあります。
α 変換の正確なルールは、完全に自明というわけではありません。まず、抽象化を α 変換する場合、名前が変更される変数出現は、同じ抽象化にバインドされているものだけです。たとえば、 λ x .λ x . xの α 変換は λ y .λ x . xになる可能性がありますが、 λ y .λ x . yになることはできません。後者は元の意味とは異なります。これは、変数シャドウイングというプログラミング概念に似ています。
2 番目に、変数が異なる抽象化によってキャプチャされる結果になる場合、α 変換は不可能です。たとえば、λ x .λ y . xでx をyに置き換えると、λ y .λ y . yになりますが、これはまったく同じではありません。
静的スコープを持つプログラミング言語では、α 変換を使用して、変数名が包含スコープ内の名前をマスクしないようにすることで、名前解決を簡素化できます( 「名前解決を容易にするための α 名変更」を参照)。
De Bruijn 指数表記では、任意の 2 つの α 同値項は構文的に同一です。
代替
置換はM [ x := N ] と書かれ、式M内の変数xのすべての自由な出現を式Nに置き換えるプロセスです。ラムダ計算の項の置換は、項の構造の再帰によって次のように定義されます (注: x と y は変数のみですが、 M と N は任意のラムダ式です)。
- x [ x := N ] = N
- y [ x := N ] = y、x ≠ yの場合
- ( M 1 M 2 )[ x := N ] = M 1 [ x := N ] M 2 [ x := N ]
- (λ x . M )[ x := N ] = λ x . M
- (λ y . M )[ x := N ] = λ y .( M [ x := N ])、x ≠ yかつy ∉ FV( N ) の場合FVについては上記を参照
抽象表現に代入するには、式をα変換する必要がある場合があります。たとえば、(λ x . y )[ y := x ] が λ x . xになるのは正しくありません。代入されたx は自由であるはずが、結局は束縛されているからです。この場合の正しい代入は、α同値性までλ z . xです。代入は、α同値性まで一意に定義されます。上記のキャプチャ回避代入を参照してください。
β還元
β-還元(ベータ還元)は関数適用の考え方を捉えたものである。β-還元は置換の観点から定義される。すなわち、(λ x . M ) Nのβ-還元はM [ x := N ]である。[b]
たとえば、2、7、× のエンコードを想定すると、次の β 縮小が得られます: (λ n . n × 2) 7 → 7 × 2。
β-還元は、カリー・ハワード同型性を介して、自然演繹における局所還元の概念と同じであると見ることができます。
η-還元
η-還元(イータ還元)は拡張性[24]の考え方を表現しており、この文脈では、2つの関数が同じであるためには、すべての引数に対して同じ結果を返す必要があるというものである。η-還元は、 xがf内で自由に現れない場合は常に、λx.fxとfの間で変換を行う。
η-還元は、カリー・ハワード同型性を介して、自然演繹における局所完全性の概念と同じであると見ることができます。
正規形と合流
型なしラムダ計算の場合、書き換え規則としての β 還元は、強く正規化することも弱く正規化することもありません。
しかし、β 還元は α 変換まで進むと合流することが示されます(つまり、2 つの正規形は、一方を他方に α 変換できる場合は等しいとみなします)。
したがって、強く正規化する項と弱く正規化する項はどちらも、一意の正規形を持ちます。強く正規化する項の場合、どの削減戦略でも正規形が得られることが保証されますが、弱く正規化する項の場合、一部の削減戦略では正規形を見つけられない場合があります。
エンコードデータ型
基本的なラムダ計算は、次のサブセクションi、ii、iii、および§ ivに 示すように、算術、ブール値、データ構造、および再帰をモデル化するために使用できます。
ラムダ計算における算術
ラムダ計算で自然数を定義する方法はいくつかありますが、最も一般的なのはチャーチ数であり、次のように定義できます。
- 0 := λ f .λ x . x
- 1 := λ f .λ x . f x
- 2 := λ f .λ x . f ( f x )
- 3 := λ f .λ x . f ( f ( f x ))
など。または、上記の表記法で示した代替構文を使用します。
- 0 := λ fx . x
- 1 := λ fx . f x
- 2 := λ fx . f ( f x )
- 3 := λ fx . f ( f ( f x ))
チャーチ数とは高階関数であり、引数が 1 つの関数fを受け取り、引数が 1 つの別の関数を返します。チャーチ数n は、関数f を引数として受け取り、fのn次合成、つまり関数fをn回合成したものを返す関数です。これはf ( n )と表記され、実際はfのn乗です(演算子として考えた場合)。f (0)は恒等関数として定義されます。このような繰り返し合成 (単一関数fの) は指数法則に従うため、これらの数を算術に使用できます。 (チャーチのオリジナルのラムダ計算では、ラムダ式の形式パラメータは関数本体に少なくとも 1 回出現する必要があり、上記の0の定義は不可能でした。)
プログラムを分析するときによく役立つチャーチ数nについての考え方の1つは、「 n回繰り返す」という命令として考えることです。たとえば、以下に定義するPAIR関数とNIL関数を使用すると、空のリストから始めて「別のx要素を先頭に追加する」をn回繰り返すことで、すべてxに等しいn要素の(連結)リストを構築する関数を定義できます。ラムダ項は
- λ n .λ x . n (ペアx ) NIL
何が繰り返されるか、また、その繰り返される関数がどの引数に適用されるかを変更することで、非常に多くの異なる効果を実現できます。
チャーチ数nを受け取り、fをもう一度適用してn + 1を返す後継関数を定義できます。ここで、「(mf)x」は、関数「f」が「x」に「m」回適用されることを意味します。
- SUCC := λ n .λ f .λ x . f ( n f x )
fのm番目の合成とfのn番目の合成を組み合わせると、 fのm + n番目の合成が得られるため、加算は次のように定義できます。
- プラス := λ m .λ n .λ f .λ x。m f ( n f x )
PLUSは、 2つの自然数を引数として受け取り、自然数を返す関数と考えることができます。
- プラス2 3
そして
- 5
はβ-等価なラムダ式です。mをnに加算することは1をm回加算することで達成できるので、別の定義は次のようになります。
- プラス := λ m .λ n。m成功n [25]
同様に、掛け算は次のように定義できる。
- MULT := λ m .λ n .λ f . m ( n f ) [21]
あるいは
- MULT := λ m .λ n。m (プラスn ) 0
mとnを掛け合わせることは、nを足す関数をm回繰り返し、それをゼロに適用すること と同じである。べき乗はチャーチ数字ではかなり単純な表現で表され、すなわち
- POW := λ b .λ e . e b [1]
正の整数nに対してPRED n = n − 1、PRED 0 = 0で定義される先行関数はかなり難しい。式
- PRED := λ n .λ f .λ x。n (λ g .λ h . h ( g f )) (λ u . x ) (λ u . u )
は、T が(λ g .λ h . h ( g f ))を表す場合、n > 0 に対してT ( n ) (λ u . x ) = (λ h . h ( f ( n −1) ( x )))であることを帰納的に証明することで検証できます。PREDの他の 2 つの定義を以下で示します。1 つは条件文を使用し、もう 1 つはペアを使用します。先行関数を使用すると、減算は簡単です。定義
- SUB := λ m .λ n。n PRED m、
SUB m n は、m > nの場合はm − n を返し、それ以外の場合は0 を返します。
論理と述語
慣例により、ブール値TRUEとFALSEには次の 2 つの定義 (Church ブール値と呼ばれる) が使用されます。
- 真 := λ x .λ y . x
- 偽 := λ x .λ y . y
次に、これら 2 つのラムダ項を使用して、いくつかの論理演算子を定義できます (これらは単なる可能な定式化であり、他の表現も同様に正しい可能性があります)。
- そして := λ p .λ q . p q p
- または := λ p .λ q . p p q
- NOT := λ p . p偽 真
- IFTHENELSE := λ p .λ a .λ b。p a b
これで、次のような論理関数を計算できるようになりました。
- そして真実偽り
- ≡ (λ p .λ q . p q p ) TRUE FALSE → β TRUE FALSE TRUE
- ≡ (λ x .λ y . x ) FALSE TRUE → β FALSE
AND TRUE FALSE はFALSEと同等であることがわかります。
述語はブール値を返す関数です。最も基本的な述語はISZEROで、引数がチャーチ数値0の場合はTRUEを返し、引数がその他のチャーチ数値の場合は FALSE を返します。
- ISZERO := λ n。n (λ x .FALSE) TRUE
次の述語は、最初の引数が 2 番目の引数以下かどうかをテストします。
- LEQ := λ m .λ n .ISZERO (SUB m n )、
m = nなので、LEQ m nかつLEQ n mであれば、数値的等価性の述語を構築するのは簡単です。
述語の利用可能性と、上記のTRUEおよびFALSEの定義により、ラムダ計算で「if-then-else」式を記述することが簡単になります。たとえば、先行関数は次のように定義できます。
- PRED := λ n。n (λ g .λ k .ISZERO ( g 1) k (PLUS ( g k ) 1)) (λ v .0) 0
これは、 n (λ g .λ k .ISZERO ( g 1) k (PLUS ( g k ) 1)) (λ v .0)がn > 0 に対してn − 1 の加算関数であることを帰納的に示すことで検証できます。
ペア
ペア (2 組) は、ペアの Church エンコーディングを使用してTRUEとFALSEで定義できます。たとえば、PAIR はペア ( x、y ) をカプセル化し、FIRST はペアの最初の要素を返し、SECOND は2 番目の要素を返します。
- ペア := λ x .λ y .λ f . f x y
- 最初 := λ p . p真
- 2番目 := λ p . p偽
- NIL := λ x .TRUE
- NULL := λ p。p (λ x .λ y .FALSE)
リンク リストは、空のリストの場合は NIL、要素と小さいリストのペアの場合は NIL として定義できます。述語NULL は、値NILをテストします。(または、NIL := FALSEの場合、構文l (λ h .λ t .λ z .deal_with_head_ h _and_tail_ t ) (deal_with_nil)によって明示的な NULL テストが不要になります)。
ペアの使用例として、 ( m , n )を( n , n + 1)にマッピングするシフト・インクリメント関数は次のように定義できます 。
- Φ := λ x .PAIR (SECOND x ) (SUCC (SECOND x ))
これにより、おそらく前身関数の最も透過的なバージョンを提供できるようになります。
- PRED := λ n .FIRST ( n Φ (PAIR 0 0)).
追加のプログラミングテクニック
ラムダ計算には、かなりの数のプログラミング イディオムがあります。これらの多くは、もともとラムダ計算をプログラミング言語セマンティクスの基礎として使用するという文脈で開発され、実質的にはラムダ計算を低レベル プログラミング言語として使用していました。いくつかのプログラミング言語にはラムダ計算 (または非常に類似したもの) がフラグメントとして含まれているため、これらのテクニックは実際のプログラミングでも使用されていますが、わかりにくい、または外国語として認識される可能性があります。
名前付き定数
ラムダ計算では、ライブラリは、以前に定義された関数のコレクションの形をとります。ラムダ項は特定の定数にすぎません。純粋なラムダ計算では、すべてのアトミック ラムダ項が変数であるため、名前付き定数の概念はありませんが、定数の名前として変数を用意し、抽象化を使用してその変数を本体にバインドし、その抽象化を意図した定義に適用することで、名前付き定数をエミュレートできます。したがって、f を使用して、 M (別のラムダ項、"メイン プログラム") 内のN (明示的なラムダ項)を意味するには、次のようにします。
- (λf . M ) Nの
著者は、let、[k]などの構文糖を導入して、上記をより直感的な順序で記述できるようにすること が多い。
- f = N in Mとする
このような定義を連鎖させることで、ラムダ計算「プログラム」を 0 個以上の関数定義として記述し、その後にそれらの関数を使用してプログラムの本体を構成する 1 つのラムダ項を記述することができます。
このletの注目すべき制限は、名前fがNで定義されていないことです。これは、 N が抽象バインディングfのスコープ外になるためです。つまり、再帰関数定義をletのNとして使用することはできません。letrec [l]構造を使用すると、再帰関数定義を記述できます。
再帰と固定点
再帰とは、関数が自分自身を呼び出す定義です。定義が自分自身の中に値によって含まれると、値全体が無限サイズになります。再帰をネイティブにサポートする他の表記法では、関数定義を名前で参照することでこれを克服しています。ラムダ計算ではこれを表現できません。ラムダ計算ではすべての関数が匿名であるため、同じ値を定義するラムダ項内で、まだ定義されていない値を名前で参照することはできません。ただし、ラムダ式は、たとえば (λ x . x x ) Eのように、自分自身を引数として受け取ることができます。ここで、E は抽象化である必要があり、そのパラメーターを値に適用して再帰を表現します。
再帰的に定義された 階乗関数F( n )を考える。
- n = 0の場合はF( n ) = 1、それ以外の場合はn × F( n −1)。
この関数を表すラムダ式では、パラメータ(通常は最初のパラメータ)はラムダ式自体を値として受け取るものと想定されるため、それを呼び出す(引数に適用する)と再帰が発生します。したがって、再帰を実現するには、自己参照として意図された引数(ここではrと呼びます)を、関数本体内の呼び出しポイントで常に自分自身に渡す必要があります。
- G := λ r . λ n .( n = 0の場合は1、それ以外の場合はn × ( r r ( n −1)))
- r r x = F x = G r xが 成り立つので、 r = Gであり 、
- F := GG = (λ x . x x ) G
自己アプリケーションはここでレプリケーションを実現し、関数のラムダ式を引数値として次の呼び出しに渡し、そこで参照および呼び出しできるようにします。
これで問題は解決しますが、各再帰呼び出しを自己適用として書き直す必要があります。書き直す必要のない汎用的なソリューションが欲しいです。
- G := λ r . λ n .( n = 0の場合は1、それ以外の場合はn × ( r ( n −1)))
- r x = F x = G r xが 成り立つので、 r = G r =: FIX Gとなり 、
- F := FIX G ただし FIX g := ( rただしr = g r ) = g (FIX g )
- つまり、 FIX G = G (FIX G) = (λ n .(1, if n = 0; else n × ((FIX G) ( n −1))))
最初の引数が再帰呼び出しを表すラムダ項 (ここではGなど) が指定されると、固定小数点コンビネータFIX は、再帰関数 (ここではF )を表す自己複製ラムダ式を返します。関数は、呼び出されるたびに実行されるように事前に作成時に自己複製が準備されているため、どの時点でも明示的に関数自体に渡す必要はありません。したがって、元のラムダ式(FIX G)は呼び出し時点でそれ自体の内部で再作成され、自己参照を実現します。
実際、このFIX演算子にはさまざまな定義が可能ですが、最も単純なものは次のとおりです。
- Y := λ g .(λ x . g ( x x )) (λ x . g ( x x ))
ラムダ計算では、Y g はg の不動点であり、次のように展開されます。
- Y g
- (λ h .(λ x . h ( x x )) (λ x . h ( x x ))) g
- (λ x . g ( x x )) (λ x . g ( x x ))
- g ((λ x . g ( x x )) (λ x . g ( x x )))
- g ( Y g )
さて、階乗関数への再帰呼び出しを実行するには、単に( Y G) n を呼び出します。ここで、 n は階乗を計算する数です。たとえば、 n = 4 の場合、次のようになります。
- (YG)4
- G ( Y G) 4
- (λ r .λ n .(1, n = 0の場合; それ以外の場合はn × ( r ( n −1)))) ( Y G) 4
- (λ n .(1, n = 0の場合; それ以外の場合はn × (( Y G) ( n −1)))) 4
- 4 = 0の場合は1、それ以外の場合は4 × (( Y G) (4−1))
- 4 × (G ( Y G) (4−1))
- 4 × ((λ n .(1, n = 0の場合; それ以外の場合はn × (( Y G) ( n −1)))) (4−1))
- 4 × (1, 3 = 0の場合; それ以外の場合は3 × (( Y G) (3−1)))
- 4 × (3 × (G ( Y G) (3−1)))
- 4 × (3 × ((λ n .(1, n = 0の場合; それ以外の場合はn × (( Y G) ( n −1)))) (3−1)))
- 4 × (3 × (1, 2 = 0の場合; それ以外の場合は2 × (( Y G) (2−1))))
- 4 × (3 × (2 × (G ( Y G) (2−1))))
- 4 × (3 × (2 × ((λ n .(1, n = 0の場合; それ以外の場合はn × (( Y G) ( n −1)))) (2−1))))
- 4 × (3 × (2 × (1、1 = 0の場合; それ以外の場合は1 × (( Y G) (1−1)))))
- 4 × (3 × (2 × (1 × (G ( Y G) (1−1)))))
- 4 × (3 × (2 × (1 × ((λ n .(1, n = 0の場合; それ以外の場合はn × (( Y G) ( n −1)))) (1−1)))))
- 4 × (3 × (2 × (1 × (1、0 = 0の場合;それ以外の場合は0 × (( Y G) (0−1))))))
- 4 × (3 × (2 × (1 × (1))))
- 24
再帰的に定義されたすべての関数は、追加の引数を伴う再帰呼び出しを閉じる適切に定義された関数の固定点として見ることができるため、Y を使用すると、再帰的に定義されたすべての関数をラムダ式として表現できます。特に、自然数の減算、乗算、比較述語を再帰的に明確に定義できるようになりました。
標準用語
いくつかの用語には一般に受け入れられている名前があります: [27] [28] [29]
- I := λ x . x
- S := λ x .λ y .λ z。x z ( y z )
- K := λ x .λ y . x
- B := λ x .λ y .λ z。x ( y z )
- C := λ x .λ y .λ z . x z y
- W := λ x .λ y . x y y
- ωまたはΔまたはU := λ x . x x
- Ω := ω ω
Iは恒等関数です。SKとBCKW は、任意のラムダ項を表現できる完全なコンビネータ計算システムを形成します。次のセクションを参照してください。Ωは UUで、正規形を持たない最小の項です。YIもそのような項の 1 つです。Y は標準で上記で定義されていますが、 Y = BU(CBU)として定義することもできるため、 Y g=g( Y g)となります。上記で定義したTRUEとFALSE は、通常、 TとFと省略されます。
抽象化の排除
N が抽象化されていないラムダ項であるが、名前付き定数(コンビネータ)を含む可能性がある場合、 λ x . Nと同等で抽象化されていないラムダ項T ( x , N )が存在します(名前付き定数が非アトミックと見なされる場合は、その一部を除く)。これは、匿名化変数と見なすこともできます。T ( x , N )は、 Nからxのすべての出現を削除しますが、 Nにx が含まれる位置に引数値を代入することはできます。変換関数T は次のように定義できます。
- T ( x , x ) := I
- xがN内で自由でない場合は、T ( x , N ) := K N。
- T ( x , M N ) := S T ( x , M ) T ( x , N )
どちらの場合でも、形式T ( x , N ) Pの項は、初期コンビネータI、K、またはSに引数P を取得させることで簡約できます。これは、 (λ x . N ) Pの β 簡約と同じです。Iはその引数を返します。Kは、 x がNに自由に出現しない場合に(λ x . N )が行うのと同じように、引数を破棄します。Sは、引数をアプリケーションの両方のサブ項に渡し、最初の結果を 2 番目の結果に適用します。
コンビネータBとC はSに似ていますが、引数をアプリケーションの 1 つのサブ項にのみ渡します ( B は「引数」サブ項に、C は「関数」サブ項に)。そのため、サブ項にxが 1 つも出現しない場合は、後続のKが節約されます。 BとCと比較すると、Sコンビネータは実際には 2 つの機能を融合します。引数の並べ替えと、引数を複製して 2 か所で使用できるようにすることです。Wコンビネータは後者のみを実行し、SKI コンビネータ計算の代替としてB、C、K、W システムを生成します。
型付きラムダ計算
型付きラムダ計算は、ラムダ記号 ( ) を使用して匿名関数の抽象化を表す型付き形式主義です。この文脈では、型は通常、ラムダ項に割り当てられる構文上の性質を持つオブジェクトです。型の正確な性質は、検討する計算によって異なります (型付きラムダ計算の種類を参照)。ある観点からは、型付きラムダ計算は型なしラムダ計算の改良版と見なすことができますが、別の観点からは、より基本的な理論と見なすことができ、型なしラムダ計算は1 つの型のみを持つ特殊なケースと見なすことができます。[30]
型付きラムダ計算は基礎的なプログラミング言語であり、MLやHaskellなどの型付き関数型プログラミング言語、さらに間接的には型付き命令型プログラミング言語の基礎となっています。型付きラムダ計算は、プログラミング言語の型システムの設計において重要な役割を果たします。ここで、型付け可能性は通常、プログラムの望ましい特性を捉えます。たとえば、プログラムはメモリ アクセス違反を引き起こさないなどです。
型付きラムダ計算は、カリー・ハワード同型性を介して数学論理および証明理論に密接に関連しており、カテゴリのクラスの内部言語と見なすことができます。たとえば、単純型付きラムダ計算は、デカルト閉カテゴリ(CCC) の言語です。
削減戦略
項が正規化されているかどうか、また正規化されている場合に正規化にどれだけの作業が必要かは、使用される削減戦略に大きく依存する。一般的なラムダ計算削減戦略には以下のものがある: [31] [32] [33]
- 通常注文
- 最も左端の redex が最初に縮約されます。つまり、可能な場合は常に、引数が縮約される前に抽象化の本体に引数が代入されます。項がベータ正規形である場合、正規順序縮約は常にその正規形に到達します。
- 適用順序
- 最も左の最も内側の redex が最初に縮約されます。その結果、関数の引数は、関数に代入される前に常に縮約されます。通常の順序の縮約とは異なり、適用順序の縮約では、式のベータ正規形が存在する場合でも、その形式を見つけられない場合があります。たとえば、項は適用順序によってそれ自体に縮約されますが、通常の順序では、項はそのベータ正規形に縮約されます。
- 完全なβ還元
- いかなる redex もいつでも還元できます。これは、本質的には特定の還元戦略が存在しないことを意味します。還元可能性に関しては、「すべてが不可能」です。
弱い削減戦略はラムダ抽象化では削減されません。
- 値による呼び出し
- 適用順序に似ていますが、抽象化内では削減は実行されません。これは、C などの厳密な言語の評価順序に似ています。関数の引数は関数を呼び出す前に評価され、引数が代入されるまで関数本体は部分的にも評価されません。
- 名前で呼ぶ
- 通常の順序と同様ですが、抽象化内では簡約は実行されません。たとえば、λ x .(λ y . y ) xは、 (λ y . y ) xという冗長表現を含んでいますが、この戦略によれば通常の形式です。
共有戦略により、並列で「同じ」計算が削減されます。
- 最適な削減
- 通常の順序と同じですが、同じラベルを持つ計算は同時に削減されます。
- 必要に応じて電話する
- 名前による呼び出しと同じですが (したがって弱い)、項を重複する関数アプリケーションは引数に名前を付けます。引数は「必要なとき」に評価され、その時点で名前バインディングが削減された値で更新されます。これにより、通常の順序による評価に比べて時間を節約できます。
計算可能性
任意の2つのラムダ式を入力として受け取り、一方の式が他方の式に簡約されるかどうかによってTRUEまたはFALSE を出力するアルゴリズムは存在しません。 [13]より正確には、計算可能関数ではその質問を決定できません。これは歴史的に、決定不能性が証明された最初の問題でした。このような証明ではよくあることですが、計算可能とは、チューリング完全な計算モデルによって計算可能であることを意味します。実際、計算可能性自体はラムダ計算によって定義できます。自然数の関数F : N → Nが計算可能関数であるための必要条件は、N内のすべてのx、y のペアに対して、f x = β yの場合にのみF ( x )= yとなるラムダ式f が存在する場合です。ここで、xとyはそれぞれxとyに対応するチャーチ数であり、 = β はβ簡約との同値性を意味します。計算可能性とその同値性を定義する他のアプローチについては、 チャーチ–チューリングのテーゼを参照してください。
チャーチの計算不可能性の証明は、まず与えられたラムダ式が正規形を持つかどうかを判断する問題に帰着する。次に、この述語は計算可能であり、したがってラムダ計算で表現できると仮定する。クリーネによる以前の研究とラムダ式のゲーデル数付けの構築を基に、チャーチはゲーデルの第 1 不完全性定理の証明に厳密に従うラムダ式e を構築する。eを自身のゲーデル数に適用すると、矛盾が生じる。
複雑
ラムダ計算の計算量の概念は少々複雑である。なぜなら、β-還元のコストは実装方法によって異なるからである。[34] 正確には、式Eにおける束縛変数Vの出現箇所をすべて何らかの方法で見つけなければならないため、時間コストがかかる。あるいは、自由変数の箇所を何らかの方法で追跡しなければならないため、空間コストがかかる。 EにおけるVの箇所の単純な検索は、Eの長さnでO ( n )である。ディレクターストリングは、この時間コストを 2 乗の空間使用量と交換した初期のアプローチであった。[35]より一般的には、これは明示的な置換を使用するシステムの研究につながった。
2014 年には、項を縮約するために通常順序縮約で実行される β 縮約ステップの数は、妥当な時間コスト モデルであることが示されました。つまり、縮約は、ステップ数に多項式的に比例する時間でチューリング マシンでシミュレートできます。[36]これは、サイズ爆発、つまり各 β 縮約ごとにサイズが指数関数的に増加するラムダ項の存在により、長年未解決の問題でした。結果は、コンパクトな共有表現を使用することでこれを回避します。結果は、ラムダ項を評価するために必要なスペースの量が、縮約中の項のサイズに比例しないことを示しています。現在のところ、空間計算量の適切な尺度が何であるかはわかっていません。[37]
不合理なモデルは必ずしも非効率的というわけではありません。最適縮約は、同じラベルを持つすべての計算を 1 つのステップで縮約し、重複した作業を避けますが、特定の項を正規形に縮約するための並列 β 縮約ステップの数は、項のサイズにほぼ比例します。これは、合理的なコストの尺度としては小さすぎます。なぜなら、任意のチューリング マシンは、チューリング マシンのサイズに比例したサイズでラムダ計算にエンコードされる可能性があるからです。ラムダ項を縮約する真のコストは、β 縮約自体によるものではなく、β 縮約中の redex の重複の処理によるものです。[38]最適縮約の実装が、正規形への最左最外ステップの数などの合理的なコスト モデルに関して測定した場合に合理的かどうかは不明ですが、ラムダ計算のフラグメントでは、最適縮約アルゴリズムが効率的で、最左最外に比べて最大で 2 乗のオーバーヘッドしかないことが示されています。[37]さらに、BOHMの最適削減プロトタイプ実装は、純粋なラムダ項ではCaml LightとHaskellの両方を上回りました。 [38]
ラムダ計算とプログラミング言語
ピーター・ランディンの1965年の論文「ALGOL 60とチャーチのラムダ記法の対応」[39]で指摘されているように、順次手続き型プログラミング言語は、手続き型抽象化と手続き(サブプログラム)適用の基本的なメカニズムを提供するラムダ計算の観点から理解することができます。
匿名関数
たとえば、Pythonでは、「square」関数は次のようにラムダ式として表現できます。
(ラムダ x : x ** 2 )
上記の例は、ファーストクラス関数に評価される式です。 シンボルはlambda、パラメータ名のリストx(この場合は単一の引数)と、関数の本体として評価される式を指定すると、匿名関数を作成しx**2ます。匿名関数は、ラムダ式と呼ばれることもあります。
たとえば、Pascalや他の多くの命令型言語は、関数ポインタのメカニズムを通じて、サブプログラムを他のサブプログラムへの引数として渡すことを長い間サポートしてきました。しかし、関数ポインタは、関数がファーストクラスデータ型であるための十分な条件ではありません。関数がファーストクラス データ型となるのは、実行時に関数の新しいインスタンスを作成できる場合のみだからです。また、この実行時の関数の作成は、Smalltalk、JavaScript、Wolfram Languageでサポートされており、最近ではScala、Eiffel (「エージェント」)、C# (「デリゲート」)、C++11などでもサポートされています。
並列性と同時実行性
ラムダ計算のチャーチ・ロッサー特性は、評価(β-還元)が任意の順序で実行でき、並列でも実行できることを意味します。これは、さまざまな非決定性 評価戦略が関連していることを意味します。ただし、ラムダ計算は並列性のための明示的な構成を提供しません。ラムダ計算にフューチャーなどの構成を追加することはできます。通信と並行性を記述するための他のプロセス計算が開発されています。
セマンティクス
ラムダ計算項が他のラムダ計算項、さらには自分自身に対して関数として作用するという事実は、ラムダ計算のセマンティクスに関する疑問を招きました。ラムダ計算項に意味のある意味を割り当てることはできるでしょうか? 自然なセマンティクスは、関数空間D → Dに同型の、自分自身に対する関数の集合D を見つけることです。 しかし、 Dが単独集合でない限り、 DからDまでのすべての関数の集合はDよりも大きい基数を持つため、基数制約により、そのような非自明なD は存在しません。
1970年代にダナ・スコットは、連続関数のみを考慮すると、必要な特性を持つ集合または領域 Dが見つかることを示し、ラムダ計算のモデルを提供した。 [40]
この研究はプログラミング言語の 表示的意味論の基礎も形成しました。
バリエーションと拡張
これらの拡張機能はラムダ キューブにあります:
これらの形式システムは、ラムダ キューブに含まれないラムダ計算の拡張です。
- バイナリ ラムダ計算– バイナリ I/O、項のバイナリ エンコーディング、および指定された汎用マシンを備えたラムダ計算のバージョン。
- ラムダミュー計算–古典論理を扱うためのラムダ計算の拡張
これらの形式体系はラムダ計算のバリエーションです。
- カッパ計算– ラムダ計算の一次類似物
以下の形式体系はラムダ計算に関連しています。
- 組み合わせ論理– 変数を使わない数学的論理の表記法
- SKIコンビネータ計算– S、K、Iコンビネータに基づく計算システム。ラムダ計算と同等だが、変数置換なしで簡約可能。
参照
- 応用コンピューティングシステム–ラムダ計算のスタイルによるオブジェクトの処理
- デカルトの閉カテゴリ–カテゴリ理論におけるラムダ計算の設定
- カテゴリカル抽象マシン–ラムダ計算に適用可能な計算モデル
- Clojure、プログラミング言語
- カリー・ハワード同型性– プログラムと証明の形式的な対応
- De Bruijn インデックス– アルファ変換の曖昧さを解消する表記
- De Bruijn記法– 後置修飾関数を使用した記法
- ドメイン理論–ラムダ計算の表示的意味論を与える特定のポセットの研究
- 評価戦略–プログラミング言語における式の評価のルール
- 明示的置換– β還元で使用される置換理論
- 関数型プログラミング
- ハロップ公式– 証明がラムダ項であるような構成的論理式の一種
- 相互作用ネット
- クリーネ・ロッサーのパラドックス– ラムダ計算のある種の形式が矛盾していることを示す
- ラムダ計算の騎士団– LISP とScheme ハッカーの半架空の組織
- Krivine マシン– ラムダ計算における名前による呼び出しを解釈する抽象マシン
- ラムダ計算の定義– ラムダ計算の正式な定義。
- Let 式– 抽象化に密接に関連する式。
- ミニマリズム(コンピューティング)
- 書き換え– 形式体系における式の変換
- SECDマシン–ラムダ計算用に設計された仮想マシン
- スコット・カリー定理– ラムダ項の集合に関する定理
- アラバマ物語をあざける-組み合わせ論理入門
- ユニバーサルチューリングマシン– ラムダ計算と同等の形式計算機
- Unlambda –組み合わせ論理に基づく難解な関数型プログラミング言語
さらに読む
- アベルソン、ハロルド & ジェラルド ジェイ サスマン。コンピュータ プログラムの構造と解釈。MIT出版。ISBN 0-262-51087-1 。
- Barendregt、Hendrik Pieterラムダ微積分の入門。
- Barendregt, Hendrik Pieter、「ラムダ計算の論理とコンピュータ サイエンスへの影響」、The Bulletin of Symbolic Logic、第 3 巻、第 2 号、1997 年 6 月。
- Barendregt, Hendrik Pieter、「型フリーラムダ計算」 、 Handbook of Mathematical Logicの pp1091–1132 、North-Holland (1977) ISBN 0-7204-2285-X
- Cardone, Felice および Hindley, J. Roger, 2006. History of Lambda-calculus and Combinatory Logic Archived 2021-05-06 at the Wayback Machine . In Gabbay and Woods (eds.), Handbook of the History of Logic , vol. 5. Elsevier.
- チャーチ、アロンゾ、「初等数論の解決不可能な問題」、アメリカ数学誌、58 (1936)、pp. 345–363。この論文には、ラムダ式の同値性は一般に決定不可能であることの証明が含まれています。
- チャーチ、アロンゾ (1941)。ラムダ変換の計算。プリンストン:プリンストン大学出版局。 2020年4月14日閲覧。(ISBN 978-0-691-08394-0)
- Frink Jr., Orrin (1944). 「レビュー: Alonzo Church 著『ラムダ変換の計算』」(PDF) . Bull. Amer. Math. Soc . 50 (3): 169–172. doi : 10.1090/s0002-9904-1944-08090-7 .
- Kleene, Stephen、「形式論理における正の整数の理論」、American Journal of Mathematics、57 (1935)、pp. 153–173 および 219–244。いくつかのよく知られた関数のラムダ計算定義が含まれています。
- Landin, Peter、「A Correspondence Between ALGOL 60 and Church's Lambda-Notation」、Communications of the ACM、vol. 8、no. 2 (1965)、89~101 ページ。ACM サイトから入手可能。プログラミング言語の基礎としてのラムダ計算の重要性を強調した古典的な論文。
- ラーソン、ジム、ラムダ計算と Scheme 入門。プログラマーのためのやさしい入門書。
- マイケルソン、グレッグ(2013年4月10日)。ラムダ計算による関数型プログラミング入門。Courier Corporation。ISBN 978-0-486-28029-5。[41]
- Schalk, A. および Simmons, H. (2005) λ 計算と算術の入門、豊富な演習付き。マンチェスター大学の数理論理学修士課程のコースノート。
- de Queiroz, Ruy JGB (2008). 「還元規則、使用としての意味、証明理論的意味論について」。Studia Logica . 90 (2): 211–247. doi :10.1007/s11225-008-9150-5. S2CID 11321602.「意味は使用である」という考え方に正式な裏付けを与える論文。たとえ証明に基づいていたとしても、意味を与える規則として還元をとらえる点で、ダメット-プラウィッツの伝統のような証明理論的意味論とは異なる。
- ハンキン、クリス、コンピュータ科学者のためのラムダ計算入門、 ISBN 0954300653
- 大学院生向けモノグラフ/教科書
- Sørensen, Morten Heine および Urzyczyn, Paweł (2006)、「Lectures on the Curry–Howard isomorphism」、Elsevier、ISBN 0-444-52077-5は、型のない多様体からほとんどの型付きラムダ計算まで、純粋型システムやラムダキューブなどの最近の開発を含むラムダ計算の主要なトピックを網羅した最近のモノグラフです。サブタイピングの拡張は扱っていません。
- ピアス、ベンジャミン(2002)、型とプログラミング言語、MITプレス、ISBN 0-262-16209-1実用的な型システムの観点からラムダ計算をカバーしています。依存型などのいくつかのトピックについては言及されているだけですが、サブタイピングは重要なトピックです。
- 文書
- ラムダ計算の簡単な入門-( PDF ) Achim Jung 著
- ラムダ計算のタイムライン-( PDF ) Dana Scott 著
- ラムダ計算入門チュートリアル-( PDF ) ラウル・ロハス著
- ラムダ計算の講義ノート-( PDF ) ピーター・セリンジャー著
- マリウス・ブリガによるグラフィックラムダ計算
- Peter Kelly、Paul Coddington、Andrew Wendelborn による「ワークフロー モデルとしてのラムダ計算」では、グラフ削減をラムダ式を評価する一般的な手段として取り上げ、分散コンピューティングへのラムダ計算の適用可能性について説明しています (ラムダ式の並列グラフ削減を可能にするChurch-Rosserプロパティによる)。
注記
- ^ これらの規則により、次のような式が生成されます。式が明確な場合は括弧を省略できます。一部のアプリケーションでは、論理定数や数学定数、演算の項が含まれる場合があります。
- ^ abcd Barendregt、Barendsen (2000) このフォームを呼び出します
- 公理β : (λx.M[x]) N = M[N]、(λx.M) N = M[x := N]と書き直すと、「M[x := N]はM内のxのすべての出現をNに置き換えることを表す」。[1] : 7 M[N/x]とも表記され、「M内のxをNに置き換えること」。[2]
- ^ 詳しい歴史については、Cardone と Hindley の「ラムダ計算と組み合わせ論理の歴史」(2006 年) を参照してください。
- ^ ab は 「maps to」と発音されます。
- ^ 式 e は、変数 x、ラムダ抽象化、またはアプリケーション(BNF では.)のいずれかになります。Wikipedia の「単純型付きラムダ計算#型なしラムダ計算の構文」より
- ^は ASCIIでは次のように表記されることもある。
- ^ ラムダ項は匿名形式で記述された関数を表します。
- ^ラムダ記法とその計算における自由変数は 、線形代数や同名の数学的概念に匹敵する。
- ^ Mの自由変数の集合、ただし{ x }は除かれる
- ^ の 自由変数の集合と の自由変数の集合の和集合[1]
- ^ (λ f . M ) N は「let f be N in M」と発音されます。
- ^ AriolaとBlom [26]は、1) letrecで拡張された整形式の巡回ラムダグラフを使用した表現計算の公理を使用して、無限の可能性のある巻き戻し木を検出します。2)スコープ付きラムダグラフのβ縮小を含む表現計算は、Ariola/Blomのラムダ計算の巡回拡張を構成します。3)Ariola/Blomは、§値渡しを使用して厳密な言語について推論し、Moggiの計算およびHasegawaの計算と比較します。結論は111ページにあります。[26]
参考文献
この記事の一部は、FOLDOCの資料に基づいており、許可を得て使用しています。
- ^ abc バレンドレット、ヘンク; Erik Barendsen (2000 年 3 月)、ラムダ計算入門(PDF)
- ^ nラボでの明示的な置換
- ^ チューリング、アラン M. ( 1937 年 12 月)。「計算可能性と λ-定義可能性」。The Journal of Symbolic Logic。2 ( 4): 153–163。doi :10.2307/2268280。JSTOR 2268280。S2CID 2317046 。
- ^ Coquand, Thierry (2006年2月8日). Zalta, Edward N. (編). 「型理論」.スタンフォード哲学百科事典(2013年夏版) . 2020年11月17日閲覧。
- ^ モートガット、マイケル (1988)。カテゴリー調査:ランベック計算の論理的および言語的側面。Foris Publications。ISBN 9789067653879。
- ^ ハリー、バント;マスケンス、ラインハルト編。 (2008年)。コンピューティングの意味。スプリンガー。ISBN 978-1-4020-5957-5。
- ^ ミッチェル、ジョン C. (2003)。プログラミング言語の概念。ケンブリッジ大学出版局。p. 57。ISBN 978-0-521-78098-8。。
- ^ Chacón Sartori, Camilo (2023-12-05). Racket を使用したラムダ計算入門 (技術レポート). 2023-12-07 にオリジナルからアーカイブされました。
- ^ ピアス、ベンジャミン C.コンピュータ科学者のための基礎カテゴリー理論。p. 53。
- ^ チャーチ、アロンゾ(1932) 。「論理の基礎となる公準のセット」。数学年報。シリーズ2。33 ( 2): 346–366。doi :10.2307/1968337。JSTOR 1968337。
- ^ クリーネ、スティーブン・C. ;ロッサー、JB (1935年7月) 。「特定の形式論理の矛盾」。数学年報。36 (3): 630。doi :10.2307/1968646。JSTOR 1968646。
- ^ チャーチ、アロンゾ(1942 年12月) 。「Haskell B. Curry 著『特定の形式論理の矛盾』のレビュー」。The Journal of Symbolic Logic。7 ( 4): 170–171。doi :10.2307/2268117。JSTOR 2268117。
- ^ ab Church, Alonzo (1936). 「初等数論の解決不可能な問題」. American Journal of Mathematics . 58 (2): 345–363. doi :10.2307/2371045. JSTOR 2371045.
- ^ チャーチ、アロンゾ(1940)。「単純な型理論の定式化」。シンボリックロジックジャーナル。5 (2) : 56–68。doi :10.2307/2266170。JSTOR 2266170。S2CID 15889861 。
- ^ Partee, BBH; ter Meulen, A. ; Wall, RE (1990). 言語学における数学的手法. Springer. ISBN 9789027722454. 2016年12月29日閲覧。
- ^ Alama, Jesse. Zalta, Edward N. (ed.). 「ラムダ計算」.スタンフォード哲学百科事典(2013年夏版) . 2020年11月17日閲覧。
- ^ ダナ・スコット、「過去を振り返る; 未来を見つめる」、ダナ・スコットの85歳の誕生日とドメイン理論50周年を記念したワークショップでの招待講演、7月7日~8日、FLoC 2018(2018年7月7日の講演)。関連する部分は32:50から始まります。(2016年5月に英国バーミンガム大学で行われた講演の抜粋も参照してください。)
- ^ Barendregt, Hendrik Pieter (1984)。ラムダ計算: 構文と意味論。論理学と数学の基礎研究。第 103 巻 (改訂版)。北ホラント。ISBN 0-444-87508-5。(訂正)
- ^ ab 「結合規則の例」。Lambda-bound.com 。 2012年6月18日閲覧。
- ^ 「ラムダ式の基本文法」。SoftOption。
他のシステムでは、並置をアプリケーションの意味で使用するため、「ab」は「a@b」を意味します。これは、変数の長さが 1 である必要があることを除けば問題ありません。つまり、「ab」は 2 つの変数が並置されたものであって、長さ 2 の 1 つの変数ではないことがわかります。ただし、「firstVariable」などのラベルは単一の変数を意味するようにしたいため、この並置規則は使用できません。
- ^ ab Selinger, Peter (2008)、Lecture Notes on the Lambda Calculus (PDF)、vol. 0804、Department of Mathematics and Statistics、University of Ottawa、p. 9、arXiv : 0804.3434、Bibcode :2008arXiv0804.3434S
- ^ de Queiroz, Ruy JGB (1988). 「プログラミングの証明理論的説明と縮約規則の役割」Dialectica . 42 (4): 265–282. doi :10.1111/j.1746-8361.1988.tb00919.x.
- ^ Turbak, Franklyn; Gifford, David (2008)、プログラミング言語における設計概念、MIT 出版、p. 251、ISBN 978-0-262-20175-9
- ^ Luke Palmer (2010 年 12 月 29 日) Haskell-cafe: η ルールの目的は何ですか?
- ^ Felleisen, Matthias; Flatt, Matthew (2006)、「プログラミング言語とラムダ計算」(PDF) 、p. 26、2009-02-05のオリジナル(PDF)からアーカイブ; 元の場所にある注記(2017 年にアクセス)によると、著者は元々参照されていた作品が書籍に置き換えられたと考えているようです。
- ^ ab Zena M. Ariola および Stefan Blom、Proc. TACS '94仙台、日本 1997 (1997) 巡回ラムダ計算 114 ページ。
- ^ Ker, Andrew D. 「Lambda Calculus and Types」(PDF)。p. 6。2022年1月14日閲覧。
- ^ Dezani-Ciancaglini, Mariangiola; Ghilezan, Silvia (2014). 「交差型と共用型のサブタイプの精度」(PDF) .書き換えと型付きラムダ計算. コンピュータサイエンスの講義ノート。第 8560 巻。p. 196。doi : 10.1007 /978-3-319-08918-8_14。hdl :2318 / 149874。ISBN 978-3-319-08917-1. 2022年1月14日閲覧。
- ^ Forster, Yannick; Smolka, Gert (2019年8月). 「Call-by-Value Lambda Calculus as a Model of Computation in Coq」(PDF) . Journal of Automated Reasoning . 63 (2): 393–413. doi :10.1007/s10817-018-9484-2. S2CID 53087112. 2022年1月14日閲覧。
- ^ 型とプログラミング言語、p. 273、ベンジャミン C. ピアース
- ^ ピアス、ベンジャミン C. (2002)。型とプログラミング言語。MITプレス。p. 56。ISBN 0-262-16209-1。
- ^ セストフト、ピーター (2002)。「ラムダ計算の簡約の実証」( PDF)。計算の本質。コンピュータサイエンスの講義ノート。第 2566 巻。pp. 420–435。doi : 10.1007/3-540-36377-7_19。ISBN 978-3-540-00326-7. 2022年8月22日閲覧。
- ^ ビエルナツカ、マウゴルザタ;キャラトニク、ヴィトルド。ドラブ、トマシュ (2022)。アンドロニック、6月。デ・モウラ、レオナルド(編)。 「ラムダ微積分削減戦略と Coq の動物園」(PDF)。第 13 回インタラクティブ定理証明に関する国際会議 (ITP 2022)。237 .ダグシュトゥール城 – Leibniz-Zentrum für Informatik: 7:1–7:19。土井:10.4230/LIPIcs.ITP.2022.7 。2022 年8 月 22 日に取得。
- ^ Frandsen, Gudmund Skovbjerg; Sturtivant, Carl (1991 年 8 月 26 日)。「λ 計算の効率的な実装とは何か?」。関数型プログラミング言語とコンピュータ アーキテクチャ: 第 5 回 ACM カンファレンス。米国マサチューセッツ州ケンブリッジ、1991 年 8 月 26 ~ 30 日。議事録。コンピュータ サイエンスの講義ノート。第 523 巻。Springer-Verlag。pp. 289~ 312。CiteSeerX 10.1.1.139.6913。doi : 10.1007 /3540543961_14。ISBN 9783540543961。
- ^ Sinot, F.-R. (2005). 「Director Strings Revisited: 高階書き換えにおける自由変数の効率的な表現に対する一般的なアプローチ」(PDF) . Journal of Logic and Computation . 15 (2): 201–218. doi :10.1093/logcom/exi010.
- ^ Accattoli, Beniamino; Dal Lago, Ugo (2014 年 7 月 14 日)。「ベータ リダクションは確かに不変です」。第 23 回 EACSL年次コンピュータ サイエンス ロジック カンファレンス (CSL) と第 29 回 ACM/IEEE 年次コンピュータ サイエンス ロジック シンポジウム (LICS )の合同会議議事録。pp . 1–10。arXiv : 1601.01233。doi :10.1145/ 2603088.2603105。ISBN 9781450328869. S2CID 11485010。
- ^ ab Accattoli, Beniamino (2018年10月). 「(非)効率性と適正コストモデル」.理論計算機科学における電子ノート. 338 : 23–43. doi : 10.1016/j.entcs.2018.10.003 .
- ^ ab Asperti, Andrea (2017年1月16日). 「ラムダ項の効率的な削減について」. arXiv : 1701.04240v1 [cs.LO].
- ^ Landin, PJ (1965). 「ALGOL 60 と Church のラムダ記法の対応」Communications of the ACM . 8 (2): 89–101. doi : 10.1145/363744.363749 . S2CID 6505810.
- ^ Scott, Dana (1993). 「ISWIM、CUCH、OWHY の型理論的代替手段」(PDF) .理論計算機科学. 121 (1–2): 411–440. doi :10.1016/0304-3975(93)90095-B . 2022年12月1日閲覧。1969年に執筆され、未発表原稿として広く流通した。
- ^ 「Greg Michaelsonのホームページ」。数学およびコンピューターサイエンス。リッカートン、エディンバラ:ヘリオットワット大学。 2022年11月6日閲覧。
外部リンク
- グラハム・ハットン、ラムダ計算、ラムダ計算に関する短い(12分)コンピュータファイルビデオ
- ヘルムート・ブランドル著『ラムダ計算のステップバイステップ入門』
- 「ラムダ計算」、数学百科事典、EMS Press、2001 [1994]
- デビッド・C・キーナン『アラバマ物語を解剖する:アニメーションによる縮約法によるラムダ計算のグラフィカル表記法』
- L. Allison、いくつかの実行可能な λ 計算の例
- Georg P. Loczewski、ラムダ計算と A++
- Bret Victor、アリゲーターエッグ:ラムダ計算に基づくパズルゲーム
- ラムダ計算 2012-10-14 にアーカイブされた、 Safalra のウェブサイトのWayback Machine 2021-05-02 にアーカイブされた、 Wayback Machine
- LCI Lambda Interpreter はシンプルでありながら強力な純粋微積分インタープリタです
- Lambda-the-Ultimate のラムダ計算リンク
- Mike Thyer、Lambda Animator、代替削減戦略を示すグラフィカル Java アプレット。
- C++ テンプレートを使用したラムダ計算の実装
- シェーン・スタイナート・スレルケルド、「ラムダ計算」、インターネット哲学百科事典
- アントン・サリクメトフ、マクロラムダ計算
