?he 'SILLYSENT''Page % '
?fo 'Steven Hardy'- % -'\*(DY'


.ce 2
Silly Sentences
.br
_____ _________
.br

This handout describes an exercise in list processing that has the
desirable attribute of producing unexpected output.  The basis of
this behaviour is the function ONEOF.  Try the following:
 	: REPEAT 100 TIMES
 	:	ONEOF([CAT DOG GOAT GIRL BOY]) =>
 	: CLOSE;
.br
(Once you realise what ONEOF does, stop the program by typing 
CTRL X).

Now consider the following fragment of a 'grammar' for noun phrases:-
.bi
.in +5
.ti -5
A 'noun phrase' is
an 'article', followed  by a 'qualified noun'.
.br
.ti -5
An 'article' is
either "a", "the" or "another".
.ti -5
A 'qualified noun' is
either a 'noun' or an 'adjective' followed by a 'qualified noun'.
.ti -5
An 'adjective' is
either "red", "big", "happy" or "shiny".
.ti -5
A 'noun' is either "girl", "boy", "cat", "dog" or "goat".
.in -5
.ei
We can represent this grammar in many ways.  I suggest as a first
possibility, functions, thus:
 	: FUNCTION NOUN();
 	:	ONEOF([GIRL BOY CAT DOG GOAT])
 	: END;

 	: FUNCTION QNOUN();
 	:	IF	ONEOF([HEADS TAILS]) = "HEADS"
 	:	THEN	NOUN()
 	:	ELSE	[%ADJECTIVE(), QNOUN()%]
 	:	CLOSE
 	: END


Remember that the expression 
 	: [%ADJECTIVE(), QNOUN()%]
.br
means 'make a list of the results of applying the ADJECTIVE function
and the QNOUN function'.

.tp 10
Complete the set of function definitions needed to generate 'noun
phrases' and then try:
 	: REPEAT 100 TIMES
 	:	NOUNPHRASE() =>
 	: CLOSE;

After interrupting (with CTRL X) try tracing the functions you have defined
and then generate a few noun phrases.
.bb
Here is a more extensive grammar:
 	<NOUN>   :: = CAT | DOG | GOAT | GIRL | BOY | BLOCK
 	<ADJ>    :: = RED | BLUE | HAPPY | SHINY | BIG
 	<QNOUN>  :: = <NOUN> | <ADJ> <QNOUN>
 	<ARTICLE>:: = A | THE | ANOTHER
 	<NP>     :: = <ARTICLE> <QNOUN>
 	<VERB>   :: = LOVED | HATED | KICKED | PICKED UP
 	<VP>     :: = <VERB> <NP>
 	<ORDER>  :: = PICK UP | MOVE | DESCRIBE
 	<SENT>   :: = <ORDER> <NP> | <NP> <VP>
 		      | WHY DID <NP> <ORDER> <NP>
.br
.br

Grammars are not usually described in English (as above).
One commonly used formalism is
'Backus Normal Form' (BNF) notation.  To  understand BNF
notation you need to know that "|" denotes an alternative, angle
brackets ("<"....">") denote a 'class name' and "::=" means 'can be
replaced by'.
Writing a class name followed by another (e.g. <VERB> <NP>)
denotes a string made of an instance of the first class followed by
an instance of the second.

Try encoding the above grammar as a set of POP11  functions.
.bb
The output of your program will be a nested list, for example:
 	: [[THE [HAPPY GIRL]] [KICKED [A [BIG [RED BALL]]]]]
.br
Can you write a function, called FLATTEN, which takes a nested list
like that above and produces a simple list, for example:
 	: [THE HAPPY GIRL KICKED A BIG RED BALL]
.br
.br
Here's a way of writing FLATTEN:
 	: FUNCTION FLATTEN (LIST);
 	:	IF	LIST = NIL
 	:	THEN	...
 	:	ELSEIF	ATOM(HD(LIST))
 	:	THEN	[%HD(LIST)%] <> FLATTEN (...)
 	:	ELSE	FLATTEN(...) <> FLATTEN (...)
 	:	CLOSE
 	: END
.bb
Exercises
.br
=========
.br
There are a number of ways of continuing this silly sentences mini 
project.

.br
(1)  Invent some 'grammars' of your own and generate
examples of  permissible 'sentences'.  For example
can you write a grammar to describe 'number nouns' like
'three hundred and forty two'.
(Such a grammar is shown below in exercise 5.)
.bb
(2)  Some people think that a first step in understanding
natural language utterances is to 'unflatten' the utterance
(i.e. put back the brackets that FLATTEN removes).
Could there be any sense in this view?
Write an essay giving your opinion, and perhaps,
outlining a design for a program to unflatten sentences.
.bb
(3)  As you will have seen your program sometimes produces
sentences that make sense but more often don't.  For
example:
.br
 	: [WHY DID THE HAPPY BLOCK MOVE THE SHINY BLUE GIRL]
.br
.tp 10
I object to this for several reasons:
.bi
a)  Blocks can't be happy
.br
b)  Girls can't be blue or shiny
.br
.br
c)  Blocks can't move girls
.ei
Write an essay discussing this and other problems
in generating sensible sentences.

It has been suggested that nouns and noun phrases should
have properties such as "animate" and "inanimate".  We
then say that adjectives have requirements which a noun must 
satisfy before the adjective can be applied.  For example,
HAPPY demands an animate 'argument'.  Similarly, verbs make 
requirements of their subjects (or better 'agents') and 'objects'
(for example, 'move' might require an animate agent).
How powerful a technique is this?
Could you implement a version of the program you have already written where, perhaps,
the various functions, like NOUN, took a list of required properties so that:
 	: NOUN([ANIMATE PLURAL])
.br
might produce GIRLS or BOYS but not GIRL or BLOCKS?
.bb
(4)
Consider the following 'grammar' to generate insults:
 	<INSULT> ::=	<SUGGEST> YOU <BADNAME>
 	<SUGGEST> ::=	GET LOST | GO JUMP IN A LAKE
 	<BADNAME> ::=	ROTTEN SWINE | FILTHY BEAST
.br
According to this grammar all the following are insults:
 	GET LOST YOU FILTHY SWINE
 	GO JUMP IN A LAKE YOU ROTTEN BEAST
 	GET LOST YOU ROTTEN BEAST
.br
Write a grammar to produce at least a hundred different insults,
then embody the grammar in a program
.bb
(5)
Consider the following grammar:
 	<UMP> ::=	ONE | TWO | ... | NINE
 	<UMPTEEN> ::=	TEN | ELEVEN | ... | NINETEEN
 	<UMPTY> ::=	TWENTY | THIRTY | ... | NINETY
 	<UPTO99> ::=	<UMP> | <UMPTEEN> | <UMPTY> | <UMPTY> <UMP>
 	<UMPHUM> ::=	<UMP> HUNDRED
 	<UPTO999> ::=	<UPTO99> | <UMPHUM> | <UMPHUM> AND <UPTO99>
.br
(a) Continue by defining UPTO999999.

(b) Repeat the whole exercise in French or German.

(c) Embody the grammar in a program.

(d) Write a program to take a number expressed as a list of digits
(for example [2 3 7] for 237) and to produce a list being its name
in English, or French or ... (for example
[TWO\ HUNDRED\ AND\ THIRTY\ SEVEN]).

(e) Write a program which generates a list of digits at random,
prints the English version of it and asks the user to type in the French
translation, which it then checks.
.br
.bb
(6)
Consider the following way of representing a grammar:
 	: [[UMP [ONE] [TWO] ... [NINE]]
 	:  [UMPTEEN [TEN] [ELEVEN] ... [NINETEEN]]
 	:  [UMPTY [TWENTY] [THIRTY] ... [NINETY]]
 	:  [UPTO99 [[UMP]] [[UMPTEEN]] [[UMPTY]] [[UMPTY] [UMP]]]
 	:  [UMPHUM [[UMP] HUNDRED]]
 	:  [UPTO999 [[UPTO99]] [[UMPHUM]] [[UMPHUM] AND [UPTO99]]]]
.br
.br
This list has one element for each type of class.
A typical element is in turn a list, whose HeaD is the class name and whose TaiL
is a list of possible replacements for that class.
A typical replacement is, yet again, a list the lements of which are
the the symbols with which the class name can be replaced.
If one of these symbols is in turn a list it denotes a class name,
which must be expanded.
.br
For comparison purposes the INSULT grammar shown above could be represented
as:
 	: [[INSULT [[SUGGEST] YOU [BADNAME]]]
 	:  [SUGGEST [GET LOST] [GO JUMP IN A LAKE]]
 	:  [BADNAME [FILTHY SWINE] [ROTTEN BEAST]]]
.br
Write a program to generate a member of a given class, for example:
.br
 	: VARS GRAMMAR;
.br
 	: [[INSULT [[SUGGEST] YOU [BADNAME]]
.br
 	:  [SUGGEST[GET LOST] [GO JUMP IN A LAKE]]
.br
 	:  [BADNAME [FILTHY SWINE] [ROTTEN BEAST]]]
.br
 	:	-> GRAMMAR;
.br
 	: GENERATE("SUGGEST") =>
.br
 	** [GET LOST]
.br
 	: GENERATE("BADNAME") =>
.br
 	** [FILTHY SWINE]
.br
 	: GENERATE("INSULT") =>
.br
 	** [[GET LOST] YOU [ROTTEN BEAST]]
.br
.br
You will find it helpful to have a function called LOOKUP which takes
a class name and returns the list of possible replacements.
For example:
.br
 	: TRACE GENERATE LOOKUP ONEOF;
.br
 	: GENERATE("INSULT") =>
.br
 	>GENERATE INSULT
.br
 	!>LOOKUP INSULT
.br
 	!<LOOKUP [[[SUGGEST] YOU [BADNAME]]]
.br
 	!>ONEOF [[[SUGGEST] YOU [BADNAME]]]
.br
 	!<ONEOF [[SUGGEST] YOU [BADNAME]]
.br
 	!>GENERATE SUGGEST
.br
 	!!>LOOKUP SUGGEST
.br
 	!!<LOOKUP [[GET LOST] [GO JUMP IN A LAKE]]
.br
 	!!>ONEOF [[GET LOST] [GO JUMP IN A LAKE]]
.br
 	!!<ONEOF [GO JUMP IN A LAKE]
.br
 	!<GENERATE [GO JUMP IN A LAKE]
.br
 	!>GENERATE BADNAME
.br
 	!!>LOOKUP BADNAME
.br
 	!!<LOOKUP [[FILTHY SWINE] [ROTTEN BEAST]]
.br
 	!!>ONEOF [[FILTHY SWINE] [ROTTEN BEAST]]
.br
 	!!<ONEOF [ROTTEN BEAST]
.br
 	!<GENERATE [ROTTEN BEAST]
.br
 	<GENERATE [[GO JUMP IN A LAKE] YOU [ROTTEN BEAST]]
.br
 	** [[GO JUMP IN A LAKE] YOU [ROTTEN BEAST]]
.br
.bb
(7)
Do you have any more ideas on how to unflatten sentences (exercise\ 2) having looked at
exercise 6?
.bb

Suggested reading
.br
-----------------
.bi
Edinburgh lecture notes (available from Pru or in the library).

Chomsky, Fontana modern masters series by John Lyons.
.ei
