私は CLIPS で「事実の一般化」のようなことをしようとしています (どの用語がそれを最もよく表しているかわかりません) が、これを最善の方法で行う方法がわかりません。
そのような状況を考慮してください。以下のテンプレートで記述された一連の事実があります。
(deftemplate MAIN::simplecause
(slot coraxidcause (type INTEGER) (default 0))
(slot changeidcause (type SYMBOL) (default PF1))
(multislot coraxinfo (type SYMBOL) (default undefined))
(multislot changeinfo (type SYMBOL) (default undefined)))
(deftemplate MAIN::finalcause
(multislot coraxinfo (type SYMBOL) (default undefined))
(multislot changeinfo (type SYMBOL) (default undefined))
(slot casecount (type INTEGER) (default 0)))
Coraxidcause と changeidcause の組み合わせは一種のキーです。これら 2 つのフィールドの組み合わせは一意です。changeinfo と coraxinfo には、スロットにいくつかの記号値があります (これらの各スロットには、常に 10 個を超える値はありません)。
だから私はいくつかの単純な原因の事実を持っています。私がやりたいことは、changeinfo と coraxinfo で同じ値を見つけてアサートすることです。たとえば、これらの単純な原因の事実がある場合:
(simplecause (coraxidcause id1) (changeidcause id1) (coraxinfo 1 2 3) (changeinfo a b c))
(simplecause (coraxidcause id2) (changeidcause id2) (coraxinfo 2 3 6 7) (changeinfo e a b d f))
(simplecause (coraxidcause id3) (changeidcause id3) (coraxinfo 9 11 2 3 0) (changeinfo g a b))
(simplecause (coraxidcause id4) (changeidcause id4) (coraxinfo 77) (changeinfo z))
私はそのような事実を主張したい:
(finalcause (coraxinfo 2 3) (changeinfo a b))
今のところ、私はこのルールを書きました:
(defrule MAIN::cause_generalization_initial
(simplecause (coraxidcause ?coraxid1) (changeidcause ?factid1) (coraxinfo $? $?coraxdetails $?) (changeinfo $? $?changedetails $?))
(simplecause (coraxidcause ?coraxid2) (changeidcause ?factid2) (coraxinfo $? $?coraxdetails $?) (changeinfo $? $?changedetails $?))
(or (test (<> ?coraxid1 ?coraxid2))
(neq ?factid1 ?factid2))
(not (finalcause (coraxinfo $?coraxdetails) (changeinfo $?changeddetails)))
=>
(assert (finalcause (coraxinfo ?coraxdetails) (changeinfo ?changedetails) (casecount 0))))
問題は、前述の 4 つの事実に戻ると、次のように主張されることです。
(finalcause (coraxinfo 2) (changeinfo a))
(finalcause (coraxinfo 3) (changeinfo a))
(finalcause (coraxinfo 2 3) (changeinfo b))
等
これらすべての「部分一致」は必要ありません。完全に一致する部分 (finalcause (coraxinfo 2 3) (changeinfo ab)) が必要なだけですが、その方法がわかりません。さらに、次のようなことがあると、本当に恐ろしいことが起こります。
(simplecause (coraxidcause id5) (changeidcause id5) (coraxinfo 0 1 2 3) (changeidcause a b c))
(simplecause (coraxidcause id6) (changeidcause id6) (coraxinfo 6 1 2 3) (changeidcause a b c))
この時点で、CLIPS エンジンは無限ループのようになり、LHS はすべての可能な一致を一覧表示します。
(finalcause (coraxinfo 1) (changeidcause a))
(finalcause (coraxinfo 1) (changeidcause a b))
等
それには何年もかかります(そして、前に述べたように、まだ必要のないことをしています)。私は CLIPS の初心者なので、明らかな何かを見逃していると思います。必要なことを行う方法がいくつかあるはずです。これを行う方法についての助けや提案をいただければ幸いです。どんなアイデアも本当に役に立ちます。
私は自分が何を望んでいるのかを明確にしていないようです。たとえば、次の事実がある場合、すべての事実にわたって可能なすべての「一致」を見つける必要があります。
(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) (changeinfo abc def)))
これを出力として取得する必要があります:
(finalcause (coraxinfo 2 3) (changeinfo a b))
(finalcause 88 99) (changeinfo k m))