0

考虑这种情况。我有这样的模板:

(deftemplate MAIN::simplecause
   (multislot coraxinfo (type INTEGER) (default undefined))
   (multislot changeinfo (type SYMBOL) (default undefined)))

(deftemplate MAIN::finalcause   
   (multislot coraxinfo (type INTEGER) (default undefined))
   (multislot changeinfo (type SYMBOL) (default undefined)))

我知道在 coraxinfo 插槽中,我将始终拥有不超过 14 个值(可能更少,但永远不会更多)。我现在也在 changeinfo multislot 中拥有不超过 13 个值。

我正在尝试编写一个规则,该规则将找到我将拥有的任何事实之间的所有可能匹配项。

例如:

(deffacts start
       (simplecause (coraxinfo 1 2 3) (changeinfo a b c))
       (simplecause (coraxinfo 7 8 2 3 9) (changeinfo d a b e))
       (simplecause (coraxinfo 2 3 10 13) (changeinfo f g a b z))
       (simplecause (coraxinfo 77 88 99 66) (changeinfo k m l s))
       (simplecause (coraxinfo 88 99 11 22) (changeinfo v k m w))
       (simplecause (coraxinfo 13 88 99) (changeinfo k m))
       (simplecause (coraxinfo 666 777 888) (changeinfo abc def))
       (simplecause (coraxinfo 666 111 222 888 333 444 555 777 999) (changeinfo abc 1a 2a 3a def 4a)))

我需要得到这个(每个多槽中的值顺序无关紧要):

(finalcause (coraxinfo 2 3) (changeinfo a b))
(finalcause 88 99) (changeinfo k m)) 
(finalcause 666 777 888) (changeinfo abc def)) 

现在我已经停止了这个功能:

(defrule cause_generalization_initial1
   ?f1 <- (simplecause (coraxinfo $?coraxmatch1 $?coraxmatch2 $?coraxmatch3 $?coraxmatch4 $?coraxmatch5 $?coraxmatch6 $?coraxmatch7) (changeinfo $?pricematch1 $?pricematch2 $?pricematch3 $?pricematch4 $?pricematch5 $?pricematch6 $?pricematch7))
   ?f2 <- (simplecause (coraxinfo $?coraxmatch1 $?coraxmatch2 $?coraxmatch3 $?coraxmatch4 $?coraxmatch5 $?coraxmatch6 $?coraxmatch7) (changeinfo $?pricematch1 $?pricematch2 $?pricematch3 $?pricematch4 $?pricematch5 $?pricematch6 $?pricematch7))
   (test (neq ?f1 ?f2))
   (not (finalcause (coraxinfo $?coraxmatch1 $?coraxmatch2 $?coraxmatch3 $?coraxmatch4 $?coraxmatch5 $?coraxmatch6 $?coraxmatch7) (changeinfo $?pricematch1 $?pricematch2 $?pricematch3 $?pricematch4 $?pricematch5 $?pricematch6 $?pricematch7)))
   =>
   (assert (finalcause (coraxinfo $?coraxmatch1 $?coraxmatch2 $?coraxmatch3 $?coraxmatch4 $?coraxmatch5 $?coraxmatch6 $?coraxmatch7) (changeinfo $?pricematch1 $?pricematch2 $?pricematch3 $?pricematch4 $?pricematch5 $?pricematch6 $?pricematch7))))

这有点笨拙,但据我记得$?表示“零或更多”,所以即使我的字段少于我在搜索模式中指定的字段,它也应该可以工作。我在每个模式中最多使用 7 个多槽,因为最多有 14 或 13 个值意味着在最坏的情况下,多槽中的每一秒值都将与其他事实相匹配。

当我加载 deffacts CLIPS 中指定的事实时,问题会进入一种无限循环——它很长时间没有响应,所以我相信我的规则出错了。此外,这条规则应该会杀死引擎,以防我有几个几乎相同的事实,只有一个领域的差异。在这种情况下,它们之间会产生大量的匹配。知道我哪里错了吗?我将非常感谢任何建议。

更新。如果我们尝试通过一次向 coraxinfo 和 changeinfo 插槽添加一个值来构建(finalcause)事实的方法,那么我目前已停止使用以下两条规则:

在两个多槽中创建具有一个匹配值的初始 finalcause 事实:

(defrule cause_generalization_initial
    ?f1 <- (simplecause (coraxinfo $? ?coraxmatch $?) (changeinfo $? ?changematch $?))
    ?f2 <- (simplecause (coraxinfo $? ?coraxmatch $?) (changeinfo $? ?changematch $?))
    (test (neq ?f1 ?f2))
    (not (finalcause (coraxinfo ?coraxmatch) (changeinfo ?changematch)))
    =>
    (assert (finalcause (coraxinfo ?coraxmatch) (changeinfo ?changematch)))

如果我们有任何 finalcause 事实,我们会尝试检查其中的所有 multislot 值是否是 ?coraxmatchafter 值之前的所有内容的子集,以匹配 simplecause 事实并断言扩展的 finalcause。我相信这条规则应该能够在匹配简单原因时“跳过差距”。

(defrule cause_generalization_advanced
?f1 <- (simplecause (coraxinfo $?coraxbefore1 ?coraxmatchafter $?) (changeinfo $?changebefore1 ?changematchafter $?))
?f2 <- (simplecause (coraxinfo $?coraxbefore2 ?coraxmatchafter $?) (changeinfo $?changebefore2 ?changematchafter $?))
(test (neq ?f1 ?f2))
(finalcause (coraxinfo $?finalcoraxbefore) (changeinfo $?finalchangebefore))
(test (and  (subsetp $?finalcoraxbefore $?coraxbefore1) (subsetp $?finalcoraxbefore $?coraxbefore2) 
        (subsetp $?finalchangebefore $?changebefore1) (subsetp $?finalchangebefore $?changebefore2)))
=>
(assert (finalcause (coraxinfo $?finalcoraxbefore ?coraxmatchafter) (changeinfo $?finalchangebefore ?changematchafter))))

我使用这些 deffacts 的规则(注意 deffacts 与上面的不同):

(deffacts start
       (simplecause (coraxinfo 1 2 3) (changeinfo a b c))
       (simplecause (coraxinfo 7 8 2 3 9) (changeinfo d a b e))
       (simplecause (coraxinfo 2 3 10 13) (changeinfo f g a b z))
       (simplecause (coraxinfo 77 88 99 66) (changeinfo k m l s))
       (simplecause (coraxinfo 88 99 11 22) (changeinfo v k m w))
       (simplecause (coraxinfo 13 88 99) (changeinfo k m))
       (simplecause (coraxinfo 666 777 888) (changeinfo abc def))
       (simplecause (coraxinfo 666 111 222 777 333 444 555 888 999) (changeinfo abc 1a 2a 3a def 4a)))

这里的问题是我希望它能够为 3 个匹配字段生成最终原因,但它只生成具有 2 个匹配字段的最终原因事实,我不明白为什么。难道它不应该注意到这三个事实属于第二条规则吗?

(simplecause (coraxinfo 666 777 888) (changeinfo abc def))
(simplecause (coraxinfo 666 111 222 777 333 444 555 888 999) (changeinfo abc 1a 2a 3a def 4a))
(finalcause (coraxinfo 666 888) (changeinfo abc def))

Output of both rules is:
f-0     (initial-fact)
f-1     (simplecause (coraxinfo 1 2 3) (changeinfo a b c))
f-2     (simplecause (coraxinfo 7 8 2 3 9) (changeinfo d a b e))
f-3     (simplecause (coraxinfo 2 3 10 13) (changeinfo f g a b z))
f-4     (simplecause (coraxinfo 77 88 99 66) (changeinfo k m l s))
f-5     (simplecause (coraxinfo 88 99 11 22) (changeinfo v k m w))
f-6     (simplecause (coraxinfo 13 88 99) (changeinfo k m))
f-7     (simplecause (coraxinfo 666 777 888) (changeinfo abc def))
f-8     (simplecause (coraxinfo 666 111 222 777 333 444 555 888 999) (changeinfo abc 1a 2a 3a def 4a))
f-9     (finalcause (coraxinfo 666) (changeinfo abc))
f-10    (finalcause (coraxinfo 666 888) (changeinfo abc def))
f-11    (finalcause (coraxinfo 666 777) (changeinfo abc def))
f-12    (finalcause (coraxinfo 666) (changeinfo def))
f-13    (finalcause (coraxinfo 777) (changeinfo abc))
f-14    (finalcause (coraxinfo 777 888) (changeinfo abc def))
f-15    (finalcause (coraxinfo 777) (changeinfo def))
f-16    (finalcause (coraxinfo 888) (changeinfo abc))
f-17    (finalcause (coraxinfo 888) (changeinfo def))
f-18    (finalcause (coraxinfo 88) (changeinfo k))
f-19    (finalcause (coraxinfo 88 99) (changeinfo k m))
f-20    (finalcause (coraxinfo 88) (changeinfo m))
f-21    (finalcause (coraxinfo 99) (changeinfo k))
f-22    (finalcause (coraxinfo 99) (changeinfo m))
f-23    (finalcause (coraxinfo 2) (changeinfo a))
f-24    (finalcause (coraxinfo 2 3) (changeinfo a b))
f-25    (finalcause (coraxinfo 2) (changeinfo b))
f-26    (finalcause (coraxinfo 3) (changeinfo a))
f-27    (finalcause (coraxinfo 3) (changeinfo b))
4

2 回答 2

1

使用 7 个多字段变量,您正在创建模式匹配方式的组合爆炸。查看规则中的第一个模式可以匹配的方式数量:

CLIPS> 
(deftemplate simplecause
   (multislot coraxinfo)
   (multislot changeinfo))
CLIPS> 
(deftemplate  finalcause   
   (multislot coraxinfo)
   (multislot changeinfo))
CLIPS>    
(defrule cause_generalization_initial1
   (simplecause (coraxinfo $?coraxmatch1 $?coraxmatch2 $?coraxmatch3 $?coraxmatch4 $?coraxmatch5 $?coraxmatch6 $?coraxmatch7) 
                (changeinfo $?pricematch1 $?pricematch2 $?pricematch3 $?pricematch4 $?pricematch5 $?pricematch6 $?pricematch7))
   =>)
CLIPS> (assert (simplecause (coraxinfo) (changeinfo)))
<Fact-1>
CLIPS> (agenda)
0      cause_generalization_initial1: f-1
For a total of 1 activation.
CLIPS> (modify 1 (coraxinfo a) (changeinfo 1))
<Fact-2>
CLIPS> (agenda)
0      cause_generalization_initial1: f-2
   .
   .
   .
0      cause_generalization_initial1: f-2
For a total of 49 activations.
CLIPS> (modify 2 (coraxinfo a b) (changeinfo 1 2))
<Fact-3>
CLIPS> (agenda)
0      cause_generalization_initial1: f-3
   .
   .
   .
0      cause_generalization_initial1: f-3
For a total of 784 activations.
CLIPS> (modify 3 (coraxinfo a b c) (changeinfo 1 2 3))
<Fact-4>
CLIPS> (agenda)
0      cause_generalization_initial1: f-4
   .
   .
   .
0      cause_generalization_initial1: f-4
For a total of 7056 activations.


CLIPS> (modify 4 (coraxinfo a b c d) (changeinfo 1 2 3 4))
<Fact-5>
CLIPS> (agenda)
0      cause_generalization_initial1: f-5
   .
   .
   .
0      cause_generalization_initial1: f-5
For a total of 44100 activations.
CLIPS>

如果 coraxinfo 和 changeinfo 插槽为空,则只有一种方式可以匹配模式并且只有一次激活。如果每个插槽包含一个值,则可以通过 7 种不同的方式匹配每个插槽(七个变量中的每个变量都有一个值,其余变量为空)。在这两个插槽之间,这意味着模式可以有 49 种不同的匹配方式。

一旦你在每个槽中获得 4 个值,就有 44100 种不同的方式可以匹配单个模式。这意味着通过添加第二个模式,需要比较 44,100 * 44,100 个组合。这是一个事实的断言需要进行 1,944,810,000 次比较,并且您有 8 个事实,其中一个事实在一个槽中有 9 个值,另一个在另一个槽中具有 6 个值。

这不是你要用一条规则来解决的问题。可能最好的方法是使用多个规则一次构建一个元素的最终原因事实。例如,首先确定有两个事实,其中有 666,并创建一个 (finalcause (coraxinfo 666) (changeinfo)) 事实。然后有一个规则确定有两个事实都具有 finalcause 中存在的所有值加上一个不存在的附加值并添加该值。例如,(finalcause (coraxinfo 666 777) (changeinfo))。然后,您可以拥有删除中间结果的规则。

您还需要构建规则,以免生成排列。例如,您不想生成所有这些不同但等效的事实:

(finalcause (coraxinfo 666 777 888) (changeinfo abc def))
(finalcause (coraxinfo 666 888 777) (changeinfo abc def))
(finalcause (coraxinfo 777 666 888) (changeinfo abc def))
(finalcause (coraxinfo 777 888 666) (changeinfo abc def))
(finalcause (coraxinfo 888 666 777) (changeinfo abc def))
(finalcause (coraxinfo 888 777 666) (changeinfo abc def))
(finalcause (coraxinfo 666 777 888) (changeinfo def abc))
(finalcause (coraxinfo 666 888 777) (changeinfo def abc))
(finalcause (coraxinfo 777 666 888) (changeinfo def abc))
(finalcause (coraxinfo 777 888 666) (changeinfo def abc))
(finalcause (coraxinfo 888 666 777) (changeinfo def abc))
(finalcause (coraxinfo 888 777 666) (changeinfo def abc))

为此,我建议对您放置在 finalcause 插槽中的值进行排序,以便对等价事实有唯一的排序。

于 2014-05-20T00:19:19.000 回答
0

在 Gary 的帮助下,这里有一个变种:

(deftemplate MAIN::simplecause
   (multislot coraxinfo (type INTEGER) (default 0))
   (multislot changeinfo (type SYMBOL) (default undefined)))

(deftemplate MAIN::finalcause   
   (multislot coraxinfo (type INTEGER) (default 0))
   (multislot changeinfo (type SYMBOL) (default undefined)))

(deffacts start
       (simplecause (coraxinfo 1 2 3) (changeinfo a b c))
       (simplecause (coraxinfo 7 8 2 3 9) (changeinfo d a b e))
       (simplecause (coraxinfo 2 3 10 13) (changeinfo f g a b z))
       (simplecause (coraxinfo 77 88 99 66) (changeinfo k m l s))
       (simplecause (coraxinfo 88 99 11 22) (changeinfo v k m w))
       (simplecause (coraxinfo 13 88 99) (changeinfo k m))
       (simplecause (coraxinfo 666 777 888) (changeinfo abc def))
       (simplecause (coraxinfo 666 111 222 777 333 444 555 888 999) (changeinfo abc 1a 2a 3a def 4a)))

(defrule cause_generalization_advanced_corax
    ?f1 <- (simplecause (coraxinfo $?coraxbefore1 ?coraxmatchafter $?) (changeinfo $?changebefore1))
    ?f2 <- (simplecause (coraxinfo $?coraxbefore2 ?coraxmatchafter $?) (changeinfo $?changebefore2))
    (test (neq ?f1 ?f2))
    (finalcause (coraxinfo $?finalcoraxbefore) (changeinfo $?finalchangebefore))
    (test (and  (subsetp $?finalcoraxbefore $?coraxbefore1) (subsetp $?finalcoraxbefore $?coraxbefore2) 
            (subsetp $?finalchangebefore $?changebefore1) (subsetp $?finalchangebefore $?changebefore2)))
    =>
    (assert (finalcause (coraxinfo $?finalcoraxbefore ?coraxmatchafter) (changeinfo $?finalchangebefore))))


(defrule cause_generalization_advanced_change
    ?f1 <- (simplecause (coraxinfo $?coraxbefore1) (changeinfo $?changebefore1 ?changematchafter $?))
    ?f2 <- (simplecause (coraxinfo $?coraxbefore2) (changeinfo $?changebefore2 ?changematchafter $?))
    (test (neq ?f1 ?f2))
    (finalcause (coraxinfo $?finalcoraxbefore) (changeinfo $?finalchangebefore))
    (test (and  (subsetp $?finalcoraxbefore $?coraxbefore1) (subsetp $?finalcoraxbefore $?coraxbefore2) 
            (subsetp $?finalchangebefore $?changebefore1) (subsetp $?finalchangebefore $?changebefore2)))
    =>
    (assert (finalcause (coraxinfo $?finalcoraxbefore) (changeinfo $?finalchangebefore ?changematchafter))))

(reset)
(run)

(facts)

f-0     (initial-fact)
f-1     (simplecause (coraxinfo 1 2 3) (changeinfo a b c))
f-2     (simplecause (coraxinfo 7 8 2 3 9) (changeinfo d a b e))
f-3     (simplecause (coraxinfo 2 3 10 13) (changeinfo f g a b z))
f-4     (simplecause (coraxinfo 77 88 99 66) (changeinfo k m l s))
f-5     (simplecause (coraxinfo 88 99 11 22) (changeinfo v k m w))
f-6     (simplecause (coraxinfo 13 88 99) (changeinfo k m))
f-7     (simplecause (coraxinfo 666 777 888) (changeinfo abc def))
f-8     (simplecause (coraxinfo 666 111 222 777 333 444 555 888 999) (changeinfo abc 1a 2a 3a def 4a))
f-9     (finalcause (coraxinfo 666) (changeinfo abc))
f-10    (finalcause (coraxinfo 666 888) (changeinfo abc))
f-11    (finalcause (coraxinfo 666 888) (changeinfo abc def))
f-12    (finalcause (coraxinfo 666 777) (changeinfo abc))
f-13    (finalcause (coraxinfo 666 777 888) (changeinfo abc))
f-14    (finalcause (coraxinfo 666 777 888) (changeinfo abc def))
f-15    (finalcause (coraxinfo 666 777) (changeinfo abc def))
f-16    (finalcause (coraxinfo 666) (changeinfo abc def))
f-17    (finalcause (coraxinfo 666) (changeinfo def))
f-18    (finalcause (coraxinfo 666 888) (changeinfo def))
f-19    (finalcause (coraxinfo 666 777) (changeinfo def))
f-20    (finalcause (coraxinfo 666 777 888) (changeinfo def))
f-21    (finalcause (coraxinfo 777) (changeinfo abc))
f-22    (finalcause (coraxinfo 777 888) (changeinfo abc))
f-23    (finalcause (coraxinfo 777 888) (changeinfo abc def))
f-24    (finalcause (coraxinfo 777) (changeinfo abc def))
f-25    (finalcause (coraxinfo 777) (changeinfo def))
f-26    (finalcause (coraxinfo 777 888) (changeinfo def))
f-27    (finalcause (coraxinfo 888) (changeinfo abc))
f-28    (finalcause (coraxinfo 888) (changeinfo abc def))
f-29    (finalcause (coraxinfo 888) (changeinfo def))
f-30    (finalcause (coraxinfo 88) (changeinfo k))
f-31    (finalcause (coraxinfo 88 99) (changeinfo k))
f-32    (finalcause (coraxinfo 88 99) (changeinfo k m))
f-33    (finalcause (coraxinfo 88) (changeinfo k m))
f-34    (finalcause (coraxinfo 88) (changeinfo m))
f-35    (finalcause (coraxinfo 88 99) (changeinfo m))
f-36    (finalcause (coraxinfo 99) (changeinfo k))
f-37    (finalcause (coraxinfo 99) (changeinfo k m))
f-38    (finalcause (coraxinfo 99) (changeinfo m))
f-39    (finalcause (coraxinfo 2) (changeinfo a))
f-40    (finalcause (coraxinfo 2 3) (changeinfo a))
f-41    (finalcause (coraxinfo 2 3) (changeinfo a b))
f-42    (finalcause (coraxinfo 2) (changeinfo a b))
f-43    (finalcause (coraxinfo 2) (changeinfo b))
f-44    (finalcause (coraxinfo 2 3) (changeinfo b))
f-45    (finalcause (coraxinfo 3) (changeinfo a))
f-46    (finalcause (coraxinfo 3) (changeinfo a b))
f-47    (finalcause (coraxinfo 3) (changeinfo b))
于 2014-05-21T15:47:05.893 回答