A Pretty Problem

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.