1/* @(#)talkr.pl	24.1 2/23/88 */
    2
    3/*
    4	Copyright 1986, Fernando C.N. Pereira and David H.D. Warren,
    5
    6			   All Rights Reserved
    7*/
    8/* Simplifying and executing the logical form of a NL query. */
    9
   10:-public write_tree/1, answer/1, satisfy/1.   11
   12:-mode write_tree(+).
   13:-mode wt(+,+).
   14:-mode header(+).
   15:-mode decomp(+,-,-).
   16:-mode complex(+).
   17:-mode othervars(+,-,-).
   18
   19write_tree(T):-
   20   numbervars(T,0,_),
   21   wt(T,0),
   22   fail.
   23write_tree(_).
   24
   25wt((P:-Q),L) :- !, L1 is L+3,
   26   write(P), tab(1), write((:-)), nl,
   27   tab(L1), wt(Q,L1).
   28wt((P,Q),L) :- !, L1 is L-2,
   29   wt(P,L), nl,
   30   tab(L1), put("&"), tab(1), wt(Q,L).
   31wt({P},L) :- complex(P), !, L1 is L+2,
   32   put("{"), tab(1), wt(P,L1), tab(1), put("}").
   33wt(E,L) :- decomp(E,H,P), !, L1 is L+2,
   34   header(H), nl,
   35   tab(L1), wt(P,L1).
   36wt(E,_) :- write(E).
   37
   38header([]).
   39header([X|H]) :- write(X), tab(1), header(H).
   40
   41decomp(setof(X,P,S),[S,=,setof,X],P).
   42decomp(\+(P),[\+],P) :- complex(P).
   43decomp(numberof(X,P,N),[N,=,numberof,X],P).
   44decomp(X^P,[exists,X|XX],P1) :- othervars(P,XX,P1).
   45
   46othervars(X^P,[X|XX],P1) :- !, othervars(P,XX,P1).
   47othervars(P,[],P).
   48
   49complex((_,_)).
   50complex({_}).
   51complex(setof(_,_,_)).
   52complex(numberof(_,_,_)).
   53complex(_^_).
   54complex(\+P) :- complex(P).
   55
   56% Query execution.
   57
   58:-mode respond(?).
   59:-mode holds(+,?).
   60:-mode answer(+).
   61:-mode yesno(+).         :-mode replies(+).
   62:-mode reply(+).
   63:-mode seto(?,+,-).
   64:-mode satisfy(+).
   65:-mode pickargs(+,+,+).
   66:-mode pick(+,?).
   67
   68respond([]) :- display('Nothing satisfies your question.'), nl.
   69respond([A|L]) :- reply(A), replies(L).
   70
   71answer((answer([]):-E)) :- !, holds(E,B), yesno(B).
   72answer((answer([X]):-E)) :- !, seto(X,E,S), respond(S).
   73answer((answer(X):-E)) :- seto(X,E,S), respond(S).
   74
   75seto(X,E,S) :-
   76%	portray_clause(({X} :- E)),
   77	phrase(satisfy(E,G),Vars),
   78%	portray_clause(({X} :- G)),
   79	(   setof(X,Vars^G,S)
   80	->  true
   81	;   S = []
   82	).
   83
   84holds(E,True) :-
   85	phrase(satisfy(E, G), _),
   86	(   G
   87	->  True = true
   88	;   True = false
   89	).
   90
   91yesno(true) :- display('Yes.').
   92yesno(false) :- display('No.').
   93
   94replies([]) :- display('.').
   95replies([A]) :- display(' and '), reply(A), display('.').
   96replies([A|X]) :- display(', '), reply(A), replies(X).
   97
   98reply(N--U) :- !, write(N), display(' '), write(U).
   99reply(X) :- write(X).
 satisfy(+Term, -Goal)//
Originally, Term was meta-interpreted. If we do not want every ^/2-term to act as an existential quantification, this no longer works. Hence, we now compile the term into a goal and compute the existentially quantified variables.
  108satisfy((P0,Q0), (P,Q)) --> !, satisfy(P0, P), satisfy(Q0, Q).
  109satisfy({P0}, (P->true)) --> !, satisfy(P0, P).
  110satisfy(X^P0, P) --> !, satisfy(P0, P), [X].
  111satisfy(\+P0, \+P) --> !, satisfy(P0, P).
  112satisfy(numberof(X,P0,N), (setof(X,Vars^P,S),length(S,N))) --> !,
  113	{ phrase(satisfy(P0,P),Vars) },
  114	[S], Vars.			% S is an internal variable!
  115satisfy(setof(X,P0,S), setof(X,Vars^P,S)) --> !,
  116	{ phrase(satisfy(P0,P),Vars) },
  117	Vars.
  118satisfy(+P0, \+ exceptionto(P)) --> !,
  119	satisfy(P0, P).
  120satisfy(X<Y, X<Y) --> !.
  121satisfy(X=<Y, X=<Y) --> !.
  122satisfy(X>=Y, X>=Y) --> !.
  123satisfy(X>Y, X>Y) --> !.
  124satisfy(P, database(P)) --> [].
  125
  126exceptionto(P) :-
  127   functor(P,F,N), functor(P1,F,N),
  128   pickargs(N,P,P1),
  129   exception(P1).
  130
  131exception(P) :- database(P), !, fail.
  132exception(P).
  133
  134pickargs(0,_,_) :- !.
  135pickargs(N,P,P1) :- N1 is N-1,
  136   arg(N,P,S),
  137   pick(S,X),
  138   arg(N,P1,X),
  139   pickargs(N1,P,P1).
  140
  141pick([X|S],X).
  142pick([_|S],X) :- !, pick(S,X).
  143pick([],_) :- !, fail.
  144pick(X,X)