lambda-反射を伴う計算


23

私は、リフレクションに関する推論、つまり実行中のプログラムのイントロスペクションと操作をサポートする簡単な計算を探しています。

型なしの -calculus拡張機能があり、これを使用して -termsを構文的に操作し、後で評価できる形式に変換できますか?λλλ

微積分には2つの主な追加用語があると思います。

  • reflect v:を取り、構文操作に修正可能な表現を生成します。vvv
  • eval v:用語の構文表現を取り、それを評価します。

リフレクションをサポートするには、用語の構文表現が必要です。次のようになります。

  • L A M R e R e eλx.e用語として表現される、 の反射バージョンであり、、(LAM R(e))R(e)e
  • A P P R e R e e e用語として表現される、および(APP R(e) R(e))
  • V A R x xはとして表されます。(VAR x)

この表現では、パターンマッチングを使用して用語を操作できます。

しかし、問題が発生します。とは、パターンマッチングと同様に、用語としてエンコードする必要があります。、、およびを追加するのは簡単なようですが、これらの操作をサポートするために他の用語を追加する必要がありますか?e v a l R E F L E C T E V A L M A T C HreflectevalREFLECTEVALMATCH

設計の選択が必要です。上記の関数は、およびの本体で何をすべきでしょうか?は体を変換すべきかどうか?r e f l e c t e v a l R R()reflectevalR()

私は反射自体の研究にあまり興味がないので、微積分は他の研究の手段として役立つでしょう-私は車輪を再発明したくありません。

説明した内容に一致する既存の計算式はありますか?

私の知る限り、コメントで提案されたMetaMLなどの計算は大いに役立ちますが、既に構築されているコードフラグメントをパターンマッチおよび分解する機能は含まれていません。

私ができることの1つは、次のことです。

  • let x=λy.y in reflect x(LAM (VAR y) (VAR y))

次に、結果に対してパターンマッチングを実行して、まったく異なる式を作成します。

これは確かに -calculusの保守的な拡張ではなく、メタ理論は見苦しいかもしれませんが、これは私のアプリケーションにとっては一種のポイントです。 -abstractions を分解したい。λλλ


MetaMLは、REFLECTの実行とEVALのブラケット解除の演算子を備えた型付き反射言語です。タイピングは基本ですが、モーダルS4から継承されたフラグメントは、このペーパーのように機能する可能性があります。
ex0du5

@ ex0du5:ありがとう、しかしこれは私が知る限りでは十分ではありません。もちろん、さまざまな段階でコードを作成できますが、用語を分解することはできないようです。(何かを逃したかどうかを確認するために、より詳しく読みます。)
デイブクラーク

スキーム(可変性およびその他の複雑化なし)?
ジル「SO-停止されて悪」

@Gilles:Schemeは、計算ではなくプログラミング言語です。さらに、私はそれが私が望むことを行うことができるとは思わない。
デイブクラーク

@DaveClarkeプログラミング言語は、いぼの多い微積分です。Schemeコアは一見適切なように見えますが、あなたの要件を十分に考えてはいません。うまくいかないと思いますか?(必要に応じてチャットにドロップします。)
ジル「SO-悪であるのをやめる」

回答:


15

Jean Louis Krivineは、「Krivine Machine」を非常に重要な方法で拡張する抽象計算を導入しました(Krivineマシンは、すでにLispからのcall / cc命令をサポートしています)。

彼はの"引用"演算子を導入し、この資料以下のように定義される:もしのA -term、ノートの画像一部全単射によってラムダ項から自然数まで。対応する教会の数字に注意してください。Krivineは、演算子を定義する評価ルールによって: 私はクリーネ魔術が、これはあなたが望むものを行うのに十分であることを示していると考えている:すなわち引用符とはevalを定義します演算子(が計算可能な場合)。λ N φ φ π Λ N ¯ N N N χ χ φ φ ¯ N φ πϕλnϕϕπ:ΛNn¯nNχ

χ ϕϕ nϕ¯
π

Krivineは読みにくいことで有名です(これを読んでも気に入らないでください、Jean-Louis!)。一部の研究者は、技術コンテンツをより読みやすい方法で抽出しようとする慈善行為を行っています。クリストフ・ラファリのこれらのノートを見てみてください

お役に立てれば!


あなたの興味に関連する可能性のある別の参照があることがわかります:JayとKesnerによるPure Pattern Calculusは、変数の単純な抽象化をパターンを表すパターンの抽象化に拡張する -calculusのバリアントを形式化します微積分そのもの。これは驚異的に表現力があり、特にアプリケーション自体を解体することができます。私が間違っていなければ、次の用語:λ

(λ(x y).x)((λx.x x) (λy.y))

減少し。繰り返しになりますが、これはquote演算子とeval演算子を実装するのに十分すぎると信じています。λx.x x


この一見合理的な答えに賛成したいと思いますが、それが質問に答え始めたのかどうかもわかりません。
ラファエル

@Raphaelは記事を読んで見つけます:)実際には、これは部分的な答えにすぎません:記事は、ラムダ計算にないLispの重要な機能、すなわちQUOTE演算子を確かに形式化します。しかし、大規模なメタ理論的研究はありません。集合理論の複雑な公理を実現するために、ある種の奇妙な非透明計算を表現する手段としてそれを紹介するだけです。
コーディ

1
私が正しく覚えている場合、PPCでは、redexeのパターンマッチングはできません。彼らが与えた理由は、合流のためです。また、PPCでは、パターンマッチングは一致に対して厳密であるため、はすぐに正規化され場合、パターンとの照合は失敗します。λ Y y x y (λx.x x) (λy.y)λy.y(x y)

1
私が知っている唯一の引用は、Lispのものです。しかし、私が覚えているように、引用されたものはすべて構文オブジェクトに変わります。「関数」は引数を評価せます。関数は引数の値を受け取り(評価し)、それを評価する構文式に戻します(どのように?)その値に。したがって、Krivine形式がLISP扱っている場合、質問で提案されているものに近いものは得られません。r e f l e c t q u o t equotereflectquote
babou

8

不可能ではないにしても、合流をあきらめずにそうすることは非常に困難です。つまり、あなたは毛深いメタ理論については正しいと思う。一方、すべてのチューリング計算可能な関数を表現でき、その用語を検査する完全な能力を備えたコンビネータ計算を設計することは可能です:JayとGive-Wilsonを参照してください。

ただし、この能力を持っていると、方程式の理論に悪影響を及ぼすと思います。特に、2つの値がアルファ等値まで等しい場合にのみ2つの値が等しいことを証明できる傾向があります。

リンクされたKrivineの論文のコディはまだ読んでいませんが、古典的な論理では、本質的に2つのことしかありません。真と偽です。すべてがそれらの1つと同等です。つまり、とにかく崩壊した等式理論を持つ傾向があります。


1
Krivine計算は命題の計算ではなく、命題の実現者であり、非常に重要な方程式理論を持っていることに注意してください。
コーディ

5

プログラミング言語の理論では、あなたが話す機能は通常「引用」と呼ばれます。例えば、ジョン・ロングリーは彼の作品のいくつかでそれについて書いた。この論文を参照。

(実際に有用な実装とは対照的に)理論的な考慮事項の直後にいる場合は、引数のGödelコードを返すことにより、整数型にマップするquote(またはreflect呼び出す)ことを述べることにより、物事を単純化できnatます。次に、抽象構文ツリーと同じように、数値を分解できます。さらに、evalそれは言語で実装できるため、必要ありません。これは基本的に言語のインタープリターです。

これらはあなたがクリーネの最初のコンビナトリアル代数を検討することができますしている具体的なモデルの場合:数などのすべて(ゲーデルコードと考える)を解釈し、クリーネアプリケーション定義する平均ところある -th部分関数。これにより、単純な恒等関数である -calculus(部分マップ付き)のモデルが得られます。言語に追加の機能を追加する必要はありません。nmφn(m)φnnλquote

あなたが何を望んでいるのか教えていただければ、より具体的な参考文献をお伝えできるかもしれません。

ところで、ここに未解決の問題があります:

エンリッチ -calculus(入力されたか、型なし)とされ、あなたが保つような方法で合同である -rule。λquoteξ

-ruleと言う -abstractionは合同です。下で減らすことができます。これとの組み合わせでは、も一致することになっているため、 問題になり ます。それがある場合でなければならないことがわかる どういうわけか、これは「非常に標準的な」ゲーデル符号を計算することになっていますが、型付きのがあると仮定してもξ

e1e2λx.e1λx.e2
λλquotequote
e1e2quotee1quotee2,
λ
quote((λx.x)y)quotey.
quoteλ-再帰なしの微積分は、これを行うのが難しいようです。

もちろん、そこには変換があります。私はそうは言っているはずと仮定のすべてのルールのための合同でなければなりません -calculusが、特にこと -ruleを維持することは困難です。λ ξβquoteλξ
アンドレイバウアー

ξβ

次の論文は、(ξ)方程式に関するいくつかの問題を示しています。ラムダ計算は代数的で、Peter Selingerです。興味深いことに、私が知らなかった新しい何か!クール。
有限数

4

ここに別の答えがありますが、まだ実験的な私の名目上のアプローチを使用する代わりに、論文に戻るより確立されたアプローチがいくつかあります:

LEAP:評価と多態性を持つ言語
Frank PfenningとPeter Lee
https://www.cs.cmu.edu/~fp/papers/tapsoft89.pdf

論文は以下で始まります:

これにより、レイノルズが最初に提起した、強く型付けされた言語がメタサーキュラーインタープリターを受け入れるかどうかという質問に至りました。従来の知恵は、答えが「いいえ」であることを示しているようでした。私たちの答えは「ほぼ」です。

LEAPはOPが望むものよりもはるかに強いことに注意してください。まず最初に入力されます。次に、メタサーキュラリティを要求します。これは、たとえば、evalが独自の定義を実行できることを意味します。Prologでは、solve / 1のメタサーキュラリティを取得します。

solve(true).
solve((A,B)) :- solve(A), solve(B).
solve(H) :- clause(H,B), solve(B).

solve / 1に次の句を追加すると:

solve(clause(H,B)) :- clause(H,B).

そして、それを見ると、clause / 2はsolve / 1の句も返します。その後、solve(solve(...))を呼び出して、solveがどのように実行されるかを確認できます。

自己表現の質問は、まだいくつかの研究に拍車をかけています。たとえば、以下を参照してください。

Girards System Uの自己表現U
Matt Brown、Jens Palsberg
http://compilers.cs.ucla.edu/popl15/popl15-full.pdf


3

この問題は、CoqやIsabelle / HOLなどの証明アシスタントの近くで特定されています。頭字語HOASの下にあります。λ-Prologについては、新しい∇量指定子を使用すると、このようなことができるという主張がいくつかあります。しかし、私はまだこの主張を理解できませんでした。私がこれまでに得た主な洞察は、明確なアプローチがなく、いくつかの可能なアプローチがあるということです。

私自身のテイクは、まだ完成していませんが、ゲーデルの不完全性の証明に関するポールソンの最近の論文に触発されました。メタレベルの名前を持つデータ構造に関連して、オブジェクトレベルのバインダーを使用します。基本的に、OPのデータ構造と類似しているが別個のデータ構造であり、依存型に興味があるので教会コーディングがあります。

datatype Expr = var Name                 /* written as n */
              | app Expr Expr            /* written as s t */
              | abs Name Expr Expr       /* written as λn:s.t */

メタレベル式は、変数名n、m、..などを使用して名前を表すという点で、オブジェクトレベル式と区別できます。一方、オブジェクトレベルでは変数名x、y、..などを使用します。オブジェクトロジック内のメタ用語の解釈は、次のように機能します。目的語を与えるべき名義コンテキストσの名義語tの解釈のために[t]σを書きましょう。その後、次のようになります。

 [n]σ = lookup σ n
 [s t]σ = [s]σ [t]σ
 [λn:s.t]σ = λx:[s]σ.[t]σ,n:x

上記は、OPがEVAL関数を呼び出すものを定義します。Paulsonとの小さな違いは、σは有限リストであり、関数ではありません。私の意見では、REFAL関数ではなく、EVAL関数を導入することのみが可能です。オブジェクトレベルでは、異なるラムダ式が同じになるように、ある程度の同等性がある場合があります。あなたがしなければならないことは、evalを使用して、必要性を感じた場合、おそらく反射についても推論することです。

名目上のものと名目上のものとの間で壁を取り壊したい場合は、何も展開されないPrologのような極端に行く必要があります。しかし、λ-Prologシステムの例が示すように、高次の場合、追加の問題があります。たとえば、∇数量詞などの新しい手段を導入することによってのみ論理的な方法で克服できます。

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