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 マルチスロットでは、値が 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))))

少し不器用ですが、私が覚えている限りでは $? 「ゼロ以上」を意味するため、検索パターンで指定したよりもフィールドが少なくても機能するはずです。最大値として 14 または 13 の値を持つことは、最悪の場合、マルチスロットのすべての 2 番目の値が他の事実と一致することを意味するため、各パターンで最大 7 つのマルチスロットを使用します。

defacts CLIPS で指定されたファクトをロードすると、一種の無限ループに陥るという問題 - 長い間応答しないので、ルールに誤りがあると思います。また、このルールは、1 つのフィールドのみの違いでほとんど同じである事実がいくつかある場合に備えて、エンジンを強制終了する必要があります。そのような場合、それらの間でひどい量の一致が生成されます。どこが間違っていたのですか?どんな提案でも本当に感謝します。

アップデート。coraxinfo スロットと changeinfo スロットに一度に 1 つの値を追加することで (finalcause) 事実を構築するアプローチを試みている場合、現在これら 2 つのルールで停止しています。

両方のマルチスロットで 1 つの一致する値を使用して、最初の最終原因ファクトを作成します。

(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 をアサートします。私は、このルールは、単純な原因のマッチングにおいて「ギャップを飛び越える」ことができるはずだと信じています。

(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 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 つの一致するフィールドを持つ最終的な原因の事実のみを生成し、その理由がわかりません。この 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 スロットが空の場合、パターンを一致させる唯一の方法と 1 つのアクティベーションしかありません。各スロットに 1 つの値が含まれている場合、各スロットを一致させるには 7 つの異なる方法があります (7 つの変数のそれぞれに 1 つの値があり、残りの変数は空です)。2 つのスロットの間には、パターンを一致させる 49 の異なる方法があることを意味します。

各スロットで 4 つの値に到達すると、1 つのパターンを照合できる 44100 通りの方法があります。つまり、2 番目のパターンを追加すると、比較する必要がある組み合わせは 44,100 * 44,100 になります。これは、1 つのファクトをアサーションするために 1,944,810,000 回の比較を行う必要があり、1 つのスロットに 9 つの値、もう 1 つのスロットに 6 つの値を持つ 1 つを含む 8 つのファクトがあります。

これは、1 つのルールで解決できる問題ではありません。おそらく最良のアプローチは、複数のルールを使用して一度に 1 つの要素の最終原因の事実を構築することです。たとえば、最初に 666 を含む 2 つのファクトがあることを確認し、(finalcause (coraxinfo 666) (changeinfo)) ファクトを作成します。次に、finalcause に存在するすべての値と存在しない追加の値を両方とも持ち、その値を加算する 2 つのファクトがあると判断するルールを作成します。例: (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 に答える