“It depends on what your definition of not isn’t”

Us programmer geeks have a very well defined preconceived notion of what “not” means. If I say:


var person = Pick_A_Random_Person_Off_The_Street();
if ( NOT ( person.Thinks_Mike_Is_Cool() ) ) then
    print “mike is lame”
else
    print “holy cow”

In almost all cases that program will print “mike is lame”. Only in the rare case that somebody explicitly states that I am cool will it print “holy cow”. In most cases where the random person off the street has absolutely no knowledge of my coolness (my coolness is unknown), the program will still print “mike is lame” because NOT means “do this anytime the following statement is not true”.

Simple, right, no no. SCORM 2004 Sequencing and Navigation takes a different slant on the meaning of the not operator. Instead of not meaning “any time the following statement is not true”, in SCORM S&N it means “any time the opposite of the following statement is true”. Notice the subtle difference, in SCORM the not operator covers the opposite case but not the unknown case. To write code equivalent to the code above using the SCORM definition of the not operator, you would have to write it like this:

if ((NOT(person.Thinks_Mike_Is_Cool())) OR
     person.Does_Not_Know_Mike()
   ) then
    print “mike is lame”
else
    print “holy cow”

In SCORM, NOT doesn’t cover all the cases where mike isn’t cool (person doesn’t know mike or person thinks mike is lame), it only covers the explicit opposite case of coolness (lameness).

Ok, enough abstract, self-deprecating analogies. How does this apply to real sequencing rules. Say you want to write a simple rule that says “unless the user satisfied an objective, disable the activity”. Seems straight forward enough. Using traditional logic, you would write something like this:

<!–WARNING – incorrect code example –>
<imsss:postConditionRule>
    <imsss:ruleConditions>
        <imsss:ruleCondition referencedObjective=”obj_make_mike_cool” operator=”not” condition=”satisfied”/>
    </imsss:ruleConditions>
    <imsss:ruleAction action=”disabled”/>
    </imsss:postConditionRule>

But that doesn’t do what you probably want it to. What that really says is “if the user attempted the objective and failed it, then disable the activity”. If the user never attempted the objective, then this activity will still be enabled. To achieve what you’re after, you’ll need code like this:

<imsss:postConditionRule>
    <imsss:ruleConditions conditionCombination=”any”>
        <imsss:ruleCondition referencedObjective=”obj_make_mike_cool” operator=”not” condition=”satisfied”/>
        <imsss:ruleCondition referencedObjective=”obj_make_mike_cool” operator=”not” condition=”objectiveStatusKnown”/>
    </imsss:ruleConditions>
    <imsss:ruleAction action=”disabled”/>
    </imsss:postConditionRule>

That code says, if the objective has an unknown status (has not been attempted) or if it was attempted and was not satisfied, then disable the activity.

In summary, the NOT operator does not cover the unknown state. Sequencing rule conditions need to explicitly account for the unknown state.

Mike is the Founder and was President of Rustici Software until 2016. Most recently he was the CEO of Watershed Systems. He helped guide the first draft of the Tin Can API (xAPI) and believes ice cream is the "elixir of life."