?he'MATCH''Page %'
?fo 'Steve Hardy'- % -'10th March, 1977'
.mh
THE MATCHER
.br
-----------
.hm
.pg
This handout describes the 
MATCH
function.
.pg
Very frequently we want to write functions that compare
lists. There is a function provided for this called
"="
for example:-
 	: [A B C D] = [A B] <> [C D]
.br
this returns
TRUE.
"="
is very rigid; its arguments have to be exactly the same before
it returns
TRUE.
Sometimes we want to see if one list is like another, that is
whether it fits some pattern. For example, if you had a simple
conversational program that answered questions like:-
 	: [WHAT IS THE CAPITAL OF ENGLAND]
.br
or
 	: [WHAT IS THE AGE OF AARON]
.br
This progam might also be designed to accept assertions such as
 	: [THE CAPITAL OF ENGLAND IS LONDON]
.br
or
 	: [THE AGE OF AARON IS 21]
.br
.pg
This program might want a version of 
"="
so that you could write
 	: IF INPUT = [WHAT IS THE = OF =] THEN
.br
but as we know, this will not work.
.pg
In the library there is a function called
MATCH
which behaves like
"="
except that where its first argument contains "=", it doesn't
care what is in its second argument at that point.
That is:
 	: MATCH([WHAT IS THE = OF =], [WHAT IS THE AGE OF STEVE])
.br
returns TRUE.
(For a
simplified version of such a function, see the
CONVERSE
demo.)
.pg
Quite often, we not only want to know that the input is like
some 'template' but we want to know which things were "matched"
against the equal signs. The
MATCHer
provides a facility for doing this, thus:-
 	: MATCH([WHAT IS THE ?P OF ?X], INPUT)
.br
This returns
TRUE
if
INPUT
is
 	: [WHAT IS THE AGE OF AARON]
.br
and as a 'side affect', sets the variable "P" to be the word
"AGE"
and the variable "X" to be
"AARON"
If the input did not match the given pattern, then
MATCH
returns
FALSE
and the values of "P" and "X" will be 'undefined`.
(That is they may well have some rather odd value).
.pg
Here is a simple version of our conversation program.
.tp9
 	: FUNCTION REPLYTO(INPUT);
 	:	VARS P,X,V;
 	:	IF MATCH([WHAT IS THE ?P OF ?X], INPUT) THEN
 	:		LOOKUP(P,X)
 	:	ELSEIF MATCH([THE ?P OF ?X IS ?V], INPUT) THEN
 	:		ASSERT(P,X,V)
 	:	ELSE
 	:		[I DONT UNDERSTAND]
 	:	CLOSE
 	: END;
.br
We would have to define
ASSERT
and
LOOKUP
to access some database of facts. (See the
DATABASE
demo).
.pg
Suppose, however, that we wanted to see whether the input contained,
say, a word 
"MOTHER"
in
.ul
any
position. Clearly we have a problem because, as so far
described, the 
MATCHer
insists on knowing the position of everything in its template.
Consider the following
 	: IF MATCH([= MOTHER =], INPUT) THEN
 	: 	[TELL ME MORE ABOUT YOUR FAMILY]
 	: ELSEIF ...
.br
This is inadequate because it will only recognise an input sentence
with three words in it of which the 
middle word is the word
"MOTHER".
The following, however, is acceptable:-
 	: IF MATCH([== MOTHER ==], INPUT) THEN
 	: 	...
.br
Here, the "==" sign doesn't mean "match two things", it means
"match any number of things", (including "no things").
So the above condition evaluates to 
TRUE
if input is any of the following:-
.br
a) [MY MOTHER LIKES BUTTERED SCONES]
.br
b) [I HATE MY MOTHER]
.br
c) [MOTHER COOKED DELICIOUS APPLE PIES]
.br
but it will not match
.br
d) [MY FATHER SMOKES A PIPE]
.pg
Should we want to discover what the "==" was matched against, we
can write:-
 	: MATCH([??X MOTHER ??Y], INPUT)
.br
and, assuming the match is successful, the variables X and Y
will be set to the appropriate list. In the cases above:
.br
a) X = [MY], Y = [LIKES BUTTERED SCONES]
.br
b) X = [I HATE], Y = []
.br
c) X = [], Y = [COOKED DELICIOUS APPLE PIES]
.br
Do you see how you could write a program able to recognise and
process questions like
 	: [THE SECOND COUSIN OF JOHN SMITH IS FRED]
.br
or
 	: [WHAT IS THE OLD BUILDING OF THE FRENCH QUARTER].
