I am trying to do something like 'facts generalization' in CLIPS (not sure which term describes it best of all) and I am not sure how to do this in a best way.
Consider such situation. I have a set of facts which are described by the below templates:
(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 and changeidcause combination is a kind of key - combination of these 2 fields is unique. changeinfo and coraxinfo have some symbolic values in slots (I always have not more than 10 values in each of these slots)
So I have some simplecause facts. What I want to do is to find which values are same in changeinfo and coraxinfo and assert them. For instance if I have these simplecause facts:
(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))
I want to assert such fact:
(finalcause (coraxinfo 2 3) (changeinfo a b))
For now I have written this rule:
(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))))
The issue is that if we get back to those 4 facts mentioned earlier it asserts this:
(finalcause (coraxinfo 2) (changeinfo a))
(finalcause (coraxinfo 3) (changeinfo a))
(finalcause (coraxinfo 2 3) (changeinfo b))
etc.
I don't need all these 'partial matches', I just need the fully matching part - (finalcause (coraxinfo 2 3) (changeinfo a b)), and I am not sure how to this. Moreover, a really terrible things happen when I have something like this:
(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))
At this moment CLIPS engine goes into smth like an infinite loop, LHS lists every possible match:
(finalcause (coraxinfo 1) (changeidcause a))
(finalcause (coraxinfo 1) (changeidcause a b))
etc.
That takes ages (and still does the thing I don't need, as I mentioned before). I am a newbie in CLIPS so I assume that I miss something obvious, there should be some way to do what I need. I will appreciate any help or suggestions on how to do this. Any ideas will be really useful.
Looks like I haven't clarified what exactly I want. I need to find all possible 'matches' accross all of the facts, for instance, if I have these facts:
(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)))
I would need to get this as output:
(finalcause (coraxinfo 2 3) (changeinfo a b))
(finalcause 88 99) (changeinfo k m))