In this appendix we shall develop a POP-11 program to answer questions which are well-formed sentences according to the grammar developed in the body of this chapter. We shall make use of the following database for all the examples:
[
[[the national gallery] isa [gallery]]
[[the tate gallery] isa [gallery]]
[[the national gallery] in [trafalgar square]]
[[trafalgar square] isa [square]]
[[hyde park] isa [park]]
[[hyde park] containing [the serpentine lake]]
[[the serpentine lake] isa [lake]]
[[trafalgar square] containing [nelsons column]]
[[nelsons column] isa [monument]]
[[hyde park] underground [marble arch]]
[[the tate gallery] underground [pimlico]]
[[trafalgar square] underground [charing cross]]
[[nelsons column] underground [charing cross]]
[[the national gallery] underground [charing cross]]
[[the serpentine lake] underground [marble arch]]
] -> database;
First, we need a new POP-11 procedure, which. It takes a POP-11 variable name and a list of patterns and discovers all possible ways of matching these consistently against the POP-11 database, so that multiple occurrences of any variable have the same value. The procedure which returns a list of the values taken by the given variable in each complete match:
which("x", [[?x isa [gallery]]
[?x in ?y]
[?y isa [square]]
[?y containing ?z]
[?z isa [monument]]])=>
** [[the national gallery]]
Our top-level procedure for producing a response from a question is answer. Unlike the versions of answer given in earlier chapters, this one does not match the question against a series of patterns, but begins by passing it to procedure S, the combined parser and meaning generator.
define answer(query) -> response;
vars meaning, destination, routelist;
;;; parse and semantically analyse sentence
S(query) -> meaning;
if meaning /= false then
if which("destination", meaning) matches
[?destination ==] then
route([victoria], destination) -> routelist;
if not(routelist) then
[route not found] -> response
else
reply(routelist) -> response
endif
else
[I do not know where that place is] -> response;
endif;
else
;;; cannot handle this question
[Sorry I do not understand.
Try rewording your question] -> response
endif;
enddefine;
If the question is a well-formed sentence, S returns a list of patterns, stored as the value of meaning, to be matched by which against the database; otherwise it returns <false>.
When the procedure S returns a list of patterns, the first part of the following if statement is carried out. If which finds at least one consistent match, then a value has been found for destination, and this can be given as input to route. The result of calling route is a list of stations and times, and these can then be passed to a procedure reply, which composes an English sentence:
define reply(list) -> response;
;;;
;;; Convert route list into English description of form:
;;;
;;; travelling by underground, take the ... line to ...
;;; then change and take the ... line to ...
;;; then change and take the ... line to ...
;;; ...
;;;
vars line, station, line1, response;
list --> [[[?line ??station] ==] ??list];
[travelling by underground, take the ^line line to]
-> response;
while list matches [[[?line1 ??station] ==] ??list] do
if line1 /= line then
[^^response ^^station then change and
take the ^line1 line to] -> response;
line1 -> line;
endif;
endwhile;
[^^response ^^station] -> response;
enddefine;