LoginSignup
3
2

More than 5 years have passed since last update.

Prologで解くZebraPuzzle

Last updated at Posted at 2017-06-10

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
neighbor(L,R,[L,R|_]).
neighbor(L,R,[_|Xs]) :- neighbor(L,R,Xs).

neighborx

neighborのより抽象的なもの
左右どちらでも通る

neighborx
neighborx(L,R,Xs) :- neighbor(L,R,Xs).
neighborx(L,R,Xs) :- neighbor(R,L,Xs).

drip

述語houseから要素を取り出す

drip
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

zebra.pro
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と==の使い方が間違っていることがわかりました.ありがとうございました

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2