Search code examples
clipsfuzzy-logic

Order rules execution without using declare salience


Well thats the question, imagine i have 2 rules. The second rule depends on the first rule. For example:

 (deftemplate person 
(slot name (type STRING))
(slot age (type STRING))
)

(deffacts start
 (person(name "Mike")(age "20"))
 (person(name "Laura")(age "22"))
 (person(name "Dean")(age "22"))
 (person(name "Charlie")(age "22"))
 )

 (defrule filterage
 (person (name ?n)(age ?a))
 (test (eq ?a "22"))
 =>
 (assert (is-equal-to-22 ?n))
 )

 (defrule creategroup
 (is-equal-to-22 ?c)
 =>
 (assert (is-in-22-years-old-group ?c))
 )

And as expected the second rule fires any time it has something from rule 1.

enter image description here

So, how can i make the second rule wait till all persons are created, without using declare salience


Solution

  •          CLIPS (6.31 2/3/18)
    CLIPS> (defmodule MAIN (export ?ALL))
    CLIPS> (defmodule FILTER (import MAIN ?ALL))
    CLIPS> (defmodule CREATE (import MAIN ?ALL))
    CLIPS> 
    (deftemplate MAIN::av ; attribute value
      (slot a)
      (slot v))
    CLIPS>   
    (deftemplate MAIN::person 
      (slot name)
      (slot age))
    CLIPS> 
    (deffacts MAIN::start
      (person (name "Mike") (age 20))
      (person (name "Laura") (age 22))
      (person (name "Dean") (age 22))
      (person (name "Charlie") (age 22)))
    CLIPS>   
    (defrule MAIN::start
      =>
      (focus FILTER CREATE))
    CLIPS> 
    (defrule FILTER::filterage
      (person (name ?n) (age 22))
      =>
      (assert (av (a is-equal-to-22) (v ?n))))
    CLIPS> 
    (defrule CREATE::creategroup
      (av (a is-equal-to-22) (v ?c))
      =>
      (assert (av (a is-in-22-years-old-group) (v ?c))))
    CLIPS> (watch rules)
    CLIPS> (reset)
    CLIPS> (run)  
    FIRE    1 start: *
    FIRE    2 filterage: f-4
    FIRE    3 filterage: f-3
    FIRE    4 filterage: f-2
    FIRE    5 creategroup: f-7
    FIRE    6 creategroup: f-6
    FIRE    7 creategroup: f-5
    CLIPS>