CLIPS - EnvAssertString 与 EnvAssert
CLIPS - EnvAssertString vs EnvAssert
EnvAssert
和 EnvAssertString
在功能上有区别吗?
我尝试同时使用两者来断言一个事实,但是当我使用 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 规则。
EnvAssert
和 EnvAssertString
在功能上有区别吗?
我尝试同时使用两者来断言一个事实,但是当我使用 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 规则。