如何优化 CLIPS 中不同模板化事实之间的模式匹配

How to optimize pattern matching between different templated facts in CLIPS

我有一个类似于以下的规则:

(deftemplate person
    (slot name ( type INTEGER))
    (slot surname ( type INTEGER))
)

(defrule surname_cant_be_a_name
    ?p1<-(person (name ?n1))
    ?p2<-(person (surname ?n2&:(= ?n1 ?n2)))
    =>
    (retract ?p2)
)

从功能上讲,这是有效的。但是我 运行 这是在一个巨大的事实集上进行的,而且复杂性很快就会达到顶峰。

因为规则正在寻找两个人对象,所以存在嵌套的 for 循环有点减慢执行速度的情况。此设置会遍历每个可能的人配对,只有在配对后,规则才会根据我的设置过滤掉“&:(= ?n1 ?n2))”

我觉得一定有更聪明的方法来做到这一点。理想情况下,我希望 p1 遍历所有 person 对象,但只匹配符合我规则的 p2 对象。

为了使我的观点更清楚,我正在寻找类似以下内容的东西,它可以避免双重循环:

(defrule surname_cant_be_a_name
    ?p1<-(person (name ?n1))
    ?p2<-(person (surname  %%JUST_MATCH_n1%% ))
    =>
    (retract ?p2)
)

这有可能实现这样的目标吗?任何优化此规则的建议都将受到赞赏。

谢谢

P.S。抱歉这个荒谬的例子,但它很好地突出了我的情况。

如果要比较变量的相等性,在两个地方使用同一个变量比使用两个单独的变量并调用 =eq 函数比较是否相等。在各种模式中,哈希表用于快速定位共享相同变量的事实,而当您使用函数调用来执行相等比较时则不会这样做。对于大量的事实,这可以提高几个数量级的性能:

         CLIPS (6.31 6/12/19)
CLIPS> (clear)
CLIPS> 
(deftemplate person
   (slot name (type INTEGER))
   (slot surname (type INTEGER)))
CLIPS> 
(defrule surname_cant_be_a_name
   ?p1<- (person (name ?n1))
   ?p2<- (person (surname ?n2&:(= ?n1 ?n2)))
   =>
   (retract ?p2))
CLIPS> (timer (loop-for-count (?i 10000) (assert (person (name ?i) (surname (+ ?i 1))))))
12.3485549999987
CLIPS> (clear)
CLIPS> 
(deftemplate person
   (slot name (type INTEGER))
   (slot surname (type INTEGER)))
CLIPS> 
(defrule surname_cant_be_a_name
   ?p1 <- (person (name ?n1))
   ?p2 <- (person (surname ?n1))
   =>
   (retract ?p2))
CLIPS> (timer (loop-for-count (?i 10000) (assert (person (name ?i) (surname (+ ?i 1))))))
0.0177029999995284
CLIPS> (/ 12.3485549999987 0.0177029999995284)
697.540247434201
CLIPS>