0

論理パズルを解く Prolog プログラムを書いています。回答を印刷しようとすると、すべての回答に対して同じ回答が得られます。論理パズルの答えは次のとおりです。

  • ジュヌビエーブはサイズ 4 のマンザリータを購入しました
  • lucia はサイズ 7 の Graaffetz を購入しました
  • ショーナはサイズ 5 のウィリフォードを購入しました
  • Vanessa はサイズ 6 の Abbot Hill を購入しました

私のコードは次のとおりです。

customer(genevieve).
customer(lucia).
customer(shawna).
customer(vanessa).

shoesize(4).
shoesize(5).
shoesize(6).
shoesize(7).

manufactorer(abbothill).
manufactorer(manzarita).
manufactorer(graffetz).
manufactorer(williford).

solve :-
   shoesize(GenevieveShoesize),
   shoesize(LuciaShoesize),
   shoesize(ShawnaShoesize),
   shoesize(VanessaShoesize),
   all_different([GenevieveShoesize, LuciaShoesize, ShawnaShoesize,     VanessaShoesize]),
   manufactorer(AbbotHillManufactorer),
   manufactorer(ManzaritaManufactorer),
   manufactorer(GraffetzManufactorer),
   manufactorer(WillifordManufactorer),

   all_different([AbbotHillManufactorer, ManzaritaManufactorer, 
    GraffetzManufactorer, WillifordManufactorer]),
   List = [ [genevieve,GenevieveShoesize,AbbotHillManufactorer],
      [lucia,LuciaShoesize,ManzaritaManufactorer],
      [shawna,ShawnaShoesize,GraffetzManufactorer],
      [vanessa,VanessaShoesize,WillifordManufactorer]],

   \+(member([_,5,manzarita],List)),
   \+(member([_,6,manzarita],List)),
   \+(member([lucia,5,_],List)),
   \+(member([lucia,6,_],List)),
   \+(member([genevieve,_,abbothill],List)),
   \+(member([shawna,_,graffetz],List)),
   (member([vanessa,_,abbothill],List)),

   tell(genevieve,GenevieveShoesize,GeneieveManufactorer),
   tell(lucia,LuciaShoesize,LuciaManufactorer),
   tell(shawna,ShawnaShoesize,ShawnaManufactorer),
   tell(vanessa,VanessaShoesize,VanessaManufactorer).

all_different([H | T]) :- member(H,T), !, fail.
all_different([_ | T]) :- all_different(T).
all_different([]).


tell(X,Y,Z) :-
   customer(X),
   shoesize(Y),
   manufactorer(Z),
   write(X), write(' got their shoes from'),
   write(Y), write(' and is a size '), write(Z), nl.

SWI に行って、次のように依頼すると:

-tell(X,Y,Z) 出力: X はジュヌビエーブに等しく、Y は 4 に等しく、Z は修道院長の丘に等しい。

そして、たとえば、tell(vanessa,Y,Z) のように変数の 1 つを指定すると、次のように出力されます。Y と Z の値は同じままにします。

4

1 に答える 1

0

ロジック パズルの答えは次のとおりです。 -genevieve はサイズ 4 の manzarita を購入しました -lucia はサイズ 7 の Graaffetz を購入しました -shawna はサイズ 5 の williford を購入しました -vanessa はサイズ 6 の Abbot Hill を購入しました」

それらがパズルに対する唯一の答えである場合、ロジックは間違っています。コードはそれよりも多くの答えを生成します。

プログラムに応じたソリューションの一部を次に示します。

X = genevieve,
Y = 4,
Z = abbothill ;
genevieve got their shoes from4 and is a size manzarita
X = genevieve,
Y = 4,
Z = manzarita ;
genevieve got their shoes from4 and is a size graffetz
X = genevieve,
Y = 4,
Z = graffetz ;
genevieve got their shoes from4 and is a size williford
X = genevieve,
Y = 4,
Z = williford ;
genevieve got their shoes from5 and is a size abbothill
X = genevieve,
Y = 5,
Z = abbothill ;
genevieve got their shoes from5 and is a size manzarita
X = genevieve,
Y = 5,
Z = manzarita ;
genevieve got their shoes from5 and is a size graffetz
X = genevieve,
Y = 5,
Z = graffetz ;
genevieve got their shoes from5 and is a size williford
X = genevieve,
Y = 5,
Z = williford ;

実行できるすべての一意のソリューションを見つけたい場合:setof((X,Y,Z), tell(X,Y,Z), Y).

これにより、プログラムに応じて有効な64の異なるソリューションが生成されます。

たとえば、tell(vanessa,Y,Z) のように変数の 1 つを指定すると、次のように出力されます。Y と Z の値は同じままにします。

それは値YZ同じままにしません。それは単にそれY = 4, Z = abbothillが の最初の解であることを意味します。X = vanessa次の解を で生成することができ、常に同じではないこと;がわかります。例:YZ

?- tell(vanessa,Y,Z).
vanessa got their shoes from4 and is a size abbothill
Y = 4,
Z = abbothill ;
vanessa got their shoes from4 and is a size manzarita
Y = 4,
Z = manzarita ;
vanessa got their shoes from4 and is a size graffetz
Y = 4,
Z = graffetz ;
vanessa got their shoes from4 and is a size williford
Y = 4,
Z = williford ;
vanessa got their shoes from5 and is a size abbothill
Y = 5,
Z = abbothill ;

編集:あなたが解決しようとしているのがこの論理パズルである場合:

顧客は 4 人です: Genevieve、Lucia、Shawna、Vanessa

靴のサイズは 4、5、6、7 の 4 種類あります。

靴のメーカーは、アボット・ヒル、マンザリタ、グラフェッツ、ウィリフォードの 4 社です。

  1. マンザリータの靴とルシアのペアのうち、1 つはサイズ 7、もう 1 つはサイズ 4 でした。

  2. Genevieve のペアは、Abbott Hill フットウェアよりも 2 サイズ小さかった.

  3. Vanessa さんのペアは、Genevieve さんのペアより 2 サイズ大きかったです。

  4. グラフェッツの靴は、ショーナの靴よりもやや大きかった.

顧客ごとに、名前、靴のサイズ、靴のメーカーを次のような形式で表示します。

ジョーはサイズ 13 のナイキを購入しました。

トムはサイズ 12 のリーボックを購入しました。

次のようなものを使用できます。

customer(genevieve).
customer(lucia).
customer(shawna).
customer(vanessa).

shoesize(4).
shoesize(5).
shoesize(6).
shoesize(7).

manufactorer(abbothill).
manufactorer(manzarita).
manufactorer(graffetz).
manufactorer(williford).

four_or_seven(L):-
    member((lucia, 7, _), L),
    member((_, 4, manzarita), L).
four_or_seven(L):-
    member((lucia, 4, _), L),
    member((_, 7, manzarita), L).

less_than_abbott_hill(L):-
    member((genevieve, S0, _), L),
    member((_, S1, abbothill), L),
    S0 is S1-2.

vanessa_larger_than_genevieve(L):-
    member((vanessa, S0, _), L),
    member((genevieve, S1, _), L),
    S0 is S1+2.

graffetz_larger_than_shawna(L):-
    member((shawna, S0, _), L),
    member((_, S1, graffetz), L),
    S1 > S0.

solve:-
    shoesize(S0), manufactorer(M0),
    shoesize(S1), manufactorer(M1),
    shoesize(S2), manufactorer(M2),
    shoesize(S3), manufactorer(M3),
    all_different([M0,M1,M2,M3]),
    L = [(genevieve, S0, M0), (lucia, S1, M1), (shawna, S2, M2), (vanessa, S3, M3)],
    four_or_seven(L),
    less_than_abbott_hill(L),
    vanessa_larger_than_genevieve(L),
    graffetz_larger_than_shawna(L),
    print(L).

all_different([H | T]) :- member(H,T), !, fail.
all_different([_ | T]) :- all_different(T).
all_different([]).

print([(C, S, M)|T]):-
    format("~p bhought a size ~p ~p~n", [C,S,M]),
    print(T).

print([]).

このパズルには複数の解決策があることに注意してください。実行例:

?- [puzzle].
true.

?- solve.
genevieve bhought a size 4 manzarita
lucia bhought a size 7 graffetz
shawna bhought a size 4 williford
vanessa bhought a size 6 abbothill
true ;
genevieve bhought a size 4 manzarita
lucia bhought a size 7 graffetz
shawna bhought a size 5 williford
vanessa bhought a size 6 abbothill
true
于 2017-05-08T06:57:45.673 に答える