Search code examples
clips

How must be implemented "forall" to loop on every instance of a certain template


My code:

(deftemplate person 

(slot name (type STRING))
(slot age (type STRING))
(multislot title (type STRING))
(slot areaofknowledge (type SYMBOL))
(slot yearTEDtalk (type STRING))

)

(deffacts init

(assert (person 
(name John)
(age 30)
(title Bla bla bla )
(areaofknowledge Bla)
(yearTEDtalk 2020)  
)   
)

(assert (person 
(name Laura)
(age 50)
(title Bla bla bla )
(areaofknowledge Bla)
(yearTEDtalk 2019)  
)   
)

) 

(defrules rules

 (defrule assignpersontotalk
 (forall (person
    (name ?nameTED) 
    (title ?titleTED)
    (year ?yearTED)
    )
    )

 =>
 (assert (TEDtalk-on ?titleTED ?yearTED ?nameTED ))
 )
 )

But seems this is not the rigth way to loop with foreall trough all persons, because im getting: Error

Im not founding the solution on Google, and Clips manual only explains that you have to use foreall (patter1) (pattern2) which is not really helpful.


Solution

  • The forall conditional element requires at least two patterns. It transforms patterns in this form:

    (forall <pattern-1>
            <pattern-2>
                .
                .
                .
            <pattern-n>)
    

    to this form:

    (not (and <pattern-1>
              (not (and <pattern-2>
                            .
                            .
                            .
                        <pattern-n>))))
    

    In any event, you don't have to explicitly iterate over facts matched by a rule:

    CLIPS> 
    (deftemplate person 
       (slot name)
       (slot age)
       (slot title)
       (slot areaofknowledge)
       (slot yearTEDtalk))
    CLIPS> 
    (deffacts init
       (person 
         (name John)
         (age 30)
         (title "Bla bla bla")
         (areaofknowledge Bla)
         (yearTEDtalk 2020))   
       (person 
         (name Laura)
         (age 50)
         (title "Bla bla bla")
         (areaofknowledge Bla)
         (yearTEDtalk 2019)))
    CLIPS> 
    (defrule assignpersontotalk
       (person
          (name ?nameTED) 
          (title ?titleTED)
          (yearTEDtalk ?yearTED))
        =>
        (assert (TEDtalk-on ?titleTED ?yearTED ?nameTED)))
    CLIPS> (watch rules)
    CLIPS> (watch facts)
    CLIPS> (watch activations)
    CLIPS> (reset)
    <== f-0     (initial-fact)
    ==> f-0     (initial-fact)
    ==> f-1     (person (name John) (age 30) (title "Bla bla bla") (areaofknowledge Bla) (yearTEDtalk 2020))
    ==> Activation 0      assignpersontotalk: f-1
    ==> f-2     (person (name Laura) (age 50) (title "Bla bla bla") (areaofknowledge Bla) (yearTEDtalk 2019))
    ==> Activation 0      assignpersontotalk: f-2
    CLIPS> (run)
    FIRE    1 assignpersontotalk: f-2
    ==> f-3     (TEDtalk-on "Bla bla bla" 2019 Laura)
    FIRE    2 assignpersontotalk: f-1
    ==> f-4     (TEDtalk-on "Bla bla bla" 2020 John)
    CLIPS>