2
8
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
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
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
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
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 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 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
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