实例绑定的唯一顺序

Unique Order of Instance Binding

我正在尝试为任何一对不同的实例触发一次规则。

下面是一个简单的例子:

(defclass USER_THING (is-a USER))

(definstances KNOWN_THINGS
    (thing-a of USER_THING)
    (thing-b of USER_THING)
    (thing-c of USER_THING))

(defrule match-things
    ?thing0 <- (object (is-a USER_THING))
    ?thing1 <- (object (is-a USER_THING))
=>
    (printout t "-------" crlf)
    (printout t "thing0 " (instance-name ?thing0) crlf)
    (printout t "thing1 " (instance-name ?thing1) crlf))

显然,我们期望 KNOWN_THINGS 与自身的笛卡尔积,这正是我们得到的:

CLIPS> (reset)
CLIPS> (run)
-------
thing0 [thing-c]
thing1 [thing-c]
-------
thing0 [thing-c]
thing1 [thing-b]
-------
thing0 [thing-c]
thing1 [thing-a]
-------
thing0 [thing-a]
thing1 [thing-c]
-------
thing0 [thing-b]
thing1 [thing-c]
-------
thing0 [thing-b]
thing1 [thing-b]
-------
thing0 [thing-b]
thing1 [thing-a]
-------
thing0 [thing-a]
thing1 [thing-b]
-------
thing0 [thing-a]
thing1 [thing-a]

虽然我想要的输出更类似于:

CLIPS> (reset)
CLIPS> (run)
-------
thing0 [thing-a]
thing1 [thing-b]
-------
thing0 [thing-a]
thing1 [thing-c]
-------
thing0 [thing-b]
thing1 [thing-c]

我有使用 Apache Jena 的前向链接推理系统的经验,我会在其中简单地添加一个规则子句来强制对实例名称进行任意排序:

(defrule match-things
    ?thing0 <- (object (is-a USER_THING))
    ?thing1 <- (object (is-a USER_THING))
    (> (str-compare (instance-name ?thing0) (instance-name ?thing1)) 0)
=>
    (printout t "-------" crlf)
    (printout t "thing0 " (instance-name ?thing0) crlf)
    (printout t "thing1 " (instance-name ?thing1) crlf))

这不是正确的 CLIPS 规则。我该怎么做才能达到我想要的效果?我可以根据需要向实例添加信息(例如任意数字或字符串标识符)以促进此操作。

使用测试条件元素:

(defrule match-things
    ?thing0 <- (object (is-a USER_THING))
    ?thing1 <- (object (is-a USER_THING))
    (test (> (str-compare (instance-name ?thing0) (instance-name ?thing1)) 0))
=>
    (printout t "-------" crlf)
    (printout t "thing0 " (instance-name ?thing0) crlf)
    (printout t "thing1 " (instance-name ?thing1) crlf))