2017-06-06 51 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++代碼片段:

// 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斷言如下:

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

而致電EnvAssert斷言如下:

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

有人能告訴我問題在哪裏嗎?

回答

0

AssertString是Assert的包裝。基本上,它分析字符串參數,創建適當類型的事實,分配指定的插槽值,將默認值分配給未指定的插槽,然後聲明該事實。在你使用EnvAssert的例子中,你需要調用「EnvAssignFactSlotDefaults(theEnv,newFact);」以便將默認值分配給您未指定的插槽。這將導致值True分配給SafetyStatus插槽,並允許匹配r11規則。

+0

感謝@Gary爲您的快速回復,現在它的工作。 –