2
votes

I'm studying an example from book 'Prolog by Example' (by Helder Coelho and Jose C Cotta).

Write a program for designing an architectural unit
obeying the following specifications:

+ Two rectangular rooms
+ Each room has a window and interior door
+ Rooms are connected by interior door
+ One room also has an exterior door
+ A wall can have only one door or window
+ No window can face north
+ Windows cannot be on opposite sides of the unit

enter image description here

There is a solution but it doesn't work at SWI-Prolog, even doesn't compile.

I had to change solution from book: use 'dif(X,Y)' instead of 'X =\= Y'.

Can somebody explain: why original solution doesn't work?

Here is a code:

plan(FD,D1,W1,D2,W2) :-
  frontroom(FD,D1,W1),
  opposite(D1,D2),
  room(D2,W2),
  notopposite(W1,W2).

frontroom(FD,D,W) :-
  room(D,W),
  direction(FD),
  dif(FD,D),     % FD =\= D,   % <- original was commented
  dif(FD,W).     % FD =\= W.   % <- original was commented

room(D,W) :-
  direction(D),
  direction(W),
  dif(D,W),      % D =\= W,     % <- original was commented
  dif(W,north).  % W =\= north. % <- original was commented

direction(north).
direction(south).
direction(east).
direction(west).

opposite(north,south).
opposite(south,north).
opposite(east,west).
opposite(west,east).

notopposite(D1,D2) :-
  opposite(D1,D3),
  dif(D2,D3).  % D2 =\= D3. % <- original was commented

I can make query and get the answer:

?- plan(west,D1,W1,D2,W2).
D1 = east,
W1 = south,
D2 = west,
W2 = south

I'm trying to trace the original solution (with D2 =\= D3 instead of dif(D2,D3)) and get this:

[trace]  ?- plan(west,D1,W1,D2,W2).
   Call: (8) plan(west, _9632, _9634, _9636, _9638) ? creep
   Call: (9) frontroom(west, _9632, _9634) ? creep
   Call: (10) room(_9632, _9634) ? creep
   Call: (11) direction(_9632) ? creep
   Exit: (11) direction(north) ? creep
   Call: (11) direction(_9634) ? creep
   Exit: (11) direction(north) ? creep
   Call: (11) north=\=north ? creep
ERROR: Arithmetic: `north/0' is not a function

Why I cant use '=\='?

1
dif means you create a constraint, such that later if the two operands are grounded, it will fail if the two are the same. The =\= means that it should immediately be different.Willem Van Onsem
@WillemVanOnsem: Try 2 =\= 1+1. and 3 =\= 1+1false
@commentupvoter: It is incorrect that the grounding is of relevance. Consider dif(X,Y), X = Y here, nothing is grounded, and still this fails.false

1 Answers

2
votes

It should be rather \== than the incorrect =\=. I am unaware that =\= ever meant anything else than arithmetical inequality.

The 3rd edition of 1982 is online and =\= is even documented in the very same document as being part of DECsystem 10 Prolog as of 1978. So the contradiction is present even in this prior version of the mentioned book.

So far for the text. But you are absolutely right that dif/2 is preferable to (\==)/2. See this for more.