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;