Search code examples
c++clipsexpert-system

CLIPS - EnvAssertString vs EnvAssert


Is there a difference in functionality between EnvAssert and EnvAssertString? I tried to assert a fact using both, but the related rule is activated when I assert the fact using EnvAssertString and is not activated when I assert the fact using EnvAssert!

Here is my definitions in constructs.clp file:

(deftemplate Safety
    (slot SafetyStatus (type SYMBOL) (default True) (allowed-symbols True False))
    (slot DistanceToObject (type INTEGER) (default 0))
    (slot BatteryLevel (type INTEGER) (default 0)))

(defrule r11
    ?f <- (Safety (SafetyStatus True) (BatteryLevel ?bat) (DistanceToObject ?dist))
    (test (and (> ?bat 20) (> ?dist 3)))
    => 
    (modify ?f (SafetyStatus False)))

And this is my C++ code snippet:

// The rule is activated if I use this line
EnvAssertString(theEnv, "(Safety (BatteryLevel 100)(DistanceToObject 4))");

// The rule is not activated if I used these lines
templatePtr = EnvFindDeftemplate(theEnv, "Safety");
newFact = EnvCreateFact(theEnv, templatePtr);
if (newFact == NULL) return -1;

theValue.type = INTEGER;
theValue.value = EnvAddLong(theEnv, 100);
EnvPutFactSlot(theEnv, newFact, "BatteryLevel", &theValue);

theValue.type = INTEGER;
theValue.value = EnvAddLong(theEnv, 4);
EnvPutFactSlot(theEnv, newFact, "DistanceToObject", &theValue);

EnvAssert(theEnv, newFact);

EnvRun(theEnv, -1L);

Calling EnvAssertString asserts the following:

==> f-1     (Safety (SafetyStatus nil) (DistanceToObject 4) (BatteryLevel 100))

while calling EnvAssert asserts the following:

==> f-1     (Safety (SafetyStatus True) (DistanceToObject 4) (BatteryLevel 100))

Could someone please tell me where is the problem?


Solution

  • AssertString is a wrapper for Assert. Basically it parses the string argument, creates a fact of the appropriate type, assigns the specified slot values, assigns default values to unspecified slots, and then asserts the fact. In your example using EnvAssert, you need to call "EnvAssignFactSlotDefaults(theEnv,newFact);" so that default values will be assigned to the slots you have left unspecified. This will cause the value True to be assigned to the SafetyStatus slot and allows the r11 rule to be matched.