Poison

New variables:

gafPoisonedConsequence[MAXCONSEQUENCES]

mfPoisonedStack

miCurrentConsequence

mafPoisonedSubstitution[16]

gTokenStringType

 

Chris will have ReactToNews set gTokenStringType before each call to the interpreter. If the token string sent to the interpreter is an activation equation, then gTokenStringType will be set to a value of Activation. If the token string sent to the interpreter is a consequence calculation, then gTokenStringType will be set to a value of Consequence. But what is the utility of this now?

 

Every function that takes one or more arguements from the stack will check every input arguement for range. If the arguement falls inside the allowed range of values for that arguement, nothing happens. If the arguement falls outside the allowed range of values, then the function sets the value of mfPoisonedStack to true. Note that the function must never set the value of mfPoisonedStack to false.

 

Every function that pops something off of the stack and into a variable will examine the value of mfPoisonedStack. If the value of mfPoisonedStack is false, the execution proceeds normally; if the value of mfPoisonedStack is true, then the function does not store anything into the variable, but it does decrement the value of mStackTop.

 

Every function that pushes something onto the stack will examine the value of mfPoisonedStack; if the value is false, execution proceeds normally; if the value is true, then the function pushes a zero onto the stack.

 

Every function that pops a value into a substitution variable will set the value of mafPoisonedSubstitute[that substitution variable] equal to the value of mfPoisonedStack.

 

Every function that pops a value off of the stack will examine the value of mStackTop; if that value is zero after the pop, then the function will set the value of mfPoisonedStack to false.

 

Every function that pushes a substitution variable onto the stack will logically OR the current value of mfPoisonedStack with the value of mafPoisonedSubstitute[that substitution variable], storing the result into mfPoisonedStack.

 

The function AdjustDominance will include the following two statements:

 

miCurrentConsequence = 0;

mfPoisonedStack = false;

 

The function pop_weight will include these three statements:

 

gafPoisonedConsequence[miCurrentConsequence] = mfPoisonedStack;

++miCurrentConsequence;

mfPoisonedStack = false;

 

In the function ReactToNews, before each consequence is evaluated, the code will examine the value of gafPoisonedConsequence[this consequence]; if this value is true, then the consequence will be skipped as an option.

 

A Complexity

The only issue remaining in my mind is the possibility that the storybuilder will want to create her own workaround to a poison situation. In other words, she wants to examine the situation and make her own decisions about it. For example, in the PickACharacter case we considered, in which a female character wants to seduce a male character, but they are all dead, then the result of PickACharacter will be poisoned. What if the storybuilder wants the female character to decide, in this special case, to go lesbian? 

 

First she tries out a role which includes a statement like this:

 

alpha <= PickACharacter(AnyMale)

Activate if (alpha >= 0)

 

This would have solved our problem even without the use of poison, but in any event the second line will be poisoned and so the role will not be activated. What happens now? Any attempt to examine the results of PickACharacter will lead to a poisoned result. What we need here is some sort of unpoisoning capability.

 

What if we say that any poisoned boolean operation returns a value of false and also kills the poison?