CLIPS - EnvAssertString 与 EnvAssert

CLIPS - EnvAssertString vs EnvAssert

EnvAssertEnvAssertString 在功能上有区别吗? 我尝试同时使用两者来断言一个事实,但是当我使用 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))

谁能告诉我问题出在哪里?

AssertString 是 Assert 的包装器。基本上它解析字符串参数,创建适当类型的事实,分配指定的槽值,将默认值分配给未指定的槽,然后断言事实。在您使用 EnvAssert 的示例中,您需要调用 "EnvAssignFactSlotDefaults(theEnv,newFact);" 以便将默认值分配给您未指定的插槽。这将导致将值 True 分配给 SafetyStatus 插槽并允许匹配 r11 规则。