CLIPS规则优化:如何准确检测仅不属于ss-pair的ts-pair节点
CLIPS规则修正:判断ts-pair中至多一个节点不属于ss-pair
原事实定义
(deffacts ss-and-ts-edges (ss-pair (ss 1 2)) (ss-pair (ss 2 3))(ss-pair (ss 3 4))(ss-pair (ss 4 5)) (ss-pair (ss 8 9)) (ss-pair (ss 9 10)) (ss-pair (ss 11 12)) (ss-pair (ss 12 13))(ss-pair (ss 13 14))(ss-pair (ss 14 15)) (ts-pair (ts 4 9))(ts-pair (ts 6 11))(ts-pair (ts 8 13)))
原规则的问题
原规则connexion-directe存在三处关键问题:
- 跨
ts-pair匹配节点,而非针对单个ts-pair的两个节点做整体校验,导致重复输出无关节点 - 仅匹配单个
ss-pair的节点列表,无法判断节点是否存在于任意ss-pair中 - 动作部分
or语法错误,逻辑上未区分节点是否完全不在所有ss-pair中
修正后的规则实现
; 收集所有ss-pair中的节点,生成全局节点集合事实 (defrule collect-ss-nodes (not (ss-nodes $?)) => (bind ?all-ss-nodes (create$)) ; 遍历所有ss-pair,合并节点到集合 (accumulate (bind ?all-ss-nodes (create$ ?all-ss-nodes ?1 ?2)) (ss-pair (ss ?1 ?2)) ?all-ss-nodes) (assert (ss-nodes ?all-ss-nodes))) ; 核心规则:检查每个ts-pair,输出仅有的不在ss集合中的节点 (defrule connexion-directe (ss-nodes ?all-ss) (ts-pair (ts ?u ?v)) => (bind ?u-missing (not (member$ ?u ?all-ss))) (bind ?v-missing (not (member$ ?v ?all-ss))) ; 仅当恰好一个节点不在ss集合中时输出 (if (xor ?u-missing ?v-missing) then (if ?u-missing then (printout t "u: " ?u ": NOT IN ss-pair" crlf) else (printout t "v: " ?v ": NOT IN ss-pair" crlf) ) ) )
修正说明
- 全局节点集合:通过
collect-ss-nodes规则一次性收集所有ss-pair的节点到ss-nodes事实,避免重复遍历,保证节点存在性判断的准确性 - 单ts-pair校验:核心规则针对每个
ts-pair的两个节点单独检查,避免跨pair匹配的混乱 - 逻辑准确:使用
xor判断是否恰好有一个节点不在ss集合中,符合“至多一个不属于”的要求,只输出符合条件的节点
验证结果
运行修正后的规则,输出结果与预期一致:
u: 6: NOT IN ss-pair
内容的提问来源于stack exchange,提问作者Honoré De Marseille
相关产品推荐
相关产品推荐

