2017-06-06 4 views
0

EnvAssertEnvAssertStringの機能に違いはありますか? 私は両方を使用してファクトをアサートしようとしましたが、EnvAssertStringを使用してファクトをアサートし、EnvAssertを使用してファクトをアサートすると、関連するルールがアクティブになります。ここで CLIPS - EnvAssertStringとEnvAssert

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

をそして、これは私のC++コードスニペットです:

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

中:

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

EnvAssertStringを呼び出すと、次をアサートEnvAssertを呼び出すと、次のようにアサートされます。

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

誰かが問題の原因を教えてください。

答えて

0

AssertStringはAssertのラッパーです。基本的には、文字列引数を解析し、適切な型のファクトを作成し、指定されたスロット値を割り当て、指定されていないスロットにデフォルト値を割り当ててから、その事実をアサートします。 EnvAssertを使用するあなたの例では、 "EnvAssignFactSlotDefaults(theEnv、newFact);"指定されなかったスロットにはデフォルト値が割り当てられます。これにより、値TrueがSafetyStatusスロットに割り当てられ、r11ルールが一致することができます。

+0

お返事ありがとうございます。 –

関連する問題