2017-06-06 6 views
0

Existe-t-il une différence de fonctionnalité entre EnvAssert et EnvAssertString? J'ai essayé d'affirmer un fait en utilisant les deux, mais la règle connexe est activée lorsque j'affirme le fait en utilisant EnvAssertString et n'est pas activée lorsque j'affirme le fait en utilisant EnvAssert!CLIPS - EnvAssertString vs EnvAssert

Voici mes définitions dans un fichier constructs.clp:

(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))) 

Et ceci est mon C++ extrait de code:

// 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); 

Appel EnvAssertString affirme ce qui suit:

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

tout appeler EnvAssert affirme:

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

Quelqu'un pourrait me dire où est le problème?

Répondre

0

AssertString est un wrapper pour Assert. Fondamentalement, il analyse l'argument de chaîne, crée un fait du type approprié, attribue les valeurs d'emplacement spécifiées, affecte les valeurs par défaut aux emplacements non spécifiés, puis affirme le fait. Dans votre exemple utilisant EnvAssert, vous devez appeler "EnvAssignFactSlotDefaults (theEnv, newFact);" de sorte que les valeurs par défaut seront assignées aux emplacements que vous avez laissés non spécifiés. Cela entraînera l'attribution de la valeur True à l'emplacement SafetyStatus et permettra de faire correspondre la règle r11.

+0

Merci @Gary pour votre réponse rapide, maintenant ça marche. –