2
9
10:-op(500,xfy,--). 11:-op(359,xf,ject). 12
13
14:-public write_tree/1, answer/1, satisfy//2. 15
16:-mode write_tree(+). 17:-mode wt(+,+). 18:-mode header(+). 19:-mode decomp(+,-,-). 20:-mode complex(+). 21:-mode othervars(+,-,-). 22
23write_tree(T):-
24 numbervars(T,0,_),
25 wt(T,0),
26 fail.
27write_tree(_).
28
29wt((P:-Q),L) :- !, L1 is L+3,
30 write(P), tab(1), write((:-)), nl,
31 tab(L1), wt(Q,L1).
32wt((P,Q),L) :- !, L1 is L-2,
33 wt(P,L), nl,
34 tab(L1), put_char('&'), tab(1), wt(Q,L).
35wt({P},L) :- complex(P), !, L1 is L+2,
36 put_char('{'), tab(1), wt(P,L1), tab(1), put_char('}').
37wt(E,L) :- decomp(E,H,P), !, L1 is L+2,
38 header(H), nl,
39 tab(L1), wt(P,L1).
40wt(E,_) :- write(E).
41
([]).
43header([X|H]) :- write(X), tab(1), header(H).
44
45decomp(setof(X,P,S),[S,=,setof,X],P).
46decomp(\+(P),[\+],P) :- complex(P).
47decomp(numberof(X,P,N),[N,=,numberof,X],P).
48decomp(X^P,[exists,X|XX],P1) :- othervars(P,XX,P1).
49
50othervars(X^P,[X|XX],P1) :- !, othervars(P,XX,P1).
51othervars(P,[],P).
52
53complex((_,_)).
54complex({_}).
55complex(setof(_,_,_)).
56complex(numberof(_,_,_)).
57complex(_^_).
58complex(\+P) :- complex(P).
59
61
62:-mode respond(?). 63:-mode holds(+,?). 64:-mode answer(+). 65:-mode yesno(+). :-mode replies(+). 66:-mode reply(+). 67:-mode seto(?,+,-). 68:-mode satisfy(+). 69:-mode pickargs(+,+,+). 70:-mode pick(+,?). 71
72respond([]) :- display('Nothing satisfies your question.'), nl.
73respond([A|L]) :- reply(A), replies(L).
74
75answer((answer([]):-E)) :- !, holds(E,B), yesno(B).
76answer((answer([X]):-E)) :- !, seto(X,E,S), respond(S).
77answer((answer(X):-E)) :- seto(X,E,S), respond(S).
78
79seto(X,E,S) :-
81 phrase(satisfy(E,G),Vars),
83 ( setof(X,Vars^G,S)
84 -> true
85 ; S = []
86 ).
87
88holds(E,True) :-
89 phrase(satisfy(E, G), _),
90 ( G
91 -> True = true
92 ; True = false
93 ).
94
95yesno(true) :- display('Yes.').
96yesno(false) :- display('No.').
97
98replies([]) :- display('.').
99replies([A]) :- display(' and '), reply(A), display('.').
100replies([A|X]) :- display(', '), reply(A), replies(X).
101
102reply(N--U) :- !, write(N), display(' '), write(U).
103reply(X) :- write(X).
112satisfy((P0,Q0), (P,Q)) --> !, satisfy(P0, P), satisfy(Q0, Q).
113satisfy({P0}, (P->true)) --> !, satisfy(P0, P).
114satisfy(X^P0, P) --> !, satisfy(P0, P), [X].
115satisfy(\+P0, \+P) --> !, satisfy(P0, P).
116satisfy(numberof(X,P0,N), (setof(X,Vars^P,S),length(S,N))) --> !,
117 { phrase(satisfy(P0,P),Vars) },
118 [S], Vars. 119satisfy(setof(X,P0,S), setof(X,Vars^P,S)) --> !,
120 { phrase(satisfy(P0,P),Vars) },
121 Vars.
122satisfy(+P0, \+ exceptionto(P)) --> !,
123 satisfy(P0, P).
124satisfy(X<Y, X<Y) --> !.
125satisfy(X=<Y, X=<Y) --> !.
126satisfy(X>=Y, X>=Y) --> !.
127satisfy(X>Y, X>Y) --> !.
128satisfy(P, database(P)) --> [].
129
130exceptionto(P) :-
131 functor(P,F,N), functor(P1,F,N),
132 pickargs(N,P,P1),
133 exception(P1).
134
135exception(P) :- database(P), !, fail.
136exception(P).
137
138pickargs(0,_,_) :- !.
139pickargs(N,P,P1) :- N1 is N-1,
140 arg(N,P,S),
141 pick(S,X),
142 arg(N,P1,X),
143 pickargs(N1,P,P1).
144
145pick([X|_S],X).
146pick([_|S],X) :- !, pick(S,X).
147pick([],_) :- !, fail.
148pick(X,X)