I guess I'm more than a little confused as to the "(templates $? ?t $?)" syntax. I would have expected that I could have rewritten the rule Wolfgang provided to:
(defrule makeTransforms ?s <- (source (id ?id) (templates $? ?template $?)) (not (transform (source ?id))) => (assert (transform (source ?id) (template ?template))) ) However, when I assert the source: (assert (source (id 1) (templates (create$ a b c)))) I only see one transform asserted: ==> f-1 (MAIN::transform (source 1) (template a)) Even if I create the source with just one element and repeatedly modify the asserted source's template by adding to the list, I see only one transform asserted. Very confusing. Worse however, regardless of whether I use the original makeTransform rule that Wolfgang proposed or the rewrite I did above, if I combine the makeTransforms and your removeTransforms, I end up in a system which goes into an endless loop from simply asserting one source. Here's the full test: (watch all) (deftemplate source (slot id) (multislot templates)) (deftemplate transform (slot source) (slot template)) (defrule makeTransforms ?s <- (source (id ?id)(templates $?templates)) (not (transform (source ?id))) => (foreach ?temp $?templates (assert (transform (source ?id) (template ?temp)))) ) (defrule removeTransforms ?t <- (transform (source ?id) (template ?t)) (not (source (id ?id)(templates $? ?t $?))) => (retract ?t) ) (bind ?source (assert (source (id 1) (templates (create$ a b c))))) (run-until-halt) Results in: MAIN::makeTransforms: +1+1+1+1+2+t MAIN::removeTransforms: =1+1=1+1+2+t ==> f-0 (MAIN::source (id 1) (templates a b c)) ==> Activation: MAIN::makeTransforms : f-0, FIRE 1 MAIN::makeTransforms f-0, ==> f-1 (MAIN::transform (source 1) (template a)) ==> Activation: MAIN::removeTransforms : f-1, ==> f-2 (MAIN::transform (source 1) (template b)) ==> Activation: MAIN::removeTransforms : f-2, ==> f-3 (MAIN::transform (source 1) (template c)) ==> Activation: MAIN::removeTransforms : f-3, FIRE 2 MAIN::removeTransforms f-3, <== f-3 (MAIN::transform (source 1) (template c)) FIRE 3 MAIN::removeTransforms f-2, <== f-2 (MAIN::transform (source 1) (template b)) FIRE 4 MAIN::removeTransforms f-1, <== f-1 (MAIN::transform (source 1) (template a)) ==> Activation: MAIN::makeTransforms : f-0, FIRE 5 MAIN::makeTransforms f-0, ==> f-4 (MAIN::transform (source 1) (template a)) ==> Activation: MAIN::removeTransforms : f-4, ==> f-5 (MAIN::transform (source 1) (template b)) ==> Activation: MAIN::removeTransforms : f-5, ==> f-6 (MAIN::transform (source 1) (template c)) ==> Activation: MAIN::removeTransforms : f-6, FIRE 6 MAIN::removeTransforms f-6, <== f-6 (MAIN::transform (source 1) (template c)) FIRE 7 MAIN::removeTransforms f-5, <== f-5 (MAIN::transform (source 1) (template b)) FIRE 8 MAIN::removeTransforms f-4, <== f-4 (MAIN::transform (source 1) (template a)) ==> Activation: MAIN::makeTransforms : f-0, And this continues forever. On 9/7/07 9:11 AM, "Ernest Friedman-Hill" <[EMAIL PROTECTED]> wrote: > Same idea: > > (defrule removeTransforms > ?t <- (transform (source ?id) (template ?t)) > (not (source (id ?id)(templates $? ?t $?)) > => > (retract ?t)) > > > On Sep 7, 2007, at 11:57 AM, Hal Hildebrand wrote: > >> Doh! That does work well and I'll certainly replace my cheesy >> solution with >> this, but one of the issues I'm dealing with is that the set of >> templates >> can change and I would like to ensure that as changes to the list of >> templates occur, the corresponding transforms are asserted or >> retracted. >> Sorry, this is an additional constraint I would like to satisfy that I >> should have noted. >> >> >> On 9/7/07 8:28 AM, "Wolfgang Laun" <[EMAIL PROTECTED]> >> wrote: >> >>> Assuming that the absence of any "transform" fact with a "source" >>> slot >>> equal to the "id" slot of a new "source" fact is the criterion for >>> creating the "transform" facts: >>> >>> (defrule makeTransforms >>> ?s <- (source (id ?id)(templates $?templates)) >>> (not (transform (source ?id))) >>> => >>> (foreach ?temp $?templates >>> (assert (transform (source ?id) (template ?temp)))) >>> ) >>> >>> kr >>> Wolfgang >>> >>> Hal Hildebrand wrote: >>> >>>> I have a system where I need to ensure that for every member of a >>>> list, >>>> there is a fact which contains that member. For example, here's >>>> my domain: >>>> >>>> >>>> (deftemplate source (slot id) (multislot templates)) >>>> (deftemplate transform (slot source) (slot template)) >>>> >>>> >>>> What I would like is to write some rules that ensure that for >>>> ever member of >>>> the templates slot of a "source", I have a corresponding >>>> transform. If I >>>> assert: >>>> >>>> (assert source (id 1) (templates (create$ a b c))) >>>> >>>> I would like to see three facts asserted in response: >>>> >>>> (assert transform (source 1) (template a)) >>>> (assert transform (source 1) (template b)) >>>> (assert transform (source 1) (template c)) >>>> >>>> >>>> I have accomplished this by creating an intermediary fact and >>>> some rules >>>> which essentially cycle through the list of templates in the source, >>>> asserting a transform for each. However, this just feels wrong. >>>> It seems >>>> like I should be able to express this without the intermediary >>>> facts. >>>> >>>> Perhaps this is where backward chaining would be useful? Or >>>> perhaps I can >>>> use the new "accumulate" CE? Or, have I already found the >>>> solution using an >>>> intermediary fact to cycle through the list of templates? >>>> >>>> Any help/suggestions would be appreciated. >>>> >>>> >>>> >>>> -------------------------------------------------------------------- >>>> To unsubscribe, send the words 'unsubscribe jess-users >>>> [EMAIL PROTECTED]' >>>> in the BODY of a message to [EMAIL PROTECTED], NOT to the list >>>> (use your own address!) List problems? Notify owner-jess- >>>> [EMAIL PROTECTED] >>>> -------------------------------------------------------------------- >>>> >>>> >>>> >>> >>> -------------------------------------------------------------------- >>> To unsubscribe, send the words 'unsubscribe jess-users >>> [EMAIL PROTECTED]' >>> in the BODY of a message to [EMAIL PROTECTED], NOT to the list >>> (use your own address!) List problems? Notify owner-jess- >>> [EMAIL PROTECTED] >>> -------------------------------------------------------------------- >>> >> >> >> -------------------------------------------------------------------- >> To unsubscribe, send the words 'unsubscribe jess-users >> [EMAIL PROTECTED]' >> in the BODY of a message to [EMAIL PROTECTED], NOT to the list >> (use your own address!) List problems? Notify owner-jess- >> [EMAIL PROTECTED] >> -------------------------------------------------------------------- > > --------------------------------------------------------- > Ernest Friedman-Hill > Advanced Software Research Phone: (925) 294-2154 > Sandia National Labs FAX: (925) 294-2234 > PO Box 969, MS 9012 [EMAIL PROTECTED] > Livermore, CA 94550 http://www.jessrules.com > > -------------------------------------------------------------------- > To unsubscribe, send the words 'unsubscribe jess-users [EMAIL PROTECTED]' > in the BODY of a message to [EMAIL PROTECTED], NOT to the list > (use your own address!) List problems? Notify [EMAIL PROTECTED] > -------------------------------------------------------------------- > -------------------------------------------------------------------- To unsubscribe, send the words 'unsubscribe jess-users [EMAIL PROTECTED]' in the BODY of a message to [EMAIL PROTECTED], NOT to the list (use your own address!) List problems? Notify [EMAIL PROTECTED] --------------------------------------------------------------------