341 lines
6.2 KiB
Perl
341 lines
6.2 KiB
Perl
|
%
|
||
|
% Monkey and Bananas:
|
||
|
%
|
||
|
% Forward chaining rules via CHR.
|
||
|
% rules inspired from ftp://ftp.cs.unibo.it:/pub/gaspari/fw_rules/
|
||
|
% Quite fast because no dynamic predicates are used to
|
||
|
% represent the facts.
|
||
|
% The amount of code generated is substantial however.
|
||
|
% Not optimized
|
||
|
%
|
||
|
% 970213 Christian Holzbaur
|
||
|
|
||
|
:- use_module(library(chr)).
|
||
|
|
||
|
handler monkey.
|
||
|
|
||
|
constraints phys_object/7, monkey/3, goal/5, found/0.
|
||
|
% explaination of constraints is missing here
|
||
|
|
||
|
:- op(900,fy,not).
|
||
|
% There is no such fact ('not exists' in SQL)
|
||
|
not Fact :- find_constraint( Fact, _), !, fail.
|
||
|
not _.
|
||
|
|
||
|
|
||
|
testcase(1) :-
|
||
|
phys_object(bananas,9-9,light,ceiling,_,_,ok),
|
||
|
phys_object(couch,7-7,heavy,floor,_,low,_),
|
||
|
phys_object(ladder,4-3,light,floor,_,high,_),
|
||
|
phys_object(blanket,7-7,light,_,_,_,_),
|
||
|
phys_object(garbage_can,3-5,light,floor,_,low,_),
|
||
|
monkey(7-7,couch,blanket),
|
||
|
goal(active,holds,bananas,_,_).
|
||
|
|
||
|
|
||
|
rule(1) @
|
||
|
goal(active,on,floor,A,B),
|
||
|
monkey(D,E,F) <=>
|
||
|
|
||
|
E\==floor
|
||
|
|
|
||
|
write('Jump onto the floor'),
|
||
|
nl,
|
||
|
monkey(D,floor,F),
|
||
|
goal(satisfied,on,floor,A,B).
|
||
|
|
||
|
|
||
|
rule(2) @
|
||
|
monkey(A,floor,B) \
|
||
|
goal(active,on,floor,D,E) <=>
|
||
|
|
||
|
write('Monkey is already on floor'),
|
||
|
nl,
|
||
|
goal(satisfied,on,floor,D,E).
|
||
|
|
||
|
|
||
|
rule(3) @
|
||
|
phys_object(A,B,C,floor,D,E,F) \
|
||
|
goal(active,on,A,H,I),
|
||
|
monkey(B,K,nothing) <=>
|
||
|
|
||
|
K\==A
|
||
|
|
|
||
|
write('Climb onto '),
|
||
|
write(A),
|
||
|
nl,
|
||
|
monkey(B,A,nothing),
|
||
|
goal(satisfied,on,A,H,I).
|
||
|
|
||
|
|
||
|
rule(4) @
|
||
|
goal(active,on,A,B,C),
|
||
|
phys_object(A,E,F,G,H,I,J),
|
||
|
monkey(E,L,M) ==>
|
||
|
|
||
|
M\==nothing
|
||
|
|
|
||
|
write('Put '),
|
||
|
nl,
|
||
|
goal(active,holds,nothing,O,P).
|
||
|
|
||
|
|
||
|
rule(5) @
|
||
|
goal(active,on,A,B,C),
|
||
|
phys_object(A,E,F,floor,G,H,I),
|
||
|
monkey(K,L,M) ==>
|
||
|
|
||
|
K\==E
|
||
|
|
|
||
|
goal(active,at,nothing,O,E).
|
||
|
|
||
|
|
||
|
rule(6) @
|
||
|
phys_object(A,B,C,floor,D,E,F),
|
||
|
monkey(B,A,H) \
|
||
|
goal(active,on,A,J,K) <=>
|
||
|
|
||
|
write('Monkey is already on '),
|
||
|
write(A),
|
||
|
nl,
|
||
|
goal(satisfied,on,A,J,K).
|
||
|
|
||
|
|
||
|
rule(7) @
|
||
|
goal(active,holds,nothing,A,B),
|
||
|
monkey(D,E,F),
|
||
|
phys_object(F,H,I,J,K,L,M) <=>
|
||
|
|
||
|
F\==nothing
|
||
|
|
|
||
|
write('Drop '),
|
||
|
write(F),
|
||
|
nl,
|
||
|
goal(satisfied,holds,nothing,A,B),
|
||
|
monkey(D,E,nothing),
|
||
|
phys_object(F,H,I,floor,K,L,M).
|
||
|
|
||
|
|
||
|
rule(8) @
|
||
|
goal(active,holds,nothing,A,B),
|
||
|
monkey(D,E,nothing) ==>
|
||
|
|
||
|
write('Monkey is holding nothing'),
|
||
|
nl,
|
||
|
goal(satisfied,holds,nothing,A,B).
|
||
|
|
||
|
|
||
|
rule(9) @
|
||
|
phys_object(ladder,A,B,floor,C,D,E) \
|
||
|
goal(active,holds,G,H,I),
|
||
|
phys_object(G,A,light,ceiling,K,L,M),
|
||
|
monkey(O,ladder,nothing) <=>
|
||
|
|
||
|
not phys_object(Q,R,S,G,T,U,V)
|
||
|
|
|
||
|
write('Grab '),
|
||
|
write(G),
|
||
|
nl,
|
||
|
monkey(O,ladder,G),
|
||
|
phys_object(G,A,light,nothing,K,L,M),
|
||
|
goal(satisfied,holds,G,H,I).
|
||
|
|
||
|
|
||
|
rule(10) @
|
||
|
goal(active,holds,A,B,C),
|
||
|
phys_object(A,E,light,ceiling,F,G,H),
|
||
|
phys_object(ladder,E,J,floor,K,L,M),
|
||
|
monkey(O,P,Q) ==>
|
||
|
|
||
|
P\==ladder
|
||
|
|
|
||
|
goal(active,on,ladder,S,T).
|
||
|
|
||
|
|
||
|
rule(11) @
|
||
|
goal(active,holds,A,B,C),
|
||
|
phys_object(A,E,light,ceiling,F,G,H),
|
||
|
phys_object(ladder,J,K,L,M,N,O) ==>
|
||
|
|
||
|
J\==E,
|
||
|
not goal(active,at,ladder,Q,E)
|
||
|
|
|
||
|
goal(active,at,ladder,R,E).
|
||
|
|
||
|
|
||
|
rule(12) @
|
||
|
goal(active,holds,A,B,C),
|
||
|
phys_object(A,E,light,F,G,H,I),
|
||
|
monkey(E,floor,nothing) <=>
|
||
|
|
||
|
F\==ceiling,
|
||
|
not phys_object(L,M,N,A,O,P,Q)
|
||
|
|
|
||
|
write('Grab '),
|
||
|
write(A),
|
||
|
nl,
|
||
|
phys_object(A,E,light,nothing,G,H,I),
|
||
|
monkey(E,floor,A),
|
||
|
goal(satisfied,holds,A,B,C).
|
||
|
|
||
|
|
||
|
rule(13) @
|
||
|
goal(active,holds,A,B,C),
|
||
|
phys_object(A,E,light,F,G,H,I),
|
||
|
monkey(E,F,K) ==>
|
||
|
|
||
|
F\==ceiling,
|
||
|
F\==floor
|
||
|
|
|
||
|
goal(active,on,floor,M,N).
|
||
|
|
||
|
|
||
|
rule(14) @
|
||
|
goal(active,holds,A,B,C),
|
||
|
phys_object(A,E,light,F,G,H,I),
|
||
|
monkey(K,L,M) ==>
|
||
|
|
||
|
F\==ceiling,
|
||
|
K\==E,
|
||
|
not goal(active,at,nothing,O,P)
|
||
|
|
|
||
|
goal(active,at,nothing,Q,E).
|
||
|
|
||
|
|
||
|
rule(15) @
|
||
|
goal(active,holds,A,B,C),
|
||
|
phys_object(A,E,light,F,G,H,I),
|
||
|
monkey(E,K,L) ==>
|
||
|
|
||
|
L\==nothing,
|
||
|
L\==A,
|
||
|
not goal(active,holds,nothing,N,O)
|
||
|
|
|
||
|
goal(active,holds,nothing,P,Q).
|
||
|
|
||
|
|
||
|
rule(16) @
|
||
|
goal(active,at,A,B,C),
|
||
|
monkey(E,floor,A),
|
||
|
phys_object(A,G,H,I,J,K,L) <=>
|
||
|
|
||
|
E\==C
|
||
|
|
|
||
|
write('Move '),
|
||
|
write(A),
|
||
|
write(' to '),
|
||
|
write(C),
|
||
|
nl,
|
||
|
phys_object(A,C,H,I,J,K,L),
|
||
|
monkey(C,floor,A),
|
||
|
goal(satisfied,at,A,B,C).
|
||
|
|
||
|
|
||
|
rule(17) @
|
||
|
goal(active,at,A,B,C),
|
||
|
monkey(E,F,A),
|
||
|
phys_object(A,H,I,J,K,L,M) ==>
|
||
|
|
||
|
F\==floor,
|
||
|
H\==C,
|
||
|
not goal(active,on,floor,O,P)
|
||
|
|
|
||
|
goal(active,on,floor,Q,R).
|
||
|
|
||
|
|
||
|
rule(18) @
|
||
|
goal(active,at,A,B,C),
|
||
|
phys_object(A,E,light,F,G,H,I),
|
||
|
monkey(K,L,M) ==>
|
||
|
|
||
|
E\==C,
|
||
|
M\==A,
|
||
|
not goal(active,holds,A,O,P)
|
||
|
|
|
||
|
goal(active,holds,A,Q,R).
|
||
|
|
||
|
|
||
|
rule(19) @
|
||
|
phys_object(A,B,light,C,D,E,F) \
|
||
|
goal(active,at,A,H,B) <=>
|
||
|
|
||
|
write('The object '),
|
||
|
write(A),
|
||
|
write(' is already at '),
|
||
|
write(B),
|
||
|
nl,
|
||
|
goal(satisfied,at,A,H,B).
|
||
|
|
||
|
|
||
|
rule(20) @
|
||
|
goal(active,at,nothing,A,B),
|
||
|
monkey(B,floor,nothing) <=>
|
||
|
|
||
|
write('Walk to '),
|
||
|
write(B),
|
||
|
nl,
|
||
|
monkey(B,floor,nothing),
|
||
|
goal(satisfied,at,nothing,A,B).
|
||
|
|
||
|
|
||
|
rule(21) @
|
||
|
goal(active,at,nothing,A,B),
|
||
|
monkey(D,floor,E),
|
||
|
phys_object(E,G,H,I,J,K,L) <=>
|
||
|
|
||
|
D\==B
|
||
|
|
|
||
|
write('Walk to '),
|
||
|
write(B),
|
||
|
write(' carrying '),
|
||
|
write(E),
|
||
|
nl,
|
||
|
monkey(B,floor,E),
|
||
|
phys_object(E,B,H,I,J,K,L),
|
||
|
goal(satisfied,at,nothing,A,B).
|
||
|
|
||
|
|
||
|
rule(22) @
|
||
|
goal(active,at,nothing,A,B),
|
||
|
monkey(D,E,F) ==>
|
||
|
|
||
|
E\==floor,
|
||
|
D\==B
|
||
|
|
|
||
|
goal(active,on,floor,H,I).
|
||
|
|
||
|
|
||
|
rule(23) @
|
||
|
monkey(A,B,C) \
|
||
|
goal(active,at,nothing,E,A) <=>
|
||
|
|
||
|
write('Monkey is already at '),
|
||
|
write(A),
|
||
|
nl,
|
||
|
goal(satisfied,at,nothing,E,A).
|
||
|
|
||
|
|
||
|
rule(24) @
|
||
|
goal(satisfied,A,B,C,D) ==>
|
||
|
|
||
|
not goal(active,F,G,H,I),
|
||
|
not found
|
||
|
|
|
||
|
write('CONGRATULATIONS the goals are satisfied'),
|
||
|
nl,
|
||
|
found.
|
||
|
|
||
|
|
||
|
rule(25) @
|
||
|
goal(active,holds,A,B,C),
|
||
|
phys_object(A,E,light,nothing,F,G,H),
|
||
|
monkey(E,J,A) ==>
|
||
|
|
||
|
write('Object '),
|
||
|
write(A),
|
||
|
write(' is already being held'),
|
||
|
nl,
|
||
|
goal(satisfied,holds,A,B,C).
|
||
|
|
||
|
end_of_file.
|