3

最初に、プログラム全体を投稿して申し訳ありませんが、私にはわからないので、どの部分が無関係なのかわかりません。これらは、SWI-Prolog での同じロジック パズルの 2 つのわずかに異なる実装です。1 つ目は成功し、2 つ目は失敗し、失敗の理由がわかりません。

パズル:

4 persons are having a diner:
Donna, Doreen, David, Danny

the woman (Donna,Doreen) are sitting vis-a-vis.
the men (David,Danny) are sitting vis-a-vis.

Each of them picked a unique meal and beverage.

1) Doreen sits next to the person that ordered risotto.
2) the salad came with a coke.
3) the person with the lasagna sits vis-a-vis the person with the milk.
4) david never drinks coffee.
5) donna only drinks water.
6) danny had no appetite for risotto.

who ordered the pizza?

私は次のアプローチを選択します

table with positions:

  1
4 O 2
  3

domain: positions{1,2,3,4}
variables: persons, meals, beverages

最初の非効率的な後続の実装:

solution(Pizza, Doreen, Donna, David, Danny) :-

    % assignment of unique positions to the variables
    unique(Doreen,Donna,David,Danny),
    unique(Lasagna,Pizza,Risotto,Salad),
    unique(Water,Coke,Coffee,Milk),

    % general setting
    vis_a_vis(Donna,Doreen),
    vis_a_vis(David,Danny),

    % the six constraints
    next_to(Doreen,Risotto),
    Salad = Coke,
    vis_a_vis(Lasagna,Milk),
    \+ David = Coffee,
    Donna = Water,
    \+ Danny = Risotto.



unique(X1,X2,X3,X4) :-
    pos(X1),
    pos(X2),
    \+ X1 = X2,
    pos(X3),
    \+ X1 = X3, \+ X2 = X3,
    pos(X4),
    \+ X1 = X4, \+ X2 = X4, \+ X3 = X4.

right(1,2).
right(2,3).
right(3,4).
right(4,1).

vis_a_vis(1,3).
vis_a_vis(3,1).
vis_a_vis(2,4).
vis_a_vis(4,2).

next_to(X,Y) :- right(X,Y).
next_to(X,Y) :- right(Y,X).

pos(1).
pos(2).
pos(3).
pos(4).

これは機能し、正しい結果が得られます。しかし、解決手順の節をより効率的にするために並べ替えようとすると (これは 2 番目の実装です)。

solution(Pizza, Doreen, Donna, David, Danny) :-

    % general setting
    vis_a_vis(Donna,Doreen),
    vis_a_vis(David,Danny),

    % the six constraints
    Salad = Coke,
    vis_a_vis(Lasagna,Milk),
    \+ David = Coffee,
    Donna = Water,
    \+ Danny = Risotto,

    % assignment of unique positions to the variables
    unique(Doreen,Donna,David,Danny),
    unique(Lasagna,Pizza,Risotto,Salad),
    unique(Water,Coke,Coffee,Milk).

    %% all other predicates are like the ones in the first implementation

ファイルを読み込もうとすると、変数が割り当てられていないという警告が表示されます。

Warning: /home/pizza.pl:28:
Singleton variable in \+: Coffee

計算は を返しますfalse。しかし、同じ結果を返すべきではありませんか? 違いの理由がわかりません...

4

1 に答える 1

1

警告は、否定が実行されたときに Coffe と Risotto がバインドされていないという事実によるものです。で置き換えると、警告は回避\+ David = Coffee,されDavid \= Coffee,ますが、解は計算されません。確かに、Coffee はバインドされていないため、David \= Coffee は常に失敗します。dif/2 を使用すると、ソリューションが機能し、より効率的になります。最初のスニペットは solution1/2 、これは solution2/5 と名付けました (dif/2 を使用):

solution2(Pizza, Doreen, Donna, David, Danny) :-

    % general setting
    vis_a_vis(Donna,Doreen),
    vis_a_vis(David,Danny),

    % the six constraints
    next_to(Doreen,Risotto), % note: you forgot this one
    Salad = Coke,
    vis_a_vis(Lasagna,Milk),
    dif(David, Coffee),
    Donna = Water,
    dif(Danny, Risotto),

    % assignment of unique positions to the variables
    unique(Doreen,Donna,David,Danny),
    unique(Lasagna,Pizza,Risotto,Salad),
    unique(Water,Coke,Coffee,Milk).

小さなテスト:

?- time(aggregate_all(count,solution1(P,A,B,C,D),N)).
% 380,475 inferences, 0.058 CPU in 0.058 seconds (100% CPU, 6564298 Lips)
N = 8.

?- time(aggregate_all(count,solution2(P,A,B,C,D),N)).
% 10,626 inferences, 0.002 CPU in 0.002 seconds (100% CPU, 4738996 Lips)
N = 8.
于 2014-11-16T16:23:13.750 に答える