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