Information Technology Reference
In-Depth Information
Figure 7.3.
The blocks-world program redone
blocks2.pl
% This is a list-based version of the blocks-world program.
% X appears before Y in list L.
before(X,Y,L) :- append(Z,[Y|_],L), append(_,[X|_],Z).
% The given blocks-world scene: three stacks of blocks
scene([[b1,b2],[b3,b4,b5,b6],[b7]]).
% above(X,Y) means that block X is somewhere above block Y.
above(X,Y) :- scene(L), member(Stack,L), before(X,Y,Stack).
% left(X,Y) means that block X is somewhere left of block Y.
left(X,Y) :- scene(L), before(Stack1,Stack2,L),
member(X,Stack1), member(Y,Stack2).
right(Y,X) :- left(X,Y).
This says that X appears before Y in list L if there is a list Z such that X appears
somewhere in Z , and joining Z to a list whose head is Y results in L .
This almost does the right thing:
?- before(2,4,[1,2,3,4,5]).
Yes
?- before(8,4,[1,2,3,4,5]).
ERROR: Out of global stack
The problem is the first atom in the body, append(_,[X|_],Z) . There are infinitely
many lists Z that contain X , and it may turn out that none of them satisfy the second
query. The solution is to change the order of the queries so that Z is generated as a
sublist of L :
% A better version
before(X,Y,L) :- append(Z,[Y|_],L), append(_,[X|_],Z).
This results in the desired behavior:
?- before(2,4,[1,2,3,4,5]).
Yes
?- before(8,4,[1,2,3,4,5]).
No
Search WWH ::




Custom Search