【问题标题】:CLIPS - looking for match between random slots in multislot fieldsCLIPS - 在多槽字段中寻找随机槽之间的匹配
【发布时间】:2014-07-07 18:50:02
【问题描述】:

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

(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 值是否是匹配 simplecause 事实和断言扩展 finalcause 中的 ?coraxmatchafter 值之前的所有内容的子集。我相信这条规则应该能够在匹配简单原因时“跳过差距”。

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

【问题讨论】:

    标签: clips expert-system inference-engine generalization


    【解决方案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 槽中的值进行排序,以便对等价的事实有唯一的排序。

    【讨论】:

    • 嗨,加里。这是有道理的,我已经在 simplecause 生成器端实现了一个排序器,所以现在排列是不可能的。此外,我不需要在 coraxinfo 中具有相同值但在 changeinfo 中不具有相同值的简单原因事实之间进行匹配(反之亦然),我需要它们在两个多槽中具有相同的字段。问题是我不太确定如何以有效的方式构建这个“多重规则”。我已经更新了原始问题的尾部,以显示我制定了哪些规则,但我不确定这是否是一个好方法 - 我会感谢他们的任何 cmets。
    • 无视,发现错误
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多