1/* @(#)chattop.pl	26.1 5/13/88 */
    2
    3/*
    4	Copyright 1986, Fernando C.N. Pereira and David H.D. Warren,
    5
    6			   All Rights Reserved
    7*/
    8
    9% CHATTOP.PL
   10
   11:-public hi/0, hi/1, quote/1.   12:-export((hi/0, hi/1, quote/1)).   13
   14:- mode control80(+),
   15	doing(+,+),
   16	uses(+,?),
   17        process(+),
   18        simplify(+,?),
   19        simplify(+,?,?),
   20	simplify_not(+,?),
   21        revand(+,+,?),
   22        report(?,+,+,+),
   23        report_item(+,?).   24
   25
   26/* ----------------------------------------------------------------------
   27	Simple questions
   28	These question do not require setof/3 and are useful for early
   29	testing of a system.
   30   ---------------------------------------------------------------------- */
   31
   32eg( [ does, america, contain, new_york, ? ] ).
   33eg( [ does, mexico, border, the, united_states, ? ] ).
   34eg( [ is, the, population, of, china, greater, than, nb(200), million, ? ] ).
   35eg( [ does, the, population, of, china, exceed, nb(1000), million, ? ] ).
   36eg( [ is, the, population, of, china, nb(840), million, ? ] ).
   37eg( [ does, the, population, of, china, exceed, the, population, of,
   38      india, ? ] ).
   39eg( [ is, spain, bordered, by, the, pacific, ? ] ).
   40eg( [ does, the, atlantic, border, spain, ? ] ).
   41eg( [ is, the, rhine, in, switzerland, ? ] ).
   42eg( [ is, the, united_kingdom, in, europe, ? ] ).
   43
   44
   45/* ----------------------------------------------------------------------
   46	Standard question set
   47	This is the standard chat question set, originally put together
   48	by David and Fernando and use in their papers. Quintus uses this
   49	set as a standard for performance comparisons.
   50   ---------------------------------------------------------------------- */
   51
   52ed(  1, [ what, rivers, are, there, ? ],
   53
   54		[amazon, amu_darya, amur, brahmaputra, colorado,
   55		congo_river, cubango, danube, don, elbe, euphrates, ganges,
   56		hwang_ho, indus, irrawaddy, lena, limpopo, mackenzie,
   57		mekong, mississippi, murray, niger_river, nile, ob, oder,
   58		orange, orinoco, parana, rhine, rhone, rio_grande, salween,
   59		senegal_river, tagus, vistula, volga, volta, yangtze,
   60		yenisei, yukon, zambesi]  ).
   61
   62ed(  2, [ does, afghanistan, border, china, ? ],
   63
   64		[true]  ).
   65
   66ed(  3, [ what, is, the, capital, of, upper_volta, ? ],
   67
   68		[ouagadougou]  ).
   69
   70ed(  4, [ where, is, the, largest, country, ? ],
   71
   72		[asia, northern_asia]  ).
   73
   74ed(  5, [ which, countries, are, european, ? ],
   75
   76		[albania, andorra, austria, belgium, bulgaria, cyprus,
   77		czechoslovakia, denmark, east_germany, eire, finland,
   78		france, greece, hungary, iceland, italy, liechtenstein,
   79		luxembourg, malta, monaco, netherlands, norway, poland,
   80		portugal, romania, san_marino, spain, sweden, switzerland,
   81		united_kingdom, west_germany, yugoslavia]  ).
   82
   83ed(  6, [ which, country, '''', s, capital, is, london, ? ],
   84
   85		[united_kingdom]  ).
   86
   87ed(  7, [ which, is, the, largest, african, country, ? ],
   88
   89		[sudan]  ).
   90
   91ed(  8, [ how, large, is, the, smallest, american, country, ? ],
   92
   93		[0--ksqmiles]  ).
   94
   95ed(  9, [ what, is, the, ocean, that, borders, african, countries,
   96	  and, that, borders, asian, countries, ? ],
   97
   98		[indian_ocean]  ).
   99
  100ed( 10, [ what, are, the, capitals, of, the, countries, bordering, the,
  101	  baltic, ? ],
  102
  103		[[[denmark]:[copenhagen], [east_germany]:[east_berlin],
  104		[finland]:[helsinki], [poland]:[warsaw],
  105		[soviet_union]:[moscow], [sweden]:[stockholm],
  106		[west_germany]:[bonn]]]  ).
  107
  108ed( 11, [ which, countries, are, bordered, by, two, seas, ? ],
  109
  110		[egypt, iran, israel, saudi_arabia, turkey]  ).
  111
  112ed( 12, [ how, many, countries, does, the, danube, flow, through, ? ],
  113
  114		[6]  ).
  115
  116ed( 13, [ what, is, the, total, area, of, countries, south, of, the, equator,
  117	  and, not, in, australasia, ? ],
  118
  119		[10228--ksqmiles]  ).
  120
  121ed( 14, [ what, is, the, average, area, of, the, countries, in, each,
  122	  continent, ? ],
  123
  124		[[africa,233--ksqmiles], [america,496--ksqmiles],
  125		[asia,485--ksqmiles], [australasia,543--ksqmiles],
  126		[europe,58--ksqmiles]]  ).
  127
  128ed( 15, [ is, there, more, than, one, country, in, each, continent, ? ],
  129
  130		[false]  ).
  131
  132ed( 16, [ is, there, some, ocean, that, does, not, border, any, country, ? ],
  133
  134		[true]  ).
  135
  136ed( 17, [ what, are, the, countries, from, which, a, river, flows, into,
  137	  the, black_sea, ? ],
  138
  139		[[romania,soviet_union]]  ).
  140
  141ed( 18, [ what, are, the, continents, no, country, in, which, contains, more,
  142	  than, two, cities, whose, population, exceeds, nb(1), million, ? ],
  143
  144		[[africa,antarctica,australasia]]  ).
  145
  146ed( 19, [ which, country, bordering, the, mediterranean, borders, a, country,
  147	  that, is, bordered, by, a, country, whose, population, exceeds,
  148	  the, population, of, india, ? ],
  149
  150		[turkey]  ).
  151
  152ed( 20, [ which, countries, have, a, population, exceeding, nb(10),
  153	  million, ? ],
  154
  155		[afghanistan, algeria, argentina, australia, bangladesh,
  156		brazil, burma, canada, china, colombia, czechoslovakia,
  157		east_germany, egypt, ethiopia, france, india, indonesia,
  158		iran, italy, japan, kenya, mexico, morocco, nepal,
  159		netherlands, nigeria, north_korea, pakistan, peru,
  160		philippines, poland, south_africa, south_korea,
  161		soviet_union, spain, sri_lanka, sudan, taiwan, tanzania,
  162		thailand, turkey, united_kingdom, united_states, venezuela,
  163		vietnam, west_germany, yugoslavia, zaire]  ).
  164
  165ed( 21, [ which, countries, with, a, population, exceeding, nb(10), million,
  166	  border, the, atlantic, ? ],
  167
  168		[argentina, brazil, canada, colombia, france, mexico,
  169		morocco, netherlands, nigeria, south_africa, spain,
  170		united_kingdom, united_states, venezuela, west_germany,
  171		zaire]  ).
  172
  173ed( 22, [ what, percentage, of, countries, border, each, ocean, ? ],
  174
  175		[[arctic_ocean,2], [atlantic,35], [indian_ocean,14],
  176		[pacific,20]]  ).
  177
  178ed( 23, [ what, countries, are, there, in, europe, ? ],
  179
  180		[albania, andorra, austria, belgium, bulgaria, cyprus,
  181		czechoslovakia, denmark, east_germany, eire, finland,
  182		france, greece, hungary, iceland, italy, liechtenstein,
  183		luxembourg, malta, monaco, netherlands, norway, poland,
  184		portugal, romania, san_marino, spain, sweden, switzerland,
  185		united_kingdom, west_germany, yugoslavia]  ).
  186
  187
  188/* ----------------------------------------------------------------------
  189	Simple Access to demonstrations
  190   ---------------------------------------------------------------------- */
  191
  192demo(Type) :- demo(Type,L), inform(L), check_words(L,S), process(S).
  193
  194demo(mini,List) :- eg(List).
  195demo(main,List) :- ed(_,List,_).
  196
  197inform(L) :- nl, write('Question: '), inform1(L), nl, !.
  198
  199inform1([]).
  200inform1([H|T]) :- write(H), put(32), inform1(T).
  201
  202
  203/* ----------------------------------------------------------------------
  204	Top level processing for verification and performance analysis
  205   ---------------------------------------------------------------------- */
  206
  207test_chat :- test_chat(_).
  208
  209test_chat(N) :-
  210	show_title,
  211	ed(N,Sentence,CorrectAnswer),
  212	  process(Sentence,CorrectAnswer,Status,Times),
  213	  show_results(N,Status,Times),
  214	fail.
  215test_chat(_).
  216
  217test :-
  218	time(rtest_chats(20)).
  219
  220					% added JW
  221rtest_chats(0) :- !.
  222rtest_chats(N) :-
  223	rtest_chat(1),
  224	NN is N - 1,
  225	rtest_chats(NN).
  226
  227rtest_chat(N) :-
  228	ed(N,Sentence,CorrectAnswer), !,
  229	  process(Sentence,CorrectAnswer,Status,_Times),
  230	  (   Status == true
  231	  ->  true
  232	  ;   format(user_error, 'Test ~w failed!~n', [N])
  233	  ),
  234	NN is N + 1,
  235	rtest_chat(NN).
  236rtest_chat(_).
  237
  238show_title :-
  239	format('Chat Natural Language Question Anwering Test~n~n',[]),
  240	show_format(F),
  241	format(F, ['Test','Parse','Semantics','Planning','Reply','TOTAL']),
  242	nl.
  243
  244show_results(N,Status,Times) :-
  245	show_format(F),
  246	format(F, [N|Times]),
  247	( Status = true ->
  248		nl
  249	; otherwise ->
  250		tab(2), write(Status), nl
  251	).
  252
  253show_format( '~t~w~10+ |~t~w~12+~t~w~10+~t~w~10+~t~w~10+~t~w~10+' ).
  254
  255
  256process(Sentence,CorrectAnswer,Status,Times) :-
  257	process(Sentence,Answer,Times),
  258	!,
  259	check_answer(Answer,CorrectAnswer,Status).
  260process(_,_,failed,[0,0,0,0,0]).
  261
  262
  263process(Sentence,Answer,[Time1,Time2,Time3,Time4,TotalTime]) :-
  264	statistics(runtime, [T0, _]),
  265
  266	  sentence(E,Sentence,[],[],[]),
  267
  268	statistics(runtime, [T1, _]),
  269	Time1 is T1 - T0,
  270	statistics(runtime, [T2, _]),
  271
  272	  i_sentence(E,QT),
  273	  clausify(QT,UE),
  274	  simplify(UE,S),
  275
  276	statistics(runtime, [T3, _]),
  277	Time2 is T3 - T2,
  278	statistics(runtime, [T4, _]),
  279
  280	  qplan(S,S1), !,
  281
  282	statistics(runtime, [T5, _]),
  283	Time3 is T5 - T4,
  284	statistics(runtime, [T6, _]),
  285
  286	  answer(S1,Answer), !,
  287
  288	statistics(runtime, [T7, _]),
  289	Time4 is T7 - T6,
  290	TotalTime is Time1 + Time2 + Time3 + Time4.
  291
  292
  293	% Version of answer/1 from TALKR which returns answer
  294answer((answer([]):-E),[B]) :- !, holds(E,B).
  295answer((answer([X]):-E),S) :- !, seto(X,E,S).
  296answer((answer(X):-E),S) :- seto(X,E,S).
  297
  298check_answer(A,A,true) :- !.
  299check_answer(_,_,'wrong answer').
  300
  301
  302/* ----------------------------------------------------------------------
  303	Top level for runtime version, and interactive demonstrations
  304   ---------------------------------------------------------------------- */
  305
  306runtime_entry(start) :-
  307   version,
  308   format(user,'~nChat Demonstration Program~n~n',[]),
  309   hi.
  310
  311hi :-
  312   hi(user).
  313
  314hi(File) :-
  315   repeat,
  316      ask(File,P),
  317      control80(P), !,
  318      end(File).
  319
  320ask(user,P) :- !,
  321   write('Question: '),
  322   ttyflush,
  323   read_in(P).
  324ask(File,P) :-
  325   seeing(Old),
  326   see(File),
  327   read_in(P),
  328   nl,
  329   doing(P,0),
  330   nl,
  331   see(Old).
  332
  333doing([],_) :- !.
  334doing([X|L],N0) :-
  335   out(X),
  336   advance(X,N0,N),
  337   doing(L,N).
  338
  339out(nb(X)) :- !,
  340   write(X).
  341out(A) :-
  342   write(A).
  343
  344advance(X,N0,N) :-
  345   uses(X,K),
  346   M is N0+K,
  347 ( M>72, !,
  348      nl,
  349      N is 0;
  350   N is M+1,
  351      put(" ")).
  352
  353uses(nb(X),N) :- !,
  354   chars(X,N).
  355uses(X,N) :-
  356   chars(X,N).
  357
  358chars(X,N) :- atomic(X), !,
  359   name(X,L),
  360   length(L,N).
  361chars(_,2).
  362
  363end(user) :- !.
  364end(F) :-
  365   close(F).
  366
  367control80([W,'.']) :- 
  368   (W==bye; W==quit; W==exit; W==done; W==thanks),
  369   !,
  370   display('Cheerio.'),
  371   nl.
  372control80([trace,'.']) :- !,
  373   tracing ~= on,
  374   display('Tracing from now on!'), nl, fail.
  375control80([do,not,trace,'.']) :- !,
  376   tracing ~= off,
  377   display('No longer tracing.'), nl, fail.
  378control80([do,mini,demo,'.']) :- !,
  379   display('Executing mini demo...'), nl,
  380   demo(mini), fail.
  381control80([do,main,demo,'.']) :- !,
  382   display('Executing main demo...'), nl,
  383   demo(main), fail.
  384control80([test,chat,'.']) :- !,
  385   test_chat, fail.
  386control80(U0) :-
  387   check_words(U0,U),
  388   process(U),
  389   fail.
  390
  391process(U) :-
  392   statistics(runtime, [_, _]),
  393   sentence(E,U,[],[],[]),
  394   statistics(runtime, [_, Et0]),
  395   report(E,'Parse',Et0,tree),
  396   statistics(runtime, [_, _]),
  397   logic(E,S),
  398   statistics(runtime, [_, Et1]),
  399   report(S,'Semantics',Et1,expr),
  400   statistics(runtime, [_, _]),
  401   qplan(S,S1), !,
  402   statistics(runtime, [_, Et2]),
  403   report(S1,'Planning',Et2,expr),
  404   statistics(runtime, [_, _]),
  405   answer(S1), !, nl,
  406   statistics(runtime, [_, Et3]),
  407   report(_,'Reply',Et3,none).
  408process(_) :-
  409   failure.
  410
  411failure :-
  412   display('I don''t understand!'), nl.
  413
  414report(Item,Label,Time,Mode) :-
  415   tracing =: on, !,
  416   nl, write(Label), write(': '), write(Time), write('msec.'), nl,
  417   report_item(Mode,Item).
  418report(_,_,_,_).
  419
  420report_item(none,_).
  421report_item(expr,Item) :-
  422   write_tree(Item), nl.
  423report_item(tree,Item) :-
  424   print_tree(Item), nl.
  425%report_item(quant,Item) :-
  426%   pp_quant(Item,2), nl.
  427
  428quote(A&R) :-
  429   atom(A), !,
  430   quote_amp(R).
  431quote(_-_).
  432quote(_--_).
  433quote(_+_).
  434quote(verb(_,_,_,_,_)).
  435quote(wh(_)).
  436quote(name(_)).
  437quote(prep(_)).
  438quote(det(_)).
  439quote(quant(_,_)).
  440quote(int_det(_)).
  441
  442quote_amp('$VAR'(_)) :- !.
  443quote_amp(R) :-
  444   quote(R).
  445
  446logic(S0,S) :-
  447   i_sentence(S0,S1),
  448   clausify(S1,S2),
  449   simplify(S2,S).
  450
  451simplify(C,(P:-R)) :- !,
  452   unequalise(C,(P:-Q)),
  453   simplify(Q,R,true).
  454
  455simplify(setof(X,P0,S),R,R0) :- !,
  456   simplify(P0,P,true),
  457   revand(R0,setof(X,P,S),R).
  458simplify((P,Q),R,R0) :-
  459   simplify(Q,R1,R0),
  460   simplify(P,R,R1).
  461simplify(true,R,R) :- !.
  462simplify(X^P0,R,R0) :- !,
  463   simplify(P0,P,true),
  464   revand(R0,X^P,R).
  465simplify(numberof(X,P0,Y),R,R0) :- !,
  466   simplify(P0,P,true),
  467   revand(R0,numberof(X,P,Y),R).
  468simplify(\+P0,R,R0) :- !,
  469   simplify(P0,P1,true),
  470   simplify_not(P1,P),
  471   revand(R0,P,R).
  472simplify(P,R,R0) :-
  473   revand(R0,P,R).
  474
  475simplify_not(\+P,P) :- !.
  476simplify_not(P,\+P).
  477
  478revand(true,P,P) :- !.
  479revand(P,true,P) :- !.
  480revand(P,Q,(Q,P)).
  481
  482unequalise(C0,C) :-
  483   numbervars(C0,1,N),
  484   functor(V,v,N),
  485   functor(M,v,N),
  486   inv_map(C0,V,M,C).
  487
  488inv_map('$VAR'(I),V,_,X) :- !,
  489   arg(I,V,X).
  490inv_map(A=B,V,M,T) :- !,
  491   drop_eq(A,B,V,M,T).
  492inv_map(X^P0,V,M,P) :- !,
  493   inv_map(P0,V,M,P1),
  494   exquant(X,V,M,P1,P).
  495inv_map(A,_,_,A) :- atomic(A), !.
  496inv_map(T,V,M,R) :-
  497   functor(T,F,K),
  498   functor(R,F,K),
  499   inv_map_list(K,T,V,M,R).
  500
  501inv_map_list(0,_,_,_,_) :- !.
  502inv_map_list(K0,T,V,M,R) :-
  503   arg(K0,T,A),
  504   arg(K0,R,B),
  505   inv_map(A,V,M,B),
  506   K is K0-1,
  507   inv_map_list(K,T,V,M,R).
  508
  509drop_eq('$VAR'(I),'$VAR'(J),V,M,true) :- !,
  510 ( I=\=J, !,
  511      irev(I,J,K,L),
  512      arg(K,M,L),
  513      arg(K,V,X),
  514      arg(L,V,X);
  515   true).
  516drop_eq('$VAR'(I),T,V,M,true) :- !,
  517   deref(I,M,J),
  518   arg(J,V,T),
  519   arg(J,M,0).
  520drop_eq(T,'$VAR'(I),V,M,true) :- !,
  521   deref(I,M,J),
  522   arg(J,V,T),
  523   arg(J,M,0).
  524drop_eq(X,Y,_,_,X=Y).
  525
  526deref(I,M,J) :-
  527   arg(I,M,X),
  528  (var(X), !, I=J;
  529   deref(X,M,J)).
  530
  531exquant('$VAR'(I),V,M,P0,P) :-
  532   arg(I,M,U),
  533 ( var(U), !,
  534      arg(I,V,X),
  535       P=(X^P0);
  536   P=P0).
  537
  538irev(I,J,I,J) :- I>J, !.
  539irev(I,J,J,I).
  540
  541:- mode check_words(+,-).  542
  543check_words([],[]).
  544check_words([Word|Words],[RevWord|RevWords]) :-
  545   check_word(Word,RevWord),
  546   check_words(Words,RevWords).
  547
  548:- mode check_word(+,-).  549
  550check_word(Word,Word) :- word(Word), !.
  551check_word(Word,NewWord) :-
  552   display('? '), display(Word), display(' -> (!. to abort) '), ttyflush,
  553   read(NewWord0),
  554   NewWord0 \== !,
  555   check_word(NewWord0,NewWord).
  556
  557:- mode ~=(+,+), =+(+,-), =:(+,?).  558
  559Var ~= Val :-
  560 ( recorded(Var,val(_),P), erase(P)
  561 ; true), !,
  562 recordz(Var,val(Val),_).
  563
  564Var =+ Val :-
  565 ( recorded(Var,val(Val0),P), erase(P)
  566 ; Val0 is 0), !,
  567   Val is Val0+1,
  568   recordz(Var,val(Val),_).
  569
  570Var