CLIPS中如何使用modify命令修改非模板有序事实指定值
CLIPS环境modify命令修改有序事实异常解决方案
问题1:执行(modify 1 (implied ?s))返回FALSE的原因
这个写法存在两处错误:
- 对未提前用
deftemplate定义模板、直接断言的有序事实(比如示例中的(a b c d)),CLIPS会自动生成名为implied的隐式多字段槽,存储关系名(即事实第一个元素a)之后的所有内容。给多字段槽传多字段值时必须加$做显式展开,直接写?s时,CLIPS会把x y z三个值当成单个整体值传入,和槽的匹配规则冲突,直接执行失败返回FALSE。 - 修正后可直接达成修改为
(a x y z)的目标,代码如下:
CLIPS> (bind ?s x y z) (x y z) CLIPS> (modify 1 (implied $?s)) <Fact-1> CLIPS> (facts) f-1 (a x y z) For a total of 1 fact.
问题2:替换事实中指定元素的实现方法
该需求完全可以实现,两种常用写法可按需选择:
- 方法1:沿用modify命令(适配CLIPS 6.3及以上新版本)
核心逻辑是先取出原事实隐式槽的内容,替换指定位置元素后展开传入modify即可。注意CLIPS多字段索引从1开始计数,原事实(a b c d)里的c是implied槽内的第2个元素(槽内顺序为b(1)、c(2)、d(3)),实现代码:
; 初始化目标事实 CLIPS> (assert (a b c d)) <Fact-1> ; 读取原事实implied槽的内容 CLIPS> (bind ?old-content (fact-slot-value 1 implied)) (b c d) ; 替换第2位的c为g,replace$参数规则:(replace$ 多字段变量 替换起始位 替换结束位 新值) CLIPS> (bind ?new-content (replace$ ?old-content 2 2 g)) (b g d) ; 提交修改 CLIPS> (modify 1 (implied $?new-content)) <Fact-1> CLIPS> (facts) f-1 (a b g d) For a total of 1 fact.
- 方法2:先删后插(兼容所有CLIPS版本,稳定性最高)
部分老版本CLIPS对有序事实调用modify存在兼容bug,保险起见可以先撤回旧事实,替换字段后重新断言新事实:
CLIPS> (assert (a b c d)) <Fact-1> CLIPS> (bind ?old-content (fact-slot-value 1 implied)) (b c d) CLIPS> (bind ?new-content (replace$ ?old-content 2 2 g)) (b g d) CLIPS> (retract 1) CLIPS> (assert (a $?new-content)) <Fact-2> CLIPS> (facts) f-2 (a b g d) For a total of 1 fact.
补充提示:如果是复杂规则场景下需要频繁修改事实,优先用
deftemplate定义结构化模板事实,相比直接操作有序事实,可读性和执行稳定性都会高很多。
内容的提问来源于stack exchange,提问作者Ramachandran
相关产品推荐
相关产品推荐

