Search code examples
clips

How to quickly reassert a fact with multiple fields using a single variable in CLIPS


Let's say I have this template:

(deftemplate TRIP::trip
   (multislot resort-sequence)
   (multislot place-sequence)
   (multislot days-distribution))

and this rule:

(defrule test
    ?p <- (trip (days-distribution $?days))
    =>
    ;change value of ?days

Now, since ?p has 3 fields what I'm wondering is: Is it possible to reassert the facts ?p without having to bind separatly all the fields?

Something like this: (assert (trip ?p (days-distribution $?days)))

Edit: To Clarify, from one trip-fact I need to create multiple ones so I cannot modify the first


Solution

  • You can use the modify function but you need to pay attention to looping rules. Your rule above, once fired, would loop indefinitely as a newly modified trip fact would activate the rule over and over again.

    In [1]: (deftemplate trip 
          :   (multislot resort-sequence) 
          :   (multislot place-sequence) 
          :   (multislot days-distribution))                                                                                                                                                                    
    
    In [2]: (defrule test 
          :   ?loop-prevention <- (new-trip) 
          :   ?p <- (trip (days-distribution $?days)) 
          :   => 
          :   (retract ?loop-prevention) 
          :   (modify ?p (days-distribution 1 2 3)))                                                                                                                                                  
    
    In [3]: (assert (trip (resort-sequence a b c) (place-sequence d e f) (days-distribution 22 23 24)))                                                                                     
    (trip (resort-sequence a b c) (place-sequence d e f) (days-distribution 22 23 24))
    
    In [4]: (assert (new-trip))                                                                                                                                                                                 
    (new-trip)
    
    In [5]: (facts)                                                                                                                                                                                             
    f-0     (initial-fact)
    f-1     (trip (resort-sequence a b c) (place-sequence d e f) (days-distribution 22 23 24))
    f-2     (new-trip)
    For a total of 3 facts.
    
    In [6]: (agenda)                                                                                                                                                                                            
    0      test: f-2,f-1
    For a total of 1 activation.
    
    In [7]: (run)                                                                                                                                                                                               
    
    In [8]: (facts)                                                                                                                                                                                             
    f-0     (initial-fact)
    f-3     (trip (resort-sequence a b c) (place-sequence d e f) (days-distribution 1 2 3))
    For a total of 2 facts.