ロジックプログラミングに関して、PrologとminiKanrenの主な技術的な違いは何ですか?[閉まっている]


123

論理プログラミングについて読みたいと思うとき、私は今日それを行うための2つの「主な」方法につまずきます。

  • miniKanren、で導入minilanguage 推論スキーマーに起因して、現時点での人気とcore.logic
  • Prolog、最初の「大きな」ロジックプログラミング言語。

私が今興味を持っていること:2つの間の主な技術的な違いは何ですか?アプローチと実装は非常に似ていますか、それとも完全に異なるロジックプログラミングのアプローチを取っていますか?それらはどの数学の出身であり、理論的な基礎は何ですか?


3
この質問が終了したのを見て悲しい。非常に説得力のある回答と多数の賛成票で示されているように、これは完全に役立つ質問です。私は再開することに投票しました...
nealmcb

@nealmcbの質問はかつて多くの賛成投票で話題になっていたかもしれませんが、賛成票の数は有効かどうかを定義するものではありません。
Tiago Martins Peres李大仁

回答:


280

最初に、細かいpw0n1eアイコンについてお褒めさせてください。

これは、主にminiKanrenとPrologの両方に非常に多くのバリアントがあるため、答えるのが難しい質問です。miniKanrenとPrologは、実際には言語のファミリーであるため、機能を比較したり、実際にどのように使用するかさえ比較することが困難です。このため、これから述べることはすべて慎重に行ってください。Prologが深さ優先検索を使用していると言う場合、多くのProlog実装が他の検索戦略をサポートし、代替検索戦略もメタでエンコードできることに注意してください-通訳レベル。それでも、miniKanrenとPrologは設計哲学が異なり、トレードオフが異なります。

Prologは、シンボリック人工知能プログラミング用の2つの古典的な言語の1つです(もう1つの古典的な言語はLispです)。Prologは、宣言的知識が1次ロジックにエンコードされている、記号ルールベースのシステムの実装に優れています。この言語は、これらのタイプのアプリケーションの表現力と効率のために最適化されていますが、論理的な純粋さが犠牲になることもあります。たとえば、デフォルトでは、Prologは統合で「発生チェック」を使用しません。数学/論理の観点からは、このバージョンの統一は正しくありません。ただし、発生チェックはコストがかかり、ほとんどの場合、発生チェックの欠如は問題ではありません。これは、Prologでの深さ優先検索の使用やカット(!)バックトラッキングを制御します。これらの決定は1970年代のハードウェア上で実行する場合には絶対に必要であると確信しています。今日、大きな問題を処理する場合や、巨大な(多くの場合、無限の)検索スペースを処理する場合に非常に役立ちます。

Prologは、カットを含む多くの「論理外」または「非論理」機能、assertおよびretractを使用した算術用の変数の投影をサポートしますisなど。これらの機能の多くは、複雑な制御フローを表現し、Prologのファクトのグローバルデータベースを操作することを容易にします。Prologの非常に興味深い機能の1つは、Prologコード自体がファクトのグローバルデータベースに格納され、実行時に照会できることです。これにより、解釈の下でPrologコードの動作を変更するメタインタープリターを書くことは簡単になります。たとえば、検索順序を変更するメタインタープリターを使用して、Prologで幅優先検索をエンコードできます。これは非常に強力な手法であり、Prologの世界以外ではあまり知られていません。「プロローグの芸術」では、この手法について詳しく説明しています。

Prologの実装を改善するために多大な努力が払われてきました。そのほとんどはWarren Abstract Machine(WAM)に基づいています。WAMは副作用モデルを使用します。このモデルでは、値が破壊的に論理変数に割り当てられ、これらの副作用はバックトラック時に元に戻されます。WAMの命令を拡張することにより、Prologに多くの機能を追加できます。このアプローチの欠点の1つは、WAMを十分に理解しないと、Prologの実装に関する論文が読みにくい場合があることです。一方、Prologの実装者は、実装の問題を議論するための共通のモデルを持っています。並行して多くの研究が行われており、1990年代にはアンドラプロローグで最高潮に達しました。これらのアイデアの少なくとも一部は、Ciao Prologに残っています。(Ciao Prologには興味深いアイデアがたくさんあり、その多くはProlog標準をはるかに超えています。)

Prologには、統一に基づく美しい「パターンマッチング」スタイルの構文があり、非常に簡潔なプログラムになります。Lispersがs式を愛するように、プロローガーは構文を愛しています。Prologには、標準述語の大規模なライブラリもあります。WAMを高速化するために行われたすべてのエンジニアリングにより、非常に有能で成熟したProlog実装があります。その結果、多くの大規模な知識ベースのシステムが完全にPrologで記述されています。

miniKanrenは、最小限のロジックプログラミング言語として設計されており、小さく、理解しやすく、ハッキングしやすい実装を備えています。miniKanrenは当初Schemeに組み込まれており、過去10年間で他の何十ものホスト言語に移植されてきました。最も人気のあるminiKanrenの実装はClojureの 'core.logic'で、多くのPrologのような拡張機能と多数の最適化が追加されています。最近、miniKanren実装のコアがさらに簡素化され、「microKanren」と呼ばれる小さな「マイクロカーネル」が生まれました。miniKanrenは、このmicroKanrenコアの上に実装できます。microKanrenまたはminiKanrenを新しいホスト言語に移植することは、miniKanrenを学習するプログラマーにとって標準的な課題となっています。結果として、

miniKanrenとmicroKanrenの標準実装には、変異やその他の副作用は含まれていませんが、1つの例外があります。miniKanrenの一部のバージョンでは、論理変数の比較にポインターの等価性を使用します。私はこれを「良性の影響」と考えていますが、多くの実装では、実装にカウンターを渡すことでこの影響さえ回避しています。グローバルなファクトデータベースもありません。miniKanrenの実装哲学は、関数型プログラミングに触発されています。変異や影響は回避する必要があり、すべての言語構造は字句スコープを尊重する必要があります。実装を注意深く見ると、いくつかのモナドに気付くかもしれません。検索の実装は、レイジーストリームの結合と操作に基づいており、ミューテーションを使用しません。これらの実装の選択は、Prologとは非常に異なるトレードオフにつながります。Prologでは、変数のルックアップは一定の時間ですが、バックトラックは副作用を取り消す必要があります。miniKanrenでは、変数ルックアップはより高価ですが、バックトラッキングは「無料」です。実際、ストリームの処理方法により、miniKanrenにはバックトラックはありません。

miniKanren実装の興味深い側面の1つは、コードが本質的にスレッドセーフであり、少なくとも理論的には明白に並列化可能であることです。もちろん、並列化のオーバーヘッドを補うのに十分な作業を各スレッドまたはプロセスに与える必要があるので、速度を遅くせずにコードを並列化することは簡単ではありません。それでも、これはminiKanren実装の領域であり、より多くの注意と実験を期待しています。

miniKanrenは、統一の発生チェックを使用し、深さ優先検索の代わりに完全なインターリーブ検索を使用します。インターリーブ検索は、深さ優先検索よりも多くのメモリを使用しますが、深さ優先検索が永久に発散/ループする場合に、回答を見つけることができます。miniKanrenはありません ---いくつかの余分な論理演算子をサポートするcondaconduproject、例えば。 condaまた、conduPrologのカットをシミュレートprojectするために使用でき、ロジック変数に関連付けられた値を取得するために使用できます。

存在condaconduおよびproject---そして検索戦略を簡単に変更する能力---プログラマーが埋め込まれたPrologのような言語としてminiKanrenを使用することを可能にします。これは、多くのPrologのような拡張機能を含むClojureの「core.logic」のユーザーに特に当てはまります。miniKanrenのこの「実用的な」使用は、業界におけるminiKanrenの使用の大部分を占めているようです。ClojureまたはPythonまたはJavaScriptで記述された既存のアプリケーションに知識ベースの推論システムを追加したいプログラマーは、一般に、Prologでアプリケーション全体を書き直すことに関心がありません。ClojureまたはPythonに小さなロジックプログラミング言語を埋め込むことは、はるかに魅力的です。埋め込まれたProlog実装は、おそらくこの目的でも同様に機能します。

miniKanrenは、Prologに似た実用的な組み込みロジックプログラミング言語として使用されているほか、「リレーショナル」プログラミングの研究にも使用されています。つまり、数学関数ではなく数学関係として動作するプログラムを作成する場合です。たとえば、Schemeでは、append関数は2つのリストを追加して新しいリストを返すことができます。関数呼び出し(append '(a b c) '(d e))はリストを返します(a b c d e)。ただし、append2つの引数の関数としてではなく、3つの場所の関係として扱うこともできます。次に、呼び出し(appendo '(a b c) '(d e) Z)はロジック変数Zをリストに関連付けます(a b c d e)。もちろん、ロジック変数を他の位置に配置すると、より興味深いものになります。コール・(appendo X '(d e) '(a b c d e))仲間Xとの(a b c)通話中に、(appendo X Y '(a b c d e))会合X及びY添付の場合、等しいリストの対を有します(a b c d e)。たとえば、X= (a b)Y= (c d e)はそのような値のペアの1つです。また、書くことができ(appendo X Y Z)、リストの無限に多くのトリプルを生み出すであろう、XY、そしてZ追加するようXY作成しますZ

このリレーショナルバージョンのappendは、Prologで簡単に表現でき、実際に多くのPrologチュートリアルに示されています。実際には、より複雑なPrologプログラムは、カットなどの少なくともいくつかの特別な機能を使用する傾向があり、結果として得られるプログラムを関係として処理する機能を阻害します。対照的に、miniKanrenは、このスタイルのリレーショナルプログラミングをサポートするように明示的に設計されています。miniKanrenのより最近のバージョンでは、(シンボリック制約解決のためのサポートを持っていますsymbolonumberoabsento、不平等制約、名目上の論理プログラミング)を使用して、関係として重要なプログラムを簡単に記述できます。実際には、私はminiKanrenの特別な機能を一切使用せず、すべてのminiKanrenプログラムを関係として記述します。最も興味深いリレーショナルプログラムは、Schemeのサブセットのリレーショナルインタープリターです。これらのインタープリターには、リスト(I love you)に評価する100万のSchemeプログラムを生成したり、単純にクイン(自分自身に評価するプログラム)を生成したりするなど、多くの興味深い機能があります。

miniKanrenは、このリレーショナルスタイルのプログラミングを可能にするために、Prologが行うトレードオフとは大きく異なる多くのトレードオフを行います。時間の経過とともに、miniKanrenはより多くのシンボリック制約を追加し、実際にはシンボリック指向の制約ロジックプログラミング言語になりました。多くの場合、これらのシンボリック制約によりcondu、およびのような余分な論理演算子の使用を回避することが現実的になりprojectます。他の場合では、これらのシンボリック制約では不十分です。シンボリック制約のより良いサポートはminiKanren研究の1つのアクティブな領域であり、関係として大規模でより複雑なプログラムをどのように記述するかというより広い問題があります。

要するに、miniKanrenとPrologはどちらも興味深い機能、実装、使用方法を備えており、両方の言語からアイデアを学ぶ価値があると思います。Mercury、Curry、Gödelなど、他にも非常に興味深いロジックプログラミング言語があり、それぞれに独自のロジックプログラミングがあります。

最後に、いくつかのminiKanrenリソースについて説明します。

メインのminiKanrenのWebサイト:http ://minikanren.org/

リレーショナルプログラミングとminiKanrenについてのインタビュー(Prologとの比較を含む):http : //www.infoq.com/interviews/byrd-relational-programming-minikanren

乾杯、

- 意志


9
今吹き飛ばされたらすみません。私はロジックと制約ベースのプログラミングで最初の思考実験を開始したばかりで、それが私の返答です。:)実際、あなたの答えでも述べたように、私は強力な疑わしい論理計算をモナドとして実装するのに最適な候補でした。それはより多くのMonadPlusであることがわかりました、そして確かにあなたの同僚のフリードマンによる論文とリファレンス実装があります!だから私はそれを読んで遊んでいます、それについての考えは?
Profpatsch 2015

4
microKanrenの論文とコードも興味深いと思います:webyrd.net/scheme-2013/papers/HemannMuKanren2013.pdfおよびgithub.com/jasonhemann/microKanren
William E. Byrd

5
また、毎週日曜日の午後3時(グリニッジ標準時-5:00)に、Googleハングアウトで週1回のminiKanrenコースを開催しています。参加を希望される場合は、@ webyrd Twitterアカウントのリンクを常にツイートします。以前に記録されたハングアウトは次の場所にあります:youtube.com/playlist
William E. Byrd

2
基本的には'05の論文と同じ検索モナドだと思います。また、SeresとSpiveyによる「Haskellへのプロローグの埋め込み」も参照してください。spivey.oriel.ox.ac.uk/
William E. Byrd

1
@ WilliamE.Byrd-素晴らしい答え!1つあるとすると、C / C ++プログラムに埋め込むことができる最高のminiKanren実装は何ですか?また、miniKanrenにはPrologの生成的な性質がありますか?つまり、式で変数を非接地のままにして、コアエンジンが、プログラムで宣言されている現在の関係を前提として、非接地変数のすべての可能な値を生成する機能ですか。
Robert Oschler、2015

4

仮の答え:

AFAIK、「The Reasoned Schemer」は、Scheme-y構文と関数型プログラミングスタイルで基本的なロジックプログラミングを導入し、ブール値「#t」に特に一定の目標「#u」(失敗)と「#s」(成功)を追加しました"および" #f "。それは、プロローグと同じ論理プログラミングへのアプローチを使用しました:統一とバックトラック検索。週末にその本を棚から取り出す時間があるかどうかを確認します。数学の分岐は、制限された形式の1次論理(この場合はホーン節)と解決法の不統一です。参照:計算論理:過去の記憶と将来への挑戦: John Alan Robinson、および初期の段階の論理プログラミングのためのRobert Kowalskiによる論理プログラミング


3
これらの2つの引用は、KanrenまたはMiniKanrenとどのように関係していますか?

2
最後の質問を参照してください:「それらはどの数学の分岐から来ましたか、そして理論的基礎は何ですか?」
Frank Shearar
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.