カットの下で、Prologがこのタスクに非常に適している理由を確認できます。
タスクはおそらくみんなにうんざりしているので、簡単に説明します。
同志xonixはすでにプロローグの基本を非常によく描いているので、私の仕事は非常に簡単です。
所有者の国籍、ペット、タバコのブランド、飲み物、家の色など、属性ごとに1つずつ、5つの要素のリストとして家を提示します。 合計で5つの家があるため、長さ5のリスト(リスト)の中から解決策を探します。
これを行うには、標準の述語が必要です。
- member(Elem、List)-Elem要素がリストにある場合はtrue
- nth1(N、List、Elem)-リスト内のElem要素がN番目(カウントは1から始まる)にある場合はtrue
- nextto(X、Y、List)-リスト内でXがYの前(左側)にある場合はtrue
つまり、XがYの左側にあるか、その逆です。neighbors ( X , Y , List ) :- nextto ( X , Y , List ) .
neighbors ( X , Y , List ) :- nextto ( Y , X , List ) .
そして実際、ここに解決策があります。
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つに簡略化できます。
その場合、nth1述部は必要ありませんが、可能な限りオリジナルに近いものにしたかったのです。Houses = [[norwegian,_,_,_,_],_,[_,_,_,milk,_],_,_]