[alicebot-archcomm] [discuss] sets and lists in AIML

Dr. Richard S. Wallace alicebot-archcomm@list.alicebot.org
Sat, 16 Mar 2002 06:05:35 -0800


As a simple starting point to begin the discussion of sets and lists in
AIML, consider the problem of random selection without replacement.  One
common example is a shuffled deck of cards.  If you pick one card, such as
the Four of Clubs, and remove it from the deck, then the same card cannot be
selected again.  The next card picked must be one of the 51 remaining cards
less the Four of Clubs.

We can't do random selection without replacemente easily with existing AIML
tags. If you created a category with random list of 52 cards in the
template, and activated the pattern over and over again, the cards would
sometimes repeat themselves:

C: Pick a card.
R: Three of clubs.
C: Pick another card.
R: Three of clubs.

Here I have sketched a scenario whereby we can do random selection without
replacement, by adding one simple tag, <less>, to AIML.

The first category sets up the card trick by creating the set or list of
cards.  <category> tags omitted for brevity.

<pattern>CARD TRICK</pattern>
<template>
<think>
<set name="cards"/>
<li>Ace of Hearts</li>
<li>Ace of Clubs</li>
....
<li>King of Diamonds</li>
<li>King of Spades</li>
</set>
</think>
Okay.
</template>

One subtle semantic question I've never noticed before, is what happens when
you do a <set name="X">L</set> where L is a list of items enclosed in
<li>...</li>'s.  Should the <set> evaluate the expression L and perhaps
replace <'s with &lt;'s, or shoud it preserve the <li>...</li> so we can
write, for example, <random><get name="X"/></random> to apply <random> to
the whole list X.  If we mean the latter, then the category:

<pattern>PICK A CARD</pattern>
<template>
<set name="card">
<random><get name="cards"/></random>
</set>
<think>
<set name="cards"><less set="cards" item="card"/></set>
</think>
</template>

implements random selection without replacement.  The first step randomly
selects one of the cards and assigns it to the predicate "card".  The second
step revises the set or list of cards by removing one item.  In Algol-Style,
these two steps would be written:

card := random(cards);
cards := cards - {card};

The second step requires something like the prospective tag <less>.

<less> has two argument attributes, "set" and "item".  Both are AIML
predicate names, but the first one is a <li>...</li> delimited list, and the
second is a single item.

If the item is not in the list, <less> does nothing.

If the item is in the list, <less> returns a new list, exactly the same as
the original, but with (the first occurance of) the item removed from the
list.

If the list is empty, <less> returns the default predicate value for the
attribute "set".

The conversation may now proceed:

Client: Card trick.
Robot: Okay
Client: Pick a card
Robot: Two of Hearts
Client: Pick a card
Robot: Seven of Spades
Client: Pick a card
Robot: Jack of Hearts
...

And, if the default value of the predicate "cards" is "No more cards." then
eventually after 52 "Pick a card" commands, the robot will say:

C: Pick a card
R: No more cards.

The <less> tag can be used to modify the <li>..</li> separated list by
removing one item.


Okay friends, launch tomatoes.  Afterward, I will have a nice salad.

Dr. Rich