TEACH STORYGRAMMAR                                Aaron Sloman June 1999
Slightly modified June 2000


In June 2000, the Sunday Times featured a story about a program called
"Brutus" which generated stories that some people thought were produced
by humans. The program was developed over a period of seven years by
Selmer Bringsjord, a professor of logic at Rensselaer Polytechnic
Institute

The news report was originally here, but seems no longer to be
accessible.

http://www.the-times.co.uk/news/pages/sti/2000/06/04/stifgnusa01009.html

More information, including sample stories, is available at:

    http://www.rpi.edu/~brings/

Three sample stories generated by Brutus are accessible here

    http://www.rpi.edu/dept/ppcs/BRUTUS/brutus.html

This (DRAFT) teach file explains how to use LIB GRAMMAR to generate
much simpler stories than those produced by Brutus.

As explained in TEACH GRAMMAR, the grammar library allows you to define
a simple grammar and a lexicon and then use the GENERATE procedure
defined in the library to create randomly generated sentences based on
the grammar and the lexicon.

The idea presented here is a simple generalisation. We think of a story
as a particular type of large scale "sentence", for which we can define
a grammar, with an appropriate lexicon.

The key idea is simple. We extend the idea of sentences as
hierarchically decomposable to stories as hierarchically decomposable.

In other words, just as a sentence may be composed of various parts
including sub-sentences, clauses, phrases, each of which can themselves
be composed of further parts of the same or different kinds, so can a
story be composed of parts, which themselves are composed of parts, etc.

It is advisable to read TEACH GRAMMAR before this file.

If you don't have Poplog you can view that file here:

    http://www.cs.bham.ac.uk/research/poplog/teach/grammar

CONTENTS FOR THE REST OF THIS FILE

 -- Stories as hierarchically decomposable structures
 -- Warning: this teach file has many over-simplifications
 -- First make LIB GRAMMAR available
 -- Generating Haikus
 -- Example haikus generated
 -- Exercise: improve/generalise the haikus
 -- The output of summarise
 -- Designing a simple story generator
 -- -- Testing partial grammars separately
 -- -- A story lexicon: story_lex
 -- -- A grammar for story beginnings
 -- -- Testing story beginnings
 -- -- Exercise: better beginnings?
 -- -- Story middles
 -- -- Testing story middles
 -- -- Exercise: better middles?
 -- -- story ends
 -- -- Testing story endings
 -- -- Exercise: better endings?
 -- -- Combining the parts into a single story grammar
 -- Test the full story generator
 -- Accommodating alternative story formats
 -- Exercise: more integrated stories
 -- Automatically analysing stories
 -- Reading

-- Stories as hierarchically decomposable structures ------------------

To create a grammar for stories, we start by think of the different
main components a story can have, and the different ways those
components can be put together to form a story.

Depending on how we view the story, the main components might be
sentences, or paragraphs, or chapters, or sub-stories corresponding to
different phase of the story.

We then do the same for the main story components, i.e. describe ways in
which they can also be decomposed into smaller components.

We continue doing this sort of decomposition until we get down to the
level of words of various types. The desired types of words and examples
of those words can then be described in a lexicon.

The Pop-11 LIB GRAMMAR package illustrated below treats the grammar and
lexicon as separate things so that you can easily use the same grammar
and change the lexicon, but in principle the lexicon could be treated as
part of the grammar.

-- Warning: this teach file has many over-simplifications -------------

It should be stressed that the methods described here will inevitably
produce very stilted stories because no explicit account is taken of the
meanings of words and phrases, and no mechanisms are provided for
transforming words to suit their context, e.g. changing a verb to past
or future tense, or ensuring that there is proper matching of selections
for sub-components, e.g. making a singular subject match a singular form
of a verb, and likewise for plural subjects.

So this should not be treated as a theory of how to produce realistic
stories. It is merely an introductory tutorial to introduce you to some
ways of thinking which may help you understand richer and more
sophisticated theories of language in general and stories in particular.

Before generating stories, we'll generate haikus to illustrate some of
the techniques, since they are much simpler than stories (at least
superficially).


-- First make LIB GRAMMAR available -----------------------------------

You can make the sentence generator and sentence analyser mechanisms
available by giving these two commands (the first loads a standard part
of the Poplog Pop-11 library, while the second loads a small extension
which is part of the Birmingham Pop-11 library):

    uses grammar
    uses generate_category

Those commands should go at the top of any file in which you develop
your own story grammar using the ideas presented below.

The generate_category procedure is in an autoloadable library. It
slightly extends the facilities described in TEACH GRAMMAR, allowing
other things than complete sentences to be generated.

If you don't have the second library available you can use this
definition of the procedure generate_category:

define generate_category(category, grammar, lexicon) -> sentence;
    ;;; Given a grammar and a lexicon, generate an example of the
    ;;; category, at random. The procedure subgen defined in
    ;;; lib grammar uses the global variables Grammar and Lexicon
    ;;; and the recursion depth indicator, Level.

    dlocal
        Grammar = grammar,
        Lexicon = lexicon,
        Level = 0;

    subgen(category) -> sentence;
enddefine;

If you are not familiar with the idea of a formal grammar, you may find
it helpful to work through TEACH GRAMMAR before reading the rest of this
file. Practice producing sentence generators as shown there, before you
try to produce your own story generator as illustrated below.

-- Generating Haikus --------------------------------------------------

A haiku (Japanese literary form) is a three line poem of a highly
constrained form. Examples (from Boden, 1990 page 158) are

    All green in the leaves
    I smell dark pools in the trees
    Crash moon has fled

    Eons deep in the ice
    I paint all time in a whorl
    Bang the sludge has cracked

These are of the form

    All [1] in the [2]
    I [3] [4] [5] in the [6]
    [7] the [8] has [9]

We can easily specify a grammar to generate haikus with a slightly more
general form as follows, inserting the word newline after part1 and
after part2, to produce more readable output.


    vars haiku_gram =
        [
            ;;; A "sentence" is a haiku, where
            ;;; a haiku has three parts separated by newlines
            [haiku [part1 ^newline part2 ^newline part3]]

            ;;; We now define the permitted forms for each part
            ;;; part2 will use different verbs (after the word "I")
            ;;; from the verbs in part3. The two sorts of verbs, and
            ;;; the adjectives and two sorts of nouns are listed in
            ;;; the lexicon, below.

            [ part1 [start_word adj in np]]

            [ part2 [I verb1 adj noun in np]]

            ;;; part3 has two forms, one with a singular noun phrase
            ;;; followed by "has" and the other with a plural noun
            ;;; phrase followed by "have"

            [ part3 [exclaim sing_np has verb2]
                    [exclaim plural_np have verb2]]

            ;;; different types of noun phrases, singular and plural
            ;;; use different kinds of nouns and different kinds of
            ;;; determiners
            [np [sing_np][plural_np]]

            [sing_np [sing_det sing_noun]]

            [plural_np [plural_det plural_noun]]

            ;;; Nouns can be singular or plural, defined in the
            ;;; lexicon
            [noun [sing_noun] [plural_noun]]
        ];

;;; This might be an example lexicon, for use with the above grammar

    vars haiku_lex =
        [
            ;;; adjectives (you could easily add more)
            [adj abrupt acrid bitter black crass crazy cyan dark deep
                flaccid flossy ghostly goulish greenish magenta plangent
                poetic purest rancid rapt smelly starry tinkling tiny
                vicious welling white zany zealous
            ]
            ;;; Words to start part 1
            [start_word Ages All Eons Many Most So What How Days But]

            ;;; Singular and plural determiners
            [sing_det the some one every each my her your our their
                this]

            [plural_det the some all most many my your our his their
                these those two three four]

            ;;; Singular and plural nouns. Add more
            [sing_noun acorn age anchor angel anguish autumn boat bridge
                canopy cosmos darkness dawn daylight
                death dew foal forest grass greening hatching
                laughter leaf life moon night ocean power
                soul spring sunset tiger winter zoo]
            [plural_noun
                ancestors autumns
                births clouds collisions creatures dancers devils
                echoes evenings forms galaxies ghosts
                heavens hosts jokes lawns paths poets
                raindrops rivers seas spirits
                storms summers tangles tempests torments
                trees verses vessels waves watchers winters
            ]
            [verb1 abandon burn compose dangle detach
                engage enlarge expect fetch fleece frame
                grasp graze greet hug mourn
                praise press sing sip slice smell
                spy stretch stroke
                taste tear touch twist
                urge warn watch wear wipe
            ]

            [verb2 aged arisen bloomed blinked burst
                chimed come cracked crazed drowned
                drooped dropped
                eaten ended eeked
                faded fallen failed fetched floundered frozen
                gone gripped groomed gushed held hated
                left loomed lost
                missed murdered netted notched nursed
                oiled opened oozed
                raided receded riddled ripped rode
                sang slept skipped smouldered swirled swarmed swung
                switched thawed unzipped
            ]
            ;;; words for an exclamation
            [exclaim
                Aha Alas Aye Bang Crash Forever Ha Hey Ho Joy Nay
                No Ouch Oh See So Pfft Ugh Woe Yea Yes]
        ];

;;; Generate some Haikus

    uses grammar
    uses generate_category

    ;;; set the maximum recursion level for the generator
    20 -> maxlevel;

    ;;; Generate 10 haikus, using the above grammar and lexicon
    repeat 10 times
        generate_category("haiku", haiku_gram, haiku_lex) ==>
    endrepeat;

-- Example haikus generated -------------------------------------------

Here are some Haikus generated by the above:

** [Days bitter in some acorn
         I abandon welling ocean in four devils
         Crash her spring has eeked]
** [How poetic in every winter
        I touch greenish ancestors in the seas
        Ugh this life has bloomed]
** [Many acrid in my echoes
         I spy poetic evenings in the heavens
         Yea her greening has missed]
** [Most crazy in each power
         I expect starry ocean in one winter
         Pfft most heavens have cracked]
** [What dark in the echoes
         I touch poetic raindrops in every greening
         Yea the leaf has groomed]
** [But white in your raindrops
        I compose greenish dew in the spirits
        Joy three creatures have chimed]
** [But black in my tiger
        I greet flossy boat in your tangles
        Aha the darkness has nursed]
** [Days welling in these poets
         I mourn cyan heavens in two winters
         Alas one foal has come]
** [Ages tiny in our power
         I dangle dark acorn in three verses
         Hey some rivers have bloomed]
** [Eons zealous in most forms
         I abandon tinkling forest in two winters
         Joy many rivers have riddled]


** [What zealous in their storms
         I expect goulish paths in most vessels
         Pfft each daylight has blinked]
** [Days goulish in his summers
         I burn rancid paths in some heavens
         Hey our spring has unzipped]
** [Ages deep in each darkness
         I urge zealous lawns in some dawn
         Forever your darkness has hated]
** [But tinkling in those clouds
        I praise crazy storms in four forms
        Crash our trees have notched]
** [Ages plangent in his collisions
         I watch starry tangles in these heavens
         Joy every anchor has cracked]
** [So vicious in one greening
       I stretch greenish autumns in their forms
       Joy his tangles have aged]
** [Most ghostly in my heavens
         I engage tinkling clouds in your cosmos
         So our angel has sang]
** [What flossy in two rivers
         I engage poetic night in their boat
         Ha her anchor has swung]
** [But deep in the storms
        I burn crazy zoo in these paths
        Alas their jokes have oiled]
** [Days tiny in your tiger
         I frame bitter hosts in her daylight
         No these paths have burst]


-- Exercise: improve/generalise the haikus ----------------------------

1. All those haikus have "I" at the beginning of part2, because the rule
for part1 gives no choice. Try devising an extension of the grammar and
lexicon to allow "I", "We", "You", "They", and other words of an
appropriate grammatical type.

2. Can you introduce a change to make part2 produce slightly more
grammatical output by forcing the first noun to be plural. Does that
improve the haikus?

3. Try introducing more subdivisions of types of nouns, determiners,
adjectives and verbs and matching them up so that "inappropriate"
combinations are avoided. E.g. should "our night has switched" be
allowed? If not, how can you prevent it being generated? What
about adding "a" as determiner and preventing "a acorn".

-- The output of summarise --------------------------------------------

As a digression, I tried running the pop-11 "summariser" program
described in HELP SUMMARISE, on the haikus generated above by doing

    uses summarise

Then in a file containing the haikus, I did this to produce a 150 word
summary:

    ENTER summarise 150

Two such "summaries" produced were as follows:

SUMMARY

How rancid in every night I press rancid echoes in your
hatching I slice deep winters in your evenings See this age
has blinked.

Ages plangent in every night I grasp acrid verses in some
angel I frame flaccid ghosts in four raindrops I warn
goulish grass in their zoo I engage goulish anguish in many
summers Oh some galaxies have skipped. All dark in her
cosmos has blinked. Many abrupt in four vessels Joy the
torments have sang. But black in some canopy No your
tempests have smouldered. Many cyan in one soul Oh our
ocean has chimed. Eons black in some hosts I tear flossy
soul in one soul Oh our ocean has groomed. Ages smelly in
some hatching Oh all seas I touch tiny night in her
hatching See most jokes have netted.

How bitter in two watchers I engage goulish anguish in many
poets Ugh each age has thawed.
GOOD BYE!


SUMMARY

How rancid in every night I press starry night in every life
See your jokes have failed. But acrid in some autumns I spy
purest raindrops in my boat I sing crazy bridge in three
galaxies I watch zealous leaf in your evenings See this age
has blinked. Many abrupt in four echoes Bang your echoes
have arisen. So smelly in our summers I smell poetic zoo in
some hosts I tear flossy soul in one zoo I taste zany lawns
in their echoes Ho each bridge has slept. Ages rancid in
your evenings See this age has thawed.

Many rapt in my angel I frame flaccid ghosts in four
vessels Joy the torments have murdered.

But zealous in four hosts Ha those poets have dropped.

Eons welling in the death I touch ghostly anguish in many
poets Ugh all echoes have arisen. So smelly in every moon I
fetch bitter echoes in your anguish Yes one daylight has
slept.
GOOD BYE!


NOTE:
Putting full stops (periods) in the grammar for haikus, or adding them
to the output, would have produced slightly more readable "summaries".
But perhaps they are more fun without the stops.

-- Designing a simple story generator ---------------------------------

We return now to story-generating grammars, extending the techniques
described above.

We start from the assumption that a story has three parts, a beginning,
a middle and an end. We develop simple grammars for those parts
separately, and then put them together later.

-- -- Testing partial grammars separately

E.g. if we wish to develop a grammar for story beginnings we can define
a grammar of the following form

    vars begin_grammar =
        [
            [story_begin .....]
            [ ....]
            .....
        ];

Then then we can use the generate_category procedure to test that
grammar with a suitable lexicon.

Later if we have grammars for the middle and the end, which we have
also tested separately, using the above method, we can do the following
to create the complete grammar for stories:

    [ [story [story_begin story_middle story_end]]
        ^^begin_grammar
        ^^middle_grammar
        ^^end_grammar]
    ]

Then we can use generate_category to produce whole stories.

-- -- A story lexicon: story_lex

We provide a first draft story lexicon now, for use with a variety of
grammars for parts of stories, presented below. Some of the categories
given here may seem arbitrary, but their use is explained later.

vars story_lex =

    [
        [period .]

        ;;; adjectives and nouns for referring to villains
        [villain_adj
            brazen brutal heartless horrid mindless mutant rich stupid
            thuggish ugly wily wicked]
        [villain_noun
            burglar conman crook deceiver driver landlord
            murderer mugger ogre robber thief thug villain ]

        ;;; adjectives and nouns for referring to heroes
        [hero_adj
            assiduous attentive bold brave clever eager generous
            helpful kind observant selfless worthy]
        [hero_noun
            detective doctor fighter man knight policeman policewoman
            warrior woman ]

        ;;; adjectives and nouns for referring to victims
        [victim_adj
            anxious harmless helpless innocent lovely mild nervous
            polite poor wistful young ]
        [victim_noun
            beggar boy child man nun pedestrian princess professor
            stranger student woman ]

        ;;; more combinations for happy or regretful people
        [happy_noun
            clown general guardian hero heroine knight
            lady princess prince watcher]
        [happy_adj
            grateful happy joyous merry proud relieved smiling warm]

        [regret_noun
            hero heroine victim lad lass person]
        [regret_adj
            unhappy woeful sad distraught dismayed dejected downtrodden
            undone wretched]

        ;;; now verbs and adverbs for different sorts of individuals
        [villain_verb
            murdered cheated robbed betrayed threatened mugged]
        [hero_verb
            caught found detected slew unmasked challenged defeated
            overcame reported]
        [happy_verb
            celebrated cheered jumped ran romped
            skipped smiled strolled sneered]
        [happy_adv
            happily blithely joyfully excitedly triumphantly gleefully]
        [regret_verb
            cried died moped mourned prayed sat slumped stumbled walked
            wept]
        [regret_adv
            gloomily glumly sadly regretfully morosely mournfully]

        ;;; some prepositions, for complex noun phrases
        [prep over under beside near at in on within above]

        ;;; determiners for use with singular nouns
        [det the each every some one a his]

        ;;; nouns (singular only)
        [noun car bracelet chair mountain house knife river bridge car
        caravan road yard]

        ;;; adjectives
        [adj big bold small narrow wide brown green blue deserted
            ancient ugly attractive famous]

        ;;; words to start expressions of regret
        [regret alas woe how_sad NO oh_dear ouch]

        ;;; words to start expressions of joy or rejoicing
        [rejoice hooray great cool wonderful cheers yup OK]

    ];

This lexicon can be elaborated later, if necessary.


-- -- A grammar for story beginnings

We can now build on the above lexicon to create our story grammar. This
section introduces a simple sub-grammar for story beginnings.

vars begin_grammar =
    [
        ;;; The first part: a villain does something villainous
        [story_begin [start_villain_np villain_vp]]

        ;;; there are several kinds of noun phrases
        [start_villain_np
            [a villain_adj villain_noun]
            [a villain_noun]
            [start_villain_np prep_phrase]]
        [victim_np
            [det victim_adj victim_noun]
            [det victim_noun]
            [victim_np prep_phrase]]

        ;;; A verb phrase for villainous doings
        [villain_vp [villain_verb victim_np]]
        ;;; other things needed.
        [prep_phrase [prep noun_phrase]]
        [noun_phrase [det noun] [det adj noun]]
    ];

-- -- Testing story beginnings

;;; try this a few times

repeat 10 times
    generate_category("story_begin", begin_grammar, story_lex)==>
endrepeat;

This could produce sentences like:

** [a stupid landlord betrayed each beggar]
** [a mutant villain robbed the child]
** [a ogre within a road cheated a professor]
** [a brazen burglar murdered his innocent professor]
** [a robber cheated one harmless nun]
** [a murderer mugged a polite beggar]
** [a ogre murdered some anxious beggar]
** [a murderer near the bridge betrayed his nervous pedestrian]
** [a thuggish thug threatened some helpless woman]
** [a driver in a bracelet threatened the woman]

-- -- Exercise: better beginnings?

Try modifying the grammar and the lexicon to give improved opening
sentences for stories. Test your revised grammar using the
generate_category procedure.

You may find it necessary to add more sub-categories for the lexicon and
for the grammar.

-- -- Story middles

Here is a first draft grammar for the middle sentence of a three
sentence story:

vars middle_grammar =
    [
        ;;; the second part: a hero does something heroic
        [story_middle [hero_np hero_vp]]

        ;;; there are several kinds of noun phrases
        [middle_villain_np
            [the villain_adj villain_noun]
            [the villain_noun]
            [middle_villain_np prep_phrase]]
        [hero_np
            [det hero_adj hero_noun]
            [det hero_noun]
            [hero_np prep_phrase]]

        ;;; Verb phrases for hero actions
        [hero_vp [hero_verb middle_villain_np]]

        ;;; general utilities
        [prep_phrase [prep noun_phrase]]
        [noun_phrase [det noun] [det adj noun]]
    ];

-- -- Testing story middles

;;; try this a few times

repeat 10 times
    generate_category("story_middle", middle_grammar, story_lex)==>
endrepeat;

This could produce sentences like:

** [some man found the villain]
** [some assiduous woman beside some deserted house slew the mindless
         conman]
** [some woman found the driver]
** [the doctor in some brown yard challenged the thuggish driver]
** [his policewoman slew the thug]
** [some attentive detective within one green bridge overcame the
         mindless crook]
** [some worthy detective unmasked the burglar]
** [his helpful woman unmasked the mugger]
** [the policewoman challenged the ugly mugger]
** [some generous policewoman defeated the brazen thief]

-- -- Exercise: better middles?

1. Try modifying the grammar and the lexicon to give improved middle
sentences for stories composed of three sentences.

2. Try expanding the grammar for middle portions by allowing the middle
to have more than one sentence. To do this you may find it easiest to
introduce a new sub-category middle_sentence and then define
story_middle to use that more than once.

You may find it necessary to add more sub-categories for the lexicon and
for the grammar.


-- -- story ends

Here is a simple grammar which allows endings to consist of either
one word exclamations ("Woe", "Hooray") or a sentence, which may be
either a happy sentence or a sad sentence.

vars end_grammar =
    [
        ;;; The third part of the story
        ;;; There are two kinds of endings, happy and sad,
        ;;; each of two forms.
        [story_end [happy_end] [sad_end]]

        ;;; Repeat a form to get a higher probability of choosing it
        [happy_end [rejoice] [happy_np happy_vp] [happy_np happy_vp]]

        [sad_end [regret] [regret_np regret_vp] [regret_np regret_vp]]

        ;;; appropriate noun phrases
        [happy_np [det happy_noun] [det happy_adj happy_noun]]
        [regret_np [det regret_noun] [det regret_adj regret_noun]]

        ;;; Verb phrases for endings
        [happy_vp [happy_verb happy_adv] [happy_adv happy_verb]]
        [regret_vp [regret_verb regret_adv] [regret_adv regret_verb]]
    ];

-- -- Testing story endings

;;; try this a few times

repeat 10 times
    generate_category("story_end", end_grammar, story_lex)==>
endrepeat;

This could produce output like:

** [the warm clown cheered blithely]
** [his victim mournfully stumbled]
** [his hero smiled triumphantly]
** [the lass gloomily mourned]
** [one unhappy heroine wept regretfully]
** [the dejected heroine stumbled mournfully]
** [the heroine walked glumly]
** [every lad prayed sadly]
** [each princess joyfully ran]
** [oh_dear]


-- -- Exercise: better endings?

Try modifying the grammar and the lexicon to give improved endings for
stories.

-- -- Combining the parts into a single story grammar

vars story_grammar =
    [
        ;;; The top level category is story
        [story

            ;;; a story may have three parts, separated by periods
            [story_begin period story_middle period story_end period]

            ;;; or maybe two middle parts
            [story_begin period story_middle period story_middle period
                story_end period]]

        ;;; Add the previous grammars, to expand the above

        ^^begin_grammar
        ^^middle_grammar
        ^^end_grammar
    ];

NOTE: if you alter any of the sub-grammars you will have to rebuild
the story_grammar by recompiling the above command.

Check what is in story_grammar, by printing it out:

    story_grammar ==>

This has some repetitions, because of the way it was constructed, but
that will not affect the demonstrations. (If you are an experienced
Pop-11 programmer you should be able to define a prune_grammar procedure
to remove duplicate grammar rules.)


-- Test the full story generator --------------------------------------

;;; Make sure the libraries are compiled

uses grammar
uses generate_category

;;; Set the maximum level of recursion for these stories.
20 -> maxlevel;
repeat 10 times
    generate_category("story", story_grammar, story_lex)==>
endrepeat;

This could produce stories like the following (don't get too excited):

** [a horrid ogre above every river murdered one woman near every chair
      on one car . every kind policewoman under each yard in one chair
      in one car detected the murderer . some warrior detected the wicked
      murderer . NO .]
** [a murderer over each green house cheated the child . some fighter
      caught the ogre . every dismayed hero morosely died .]
** [a conman at a big yard robbed some nun above his chair over some
      bridge above a yard . one observant warrior unmasked the crook at
      the bracelet . some kind policewoman over some blue bracelet beside
      a blue house unmasked the ugly murderer . how_sad .]
** [a rich deceiver robbed the lovely beggar above every house over a
      yard . some attentive detective slew the ogre . the assiduous
      doctor beside a brown bracelet in every yard slew the thug above
      the brown river . every prince ran happily .]
** [a villain robbed a lovely man . each warrior defeated the burglar
      within a caravan near one bridge . his bold woman within each big
      road slew the murderer . how_sad .]
** [a ugly deceiver beside his big bracelet in some bridge under each
      bold yard above his bracelet mugged a nervous boy over some
      deserted mountain . the policewoman near every bridge detected the
      thief . each relieved lady blithely skipped .]
** [a deceiver betrayed his wistful man . the doctor near his ugly house
      unmasked the deceiver above a bracelet . OK .]
** [a ogre over the caravan within the chair betrayed a student in every
      famous bracelet beside some famous yard . some knight detected the
      mugger . some lad moped regretfully .]
** [a brutal mugger murdered the beggar . his detective caught the ugly
      thug . each brave detective above some small caravan defeated the
      mugger . one person gloomily slumped .]
** [a heartless burglar at the river at one mountain beside some ugly
      knife cheated each wistful child . each clever policeman challenged
      the thug . the attentive warrior overcame the mindless ogre . some
      hero sat gloomily .]

You might like to modify the grammar to produce a newline after each
period, to produce more readable output, as was done with the haiku
grammar.


-- Accommodating alternative story formats ----------------------------

More complex and varied story forms can be based on the same general
idea, allowing more varieties of top level story structures instead of
making them all take the same form

So instead of the above rule for expanding "story" into story parts we
can provide alternative expansions

    [story
        [comedy_start comedy_middle comedy_end]
        [tragedy_start tragedy_middle tragedy_end]
        [whodunnit_start whodunnit_middle whodunnit_end]
    ]

For the different sorts of start, middle and end sections there could be
various formats defined separately. This could generate a very rich
collection of story types, though, as you've seen, the techniques shown
here can produce ungrammatical and absurd stories.

Overcoming these limitations and producing convincing stories, raises
many difficulties, requiring the use of techniques which take proper
account of the grammar of English (or whatever language you use), the
meanings of words, phrases and sentences, knowledge about human beings
and the environments in which they act, the ability to plan and solve
problems. On top of that it would be necessary to add knowledge of the
aesthetic qualities of stories. All this goes far beyond the scope of
this teach file.

-- Exercise: more integrated stories ----------------------------------

Is it possible, using a tool like the generate_category procedure, to
create stories which have more coherence, e.g. where persons introduced
at the beginning play a role later on?

Or would some entirely different type of story generator be better?

See if you can design one and implement it in Pop-11.


-- Automatically analysing stories ------------------------------------

LIB GRAMMAR provides a mechanism for creating procedures for parsing
sentences which conform to a grammar and lexicon of the sorts used by
generate_category. To create those procedures, apply the procedure
setup (defined in LIB GRAMMAR) to the grammar and the lexicon.
It then creates analyser procedures for all the categories defined
in the grammar.

We can demonstrate this as follows, assuming that story_grammar and
story_lex have been defined as above.

    ;;; Make sure the library is compiled
    uses grammar

    ;;; Create the analysers
    setup(story_grammar, story_lex);

That will create procedures corresponding to the categories in the
grammar, e.g.

    story, story_begin, story_middle, story_end.

For instance we can see if this is an acceptable story_middle:
    [some warrior found the brutal crook within one chair]

We give it to the procedure story_middle, which will produce a parse
tree, if it can analyse it, otherwise false:

    story_middle([some warrior found the brutal crook within one chair]) ==>
    ** [story_middle
        [hero_np [det some] [hero_noun warrior]]
        [hero_vp [hero_verb found]
                 [middle_villain_np
                  [middle_villain_np the [villain_adj brutal] [villain_noun crook]]
                  [prep_phrase [prep within] [noun_phrase [det one] [noun chair]]]]]]

We can do the same for a complete three sentence story, like this:

    [a thug murdered one innocent stranger . some warrior found the brutal
      crook within the car . the woeful heroine sadly wept .]

We give that to the story procedure to analyse:

    story(
        [a thug murdered one innocent stranger .
            some warrior found the brutal crook within the car .
            the woeful heroine sadly wept.]) ==>


And that produces the following parse tree for the story:

** [story [story_begin
           [start_villain_np a [villain_noun thug]]
           [villain_vp
            [villain_verb murdered]
            [victim_np [det one] [victim_adj innocent] [victim_noun stranger]]]]
          [period .]
          [story_middle
           [hero_np [det some] [hero_noun warrior]]
           [hero_vp [hero_verb found]
                    [middle_villain_np
                     [middle_villain_np
                      the
                      [villain_adj brutal]
                      [villain_noun crook]]
                     [prep_phrase [prep within] [noun_phrase [det the] [noun car]]]]]]
          [period .]
          [story_end [sad_end [regret_np [det the]
                                         [regret_adj woeful]
                                         [regret_noun heroine]]
                              [regret_vp [regret_adv sadly] [regret_verb wept]]]]
          [period .]]


Try doing that for other stories generated by  story_grammar story_lex.

You can also try using showtree to display the parse tree, as
demonstrated in TEACH GRAMMAR

    uses showtree;

    showtree(story( [ ......] ));

Warning: the parse tree will be pretty big, and you'll have to do a lot
of scrolling left and right in the editor, and perhaps up and down to
view it. The arrow keys and the WORDLEFT WORDRIGHT keys should suffice.

-- Exercise: towards a story understander -----------------------------

A possible further exercise would be to have a program give an analysis
of the story based on the parse tree, e.g. in the form of a description
of the type of plot, etc. It could build up a database recording the
characters and events described in the story. The database could then be
used by a program which answers questions about what happened in the
story.


-- Reading ------------------------------------------------------------

For an introduction to some of the issues see

Margaret A. Boden,
    Artificial Intelligence and Natural Man,
    Harvester Press, 1978, Hassocks, Sussex,
    Second edition 1986. MIT Press,
    (especially chapter 11)


Margaret A Boden,
    The Creative Mind: Myths and Mechanisms,
    London, Weidenfeld & Nicolson,
    1990,
    (especially chapter 7)

Other references needed....

--- $poplocal/local/teach/storygrammar
--- Copyright University of Birmingham 2000. All rights reserved. ------
