I love clips and am quite comfortable using it to define rules, I want to use it for an upcoming project. However, I need to execute some rules on XML files. I have a bunch of XMLs and I need to extract some outputs, insights from them. I wanted to ask for guidance here, is there any pattern to model objects as clips facts?
Consider this following example:
<families>
<family>
<children>
<boy age="11"/>
<girl age="12"/>
</children>
<parent>
<father age="31"/>
<mother age="29"/>
</parent>
</family>
</families>
How would I translate this to facts in clips, and write a rule that'll output the number of boys whose mother is older than the father?
Thank you,
It would be better to use objects rather than facts since you would be able to take advantage of inheritance, but you can implement this with facts by assigning a name for each fact and use this as a symbolic link to represent the nested structure of the XML:
CLIPS (6.31 6/12/19)
CLIPS>
(deftemplate family
(slot name)
(slot progenitor (default none))
(multislot children)
(multislot parent))
CLIPS>
(deftemplate boy
(slot name)
(slot progenitor (default none))
(slot age))
CLIPS>
(deftemplate girl
(slot name)
(slot progenitor (default none))
(slot age))
CLIPS>
(deftemplate father
(slot name)
(slot progenitor (default none))
(slot age))
CLIPS>
(deftemplate mother
(slot name)
(slot progenitor (default none))
(slot age))
CLIPS>
(deffacts data
(boy-count)
(family (name family-1)
(children boy-1 girl-1)
(parent father-1 mother-1))
(boy (name boy-1)
(progenitor family-1)
(age 11))
(girl (name girl-1)
(progenitor family-1)
(age 13))
(father (name father-1)
(progenitor family-1)
(age 31))
(mother (name mother-1)
(progenitor family-1)
(age 29))
(family (name family-2)
(children boy-2 boy-3)
(parent father-2 mother-2))
(boy (name boy-2)
(progenitor family-2)
(age 14))
(boy (name boy-3)
(progenitor family-2)
(age 16))
(father (name father-2)
(progenitor family-2)
(age 35))
(mother (name mother-2)
(progenitor family-2)
(age 43)))
CLIPS>
(defrule add-boy
(family (name ?family))
(father (age ?fa) (progenitor ?family))
(mother (age ?ma&:(> ?ma ?fa)) (progenitor ?family))
(boy (name ?boy) (progenitor ?family))
?bc <- (boy-count $?names&:(not (member$ ?boy ?names)))
=>
(retract ?bc)
(assert (boy-count ?names ?boy)))
CLIPS>
(defrule print-count
(declare (salience -10))
(boy-count $?names)
=>
(bind ?count (length$ ?names))
(switch ?count
(case 0 then (printout t "There are no boys"))
(case 1 then (printout t "There is 1 boy"))
(default then (printout t "There are " ?count " boys")))
(printout t " with a mother older than a father." crlf))
CLIPS> (reset)
CLIPS> (run)
There are 2 boys with a mother older than a father.
CLIPS>