Strange warning and computation leads to constraint logic program

First, sorry to post the whole program, but since I don't know if there was a problem, I don't know which parts are irrelevant. These are two slightly different implementations of the same logic puzzle in SWI-Prolog, the first is the second and I cannot find the reason for the failure.

Puzzle:

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?

      

I take the following approach

table with positions:

  1
4 O 2
  3

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

      

First inefficient follow-up implementation:

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).

      

This works and gives the correct result. But when I try to change the order of the decision procedures to be more efficient (this is the second implementation)

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

      

When I try to upload a file, I get an unassigned variable warning:

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

      

and the calculation returns false

. But shouldn't it return the same result? I see no reason for the difference ...

+3


source to share


1 answer


the warning is due to the fact that Coffe and Risotto are not linked when the negation is done. If you replace \+ David = Coffee,

with David \= Coffee,

, you will avoid the warning, but the solution cannot be calculated. It should be clear that since coffee is unrelated David \ = Coffee always fails. You can use diff / 2, the solution will work and be more efficient. I called solution1 / 2 your first snippet and solution2 / 5 one (using 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).

      



little test:

?- 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.

      

+1


source







All Articles