Prologで研究を始めた初心者Prologerです.
ZebraPuzzleを解こう
きっかけはこちらの記事
Prolog実践入門 - AIに特化した老舗言語
Prolog界に足を踏み入れようとして,一番最初に拝見させていただいた記事でした
力も多少ついてきたということで,本格的なZebraPuzzleにチャレンジ!
ZebraPuzzleとは
参考:ZebraPuzzle
自力で解けるのは世界人口のうちわずか2%という問題らしいです,ぼくは残念ながら解けませんでした…
rscの日記:Zebra PuzzleをPythonで解いてみた。
rscさんがPythonで特にあたってルールの日本語訳を載せております.参考にさせていただきました
これらのルールをPrologで落とし込んでいきます
house(color, country, animal, drink, smoke)
colorで色,countryで国籍,animalでペット,drinkで飲み物,smokeでタバコの銘柄を表現しております
ここから既存の関数をもとに,いくつか関数を追加しました.以下関数説明で述べていきます
#関数説明
neighbor
隣の家かどうかを判定する関数
左右どちらにいるかを確認できる
neighbor(L,R,[L,R|_]).
neighbor(L,R,[_|Xs]) :- neighbor(L,R,Xs).
neighborx
neighborのより抽象的なもの
左右どちらでも通る
neighborx(L,R,Xs) :- neighbor(L,R,Xs).
neighborx(L,R,Xs) :- neighbor(R,L,Xs).
drip
述語houseから要素を取り出す
drip(color, house(Color,_,_,_,_), Color).
drip(country,house(_,Country,_,_,_),Country).
drip(animal, house(_,_,Animal,_,_), Animal).
drip(drink, house(_,_,_,Drink,_), Drink).
drip(smoke, house(_,_,_,_,Smoke), Smoke).
そうしてできたものがこちら
ZebraPuzzle
neighbor(L,R,[L,R|_]).
neighbor(L,R,[_|Xs]) :- neighbor(L,R,Xs).
neighborx(L,R,Xs) :- neighbor(L,R,Xs).
neighborx(L,R,Xs) :- neighbor(R,L,Xs).
drip(color, house(Color,_,_,_,_), Color).
drip(country,house(_,Country,_,_,_),Country).
drip(animal, house(_,_,Animal,_,_), Animal).
drip(drink, house(_,_,_,Drink,_), Drink).
drip(smoke, house(_,_,_,_,Smoke), Smoke).
zebra(X,Y) :-
Street = [H1,H2,H3,H4,H5],
member(house(red, english, _, _, _), Street),
member(house(_, spanish, dog, _, _), Street),
member(house(green, _, _, coffee, _), Street),
member(house(_, ukurina, _, tea, _), Street),
member(house(_, _,snail, _, oldgold), Street),
member(house(yellow, _, _, _, kools), Street),
member(house(_, _, _, orange, luckystrike), Street),
member(house(_, japanese, _, _, parliaments), Street),
neighbor(house(white,_,_,_,_), house(green,_,_,_,_), Street),
neighborx(house(_,_,_,_,chesterfields), house(_,_,fox,_,_), Street),
neighborx(house(_,_,_,_,kools), house(_,_,horse,_,_), Street),
neighborx(house(_,norwegian,_,_,_), house(blue,_,_,_,_), Street),
drip(drink, H3, Milk), Milk = milk,
drip(country, H1, Norw), Norw = norwegian,
member(house(_,X,_,water,_),Street),
member(house(_,Y,zebra,_,_),Street).
main :- zebra(X,Y).
※ (2017/06/12 修正 suharahiromichiさんありがとうございました)
結果
?- zebra(X,Y).
X = norwegian,
Y = japanese
うまくでてきました!
考察
whereの直前まではうまく通っているのですが,writeしてみるとMilk == milk
に引っかかるものが一つもない状態です
neighborxが原因でしょうか
進捗がで次第,追記をしていきます
(2017/06/12 追記) suharahiromichiさんのアドバイスから,typoと==の使い方が間違っていることがわかりました.ありがとうございました