CLIPS - 寻找多时隙字段中随机插槽之间的匹配

时间:2014-05-19 17:46:56

标签: clips expert-system inference-engine generalization

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

(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个值意味着在最坏的情况下,多时隙中的每秒值与其他事实中的smth匹配。

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

更新。如果我们试图通过在coraxinfo和changeinfo插槽中添加一个值,而不是我目前在这两个规则上停止的那样,采用构造(最终)事实的方法:

在两个多区域中创建一个匹配值的初始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事实,我们会尝试检查其中的所有多时隙值是否匹配simplecause事实中的?coraxmatchafter值之前的所有内容的子集,并断言扩展的finalcause。我相信这条规则应该能够超越差距。在匹配simplecauses。

(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个匹配字段的finalcause事实,我不明白为什么。难道它不会注意到这三个事实属于第二条规则吗?

(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))

2 个答案:

答案 0 :(得分: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个。

这不是您要用单一规则解决的问题。可能最好的方法是使用多个规则一次构造一个元素的finalcause事实。例如,首先确定其中有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插槽中的值进行排序,这样对于等效事实就有了独特的排序。

答案 1 :(得分: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))