I ran into a nasty little problem implementing the scripts for the verb ‘X said Y Z of you’. In this verb, the Subject tells DirObject that Actor4 related feelings about aura 5ActorTrait of magnitude 6Quantifier.
The particular problem I faced required me to prevent a Subject from re-telling DirObject something he’s already told DirObject. In other words, I need to tell Subject “Don’t repeat yourself.” That should be easy to do: just scan the HistoryBook for Events in which Subject said the same thing to DirObject. But there’s a nasty little gotcha: there are three versions of the statement, one for each of the auras in 5ActorTrait. This would not be a problem in a general-purpose programming language. It is a problem in Sappho, but for rather messy reasons.
Converging representations
I’ll show the problem by showing how I would represent the algorithm in various forms. The first form is that above: “Don’t repeat yourself.” Let’s make it a bit more explicit:
If you have in the past used the verb ‘X said Y Z of you’ to the person, then do not say the same thing again.
Even better:
Search the HistoryBook for any events in which you were the DirObject, the current person was 4Actor, and the verb was ‘relate feelings’. If you find one, then search the HistoryBook for any events in which you were the Subject, the verb was ‘X said Y Z of you’, the current person was the DirObject, and the auras and magnitudes in both events match. If you find such an event, skip the first event (with the verb ‘relate feelings’) and move to the next event. If you do not find such an event, then make this event the topic of your reply.
That sounds pretty clear, doesn’t it? Here’s how I’d code it up in Java:
boolean foundATopic = false;
int i = 0;
while ( (i < HistoryBook.size()) & ! foundATopic) {
if ( (HistoryBook[i].verb == ‘relate feelings’) &
(HistoryBook[i].dirobject == reactingActor) &
(HistoryBook[i].4Actor == subject) ) {
int j = i+1;
boolean alreadyTalkedAboutIt = false;
while ( (j < HistoryBook.size()) & ! alreadyTalkedAboutIt) {
if ( (HistoryBook[j].subject == reactingActor) &
(HistoryBook[j].verb == ‘X said Y Z of you') &
(HistoryBook[j].dirObject == subject) &
(HistoryBook[j].4Actor == HistoryBook[i].subject) &
(HistoryBook[j].5ActorTrait == HistoryBook[i].5ActorTrait) &
(HistoryBook[j].6Quantifier == HistoryBook[i].6Quantifier) ) {
alreadyTalkedAboutIt = true;
}
++j;
} // end of j-loop
++i;
if ( !alreadyTalkedAboutIt)
foundATopic = true;
}
When this routine exits, foundATopic tells us if we have a topic, and the value i - 1 is the array index in HistoryBook that tells us where to find the topic. So, all I have to do is translate this Java code into Sappho.
Hitting a brick wall
Unfortunately, Sappho can’t handle this, because it involves all sorts of nesting. Loops in Sappho are handled with the PickBest operators, and two of them would be nested in an impossible structure. The script, at first glance, would look something like this:
PickBestEvent
AND4
AreSameActor
ReactingActor
PastDirObject
CandidateEvent
AreSameActor
ThisSubject
Past4Actor
CandidateEvent
AreSameVerb
PastVerb
CandidateEvent
relate feelings
NOT
EventHappened
AND4
AreSameActor
PastSubject
CandidateEvent
reactingActor
AreSameVerb
PastVerb
CandidateEvent
X said Y Z of you
AreSameActor
PastDirObject
CandidateEvent
thisSubject
AreSameActor
Past4Actor
CandidateEvent
???????
The problem shows up in this last line. If you’ve been tracing the correspondence between the Java code and the Sappho code, you’ll know that the question marks must be replaced with the Sappho equivalent of HistoryBook[i].subject. But that is the subject of the CandidateEvent in the OUTER loop, not the CandidateEvent in the INNER loop. Those are two separate events, in exactly the same way that HistoryBook[i] is not the same as HistoryBook[j].
Wait a minute!
I just had an inspiration – this is why I write these essays. I could use a custom operator to pass HistoryBook[i], and perform the EventHappened loop inside the custom operator. The original script would now look like this:
PickBestEvent
AND4
AreSameActor
ReactingActor
PastDirObject
CandidateEvent
AreSameActor
ThisSubject
Past4Actor
CandidateEvent
AreSameVerb
PastVerb
CandidateEvent
relate feelings
NotAlreadyReported
CandidateEvent
Number2BNumber
PastTime
CandidateEvent
and the custom operator would look like this:
NOT
EventHappened
AND4
AreSameActor
PastSubject
CandidateEvent
reactingActor
AreSameVerb
PastVerb
CandidateEvent
X said Y Z of you
AreSameActor
PastDirObject
CandidateEvent
thisSubject
AND4
AreSameActor
Past4Actor
CandidateEvent
PastSubject
PassedEvent
AreSameActor
Past4Actor
CandidateEvent
PastSubject
PassedEvent
AreSameActorTrait
Past5ActorTrait
CandidateEvent
Past5ActorTrait
PassedEvent
AreSameQuantifier
Past6Quantifier
CandidateEvent
Past6Quantifier
PassedEvent
Usually, I end up cursing my own stupidity, but this time I suppose I can pat myself on the back. And Sappho is not quite as clumsy as I thought.