I just discovered that I solved the same problem twice, once with Sappho and once with Java. The problem is this: we wish to calculate the best combination of two estimates of a pValue of an aura count. Thus, we have four values to consider:
p1: the first perceived value of the aura count
u1: the uncertainty of p1
p2: the second perceived value of the aura count
u2: the uncertainty of p2
I solved this problem in yesterday’s essay, concluding that the net result should be as follows:
P = p1 + (abs(p2 - p1) / (u2 + u1)) * u1
U = (u1 + u2) / 2
But it turns out that I had worked out a completely different solution back in August; that solution is described here. After studying it for ten minutes, I still don’t understand my own calculation. That damn blend function is tricky to understand. I think it’s a good general-purpose non-rigorous way of combining numbers, but in this case it just doesn’t do the job convincingly. Here’s a partial algebraic representation of the calculation:
P = Blend( p1, p2, (u1 + ((trust + u2)/2))/2)
This is considerably different from the above calculation.
BTW, the formula above replaces the gaussian curve with a simple tepee consisting of two straight lines intersecting at the peak. Yeah, that’s a really rough approximation, but I see no need to use the formal method. After all, greater error is introduced by the integer quantifiers.
BTW^2: This provides a good example of my claim that you don’t need to use high-powered math to do good work with algorithm design. This is simple high school algebra, nowhere near as powerful as what you get in junior and senior years in high school.
Where we stand
So, I’ve got all the Java code I need; I have added the operators to the OperatorDictionary and now all is working well. Onward…
New headaches
Well, what do you expect? Headaches are the ever-present aspect of programming. So today I have been battling some programming problems. First, there was a bug in the basic Storytron code. If the user selects a word that leads into a dead end, the system gets stuck. It is supposed to provide the user with the option to back up and enter a different word, but this wasn’t happening. With much trepidation I dug through the code and eventually found some changes that appear to have fixed the problem. Nevertheless, I am not confident that my fix is reliable; it looks for all the world like an ugly kluge pasted on top of some elegant code that I don’t understand. But it’s working for now.
My current headache arises from a bug in engine operation that must be my fault. It turns out that TimeToExecute is not being properly applied. Here’s the deal: there are two delay times associated with the execution of each verb: TimeToPrepare and TimeTo Execute. They both default to 1, and in the vast majority of cases, this works just fine. The intention is that TimeToPrepare delays execution of the verb by that amount of time, while TimeToExecute keeps the Subject occupied for its duration. For example, suppose we have a verb with TimeToPrepare = 10 and TimeToExecute = 30. The Subject decides to execute the verb at time = 100. Then the verb is not executed until time = 110, during which time Subject is occupied with preparation and is unable to participate in any other action. The verb executes at time = 110, and the Subject continues to be occupied until time = 140. That is what is supposed to happen.
But it doesn’t work that way. The actual sequence is as follows:
First verb executes, setting OccupiedUntil to current time plus TimeToExecute.
Subject reacts to first verb and selects a Plan.
Creating the Plan sets OccupiedUntil to current time plus TimeToPrepare (overriding previous OccupiedUntil)
I could fix this problem by deferring reaction until AFTER TimeToExecute has elapsed. The concept behind TimeToExecute is that the verb is a continuing action that extends over a time period. For example, the verb ‘meditate’ is a continuing action extending over 30 minutes. Should people react to such a verb until the action is completed, or when it begins? The current arrangement puts the reaction when it begins, which causes our problem. It would seem that the ideal is that reactions don’t take place until after completion of the action — but how does that differ from TimeToPrepare?
Let’s consider this using a clearer example. Suppose I have a verb ‘poison’, by which Subject can put poison into DirObject’s glass. I could set up a TimeToPrepare of 10 because it takes 10 minutes to make the poison, and then TimeToExecute as 30, because it takes 30 minutes to kill the victim. But a better way to see it is as follows:
prepare poison; consumes 10 minutes
administer poison: consumes 1 minute
poison kills: consumes 30 minutes
This means that we have only ONE time delay associated with each verb, and that time delay is the amount of time that passes BEFORE the verb executes. In other words, all times are TimesToPrepare, and I should eliminate TimeToExecute. Thus, if the Subject plans ‘prepare poison’, that verb is not executed for 10 minutes. After ten minutes, the verb executes and the Subject reacts to that verb by planning ‘administer poison’, which consumes only one minute. After one minute, the verb ‘administer poison’ executes and the verb ‘poison kills’ begins preparation. It executes 30 minutes later, at which time DirObject dies.
It appears that I have more programming to do.