アインシュタインのプロローグ問題

アブレインに関するアインシュタインの仕事の週を続けたいと思いました。 非常に非常に非標準的なソリューションの後、論理プログラミング言語で論理タスクをどのように解決できるか(および解決すべきか)を示したいと思います(トートロジーについてはごめんなさい)。

カットの下で、Prologがこのタスクに非常に適している理由を確認できます。



タスクはおそらくみんなにうんざりしているので、簡単に説明します。

同志xonixはすでにプロローグ基本を非常によく描いているので、私の仕事は非常に簡単です。



所有者の国籍、ペット、タバコのブランド、飲み物、家の色など、属性ごとに1つずつ、5つの要素のリストとして家を提示します。 合計で5つの家があるため、長さ5のリスト(リスト)の中から解決策を探します。

これを行うには、標準の述語が必要です。

また、2軒の家が隣り合っていると言うことができる必要があります。 これは、次の単純な述語で実装できます。

neighbors ( X , Y , List ) :- nextto ( X , Y , List ) .

neighbors ( X , Y , List ) :- nextto ( Y , X , List ) .





つまり、XがYの左側にあるか、その逆です。



そして実際、ここに解決策があります。

einstein :-

/* 0. 5 */

Houses = [ _ , _ , _ , _ , _ ] ,

/* 1. . */

nth1 ( 1 , Houses , [ norwegian , _ , _ , _ , _ ] ) ,

/* 2. . */

member ( [ englishman , _ , _ , _ , red ] , Houses ) ,

/* 3. , . */

nextto ( [ _ , _ , _ , _ , green ] , [ _ , _ , _ , _ , white ] , Houses ) ,

/* 4. . */

member ( [ dane , _ , _ , tea , _ ] , Houses ) ,

/* 5. , Marlboro, , . */

neighbors ( [ _ , _ , marlboro , _ , _ ] , [ _ , cat , _ , _ , _ ] , Houses ) ,

/* 6. , , Dunhill. */

member ( [ _ , _ , dunhill , _ , yellow ] , Houses ) ,

/* 7. Rothmans. */

member ( [ german , _ , rothmans , _ , _ ] , Houses ) ,

/* 8. , , . */

nth1 ( 3 , Houses , [ _ , _ , _ , milk , _ ] ) ,

/* 9. , Marlboro, . */

neighbors ( [ _ , _ , marlboro , _ , _ ] , [ _ , _ , _ , water , _ ] , Houses ) ,

/* 10. , Pall Mall, . */

member ( [ _ , bird , pallmall , _ , _ ] , Houses ) ,

/* 11. . */

member ( [ swede , dog , _ , _ , _ ] , Houses ) ,

/* 12. . */

neighbors ( [ norwegian , _ , _ , _ , _ ] , [ _ , _ , _ , _ , blue ] , Houses ) ,

/* 13. , , . */

member ( [ _ , horse , _ , _ , blue ] , Houses ) ,

/* 14. , Winfield, . */

member ( [ _ , _ , winfield , beer , _ ] , Houses ) ,

/* 15. . */

member ( [ _ , _ , _ , coffee , green ] , Houses ) ,



/* , : ? */

member ( [ Owner , fish , _ , _ , _ ] , Houses ) ,



/* */

print ( 'Owner of the fish: ' ) , print ( Owner ) , nl ,

print ( 'Full Solution: ' ) , print ( Houses ) , nl .









ご覧のとおり、プログラムの行の総数は、元の問題の条件の数とほぼ一致しています。

また、行自体は元の条件とほとんど同じように読み取られます。 プロローグは非常に宣言的な言語であり、必要なものを記述するだけです。

通訳は私たちのためにすべての汚い仕事を非常に迅速に行います。 私のマシンでは、スクリプトは0.08秒で実行されます。コンパイルすると、少し速くなります。



プログラムを開始するには、SWI-Prologをインストールする必要があります。テキストをファイルにコピーし、そのようなハッシュバンを追加します。

/ usr / bin / pl - q - t einstein - s

(まあ、またはここからコード取ります



これらの関数は標準ライブラリに含まれています。 ここでは完全性のために、「きれいな」プロローグであってもソリューションがそれほど大きくないことを示します。

member ( X , [ X | _]).

member ( X , [_ | Rest ]) :- member ( X , Rest ).



nth1 ( 1 , [ Elem | _], Elem ).

nth1 ( N , [_ | Rest ], Elem ) :- N > 1 , K is N - 1 , nth1 ( K , Rest , Elem ).



nextto ( L , R , [ L , R | _]).

nextto ( L , R , [_ | Rest ]) :- nextto ( L , R , Rest ).







また、条件0、1、および8は1つに簡略化できます。

Houses = [[norwegian,_,_,_,_],_,[_,_,_,milk,_],_,_]



その場合、nth1述部は必要ありませんが、可能な限りオリジナルに近いものにしたかったのです。



All Articles