0
votes

I am with the following CLIPS programming problem: New family relationship knowledge base. Please apply the following specification:

  • use deftemplate to define the person

  • a person’s attributes are: name, age, sex, children,

  • each attribute should be defined as a slot except children, that are multi slot

  • in sex slot use the (allowed-symbols female male)

  • add data type to each slot

  • use deffacts to add people from diagram

  • define rules:

—mother,

—father,

—sister,

—predecessor

—old — giving the difference in age between predecessor and offspring

This is the code I made:

(deftemplate person
    (slot name (type SYMBOL))
    (slot age (type INTEGER))
    (slot sex (type SYMBOL) (allowed-symbols female male))
    (multislot children (type SYMBOL))
)

(deffacts init
    (person (name Fernando) (age 55) (sex male) (children Jesus Celia))
    (person (name Maria) (age 50) (sex female) (children Jesus Celia))
    (person (name Jesus) (age 25) (sex male))
    (person (name Celia) (age 20) (sex female))
    (person (name Antonio) (age 70) (sex male) (children Fernando Ana))
    (person (name Ana) (age 38) (sex female))
    (person (name Calra) (age 68) (sex female) (children Fernando Ana))
)


(defrule mother
    (person (name ?name) (sex female) (children $?before ?child $?after))


=>
    (assert (mother ?name ?child))
    (printout t ?name " is mother of " $?child crlf))

(defrule father
    (person (name ?name) (sex male) (children $?before ?child $?after))


=>
    (assert (father ?name ?child))
    (printout t ?name " is father of " $?child crlf))


(defrule sister
    (children ?z ?x)
    (children ?z ?y)
    (female ?x)
    (not (test (eq ?x ?y)))
=>
    (assert sister ?x ?y))
    (printout t ?x "is a sister to " ?y crlf))

(defrule predecessor
(or
    (children ?x ?y)
    (and (children ?x ?z)(predecessor ?z ?y))
)
=>
(assert (predecessor ?x ?y)
(printout t ?x "is a predecessor to " ?y crlf))

(defrule old
    ?fact_no <- (person (name ?n) (age ?a1 ?a2))
    (test (<= ?a1 ?a2))

=>
    (assert (result (- ?a1 ?a2)))
    (printout t "There are " ?result " years" crlf))

The mother and father relationship is working but not the rest. It gives me the following ERRORS:

CLIPS> Loading Selection...

[CSTRCPSR4] Cannot redefine deftemplate person while it is in use.

ERROR:
(deftemplate MAIN::person

[CSTRCPSR1] WARNING: Redefining deffacts: init

[CSTRCPSR1] WARNING: Redefining defrule: mother +j+j
Defining defrule: father +j+j

[CSTRCPSR1] WARNING: Redefining defrule: sister 
[PRNTUTIL2] Syntax Error:  Check appropriate syntax for RHS patterns.

ERROR:
(defrule MAIN::sister
   (children ?z ?x)
   (children ?z ?y)
   (female ?x)
   (not (test (eq ?x ?y)))
   =>
   (assert sister
Defining defrule: predecessor 
[EXPRNPSR3] Missing function declaration for defrule.

ERROR:
(defrule MAIN::predecessor
   (or  (children ?x ?y)
        (and (children ?x ?z)
             (predecessor ?z ?y)))
   =>
   (assert (predecessor ?x ?y)
           (printout t ?x "is a predecessor to " ?y crlf))
   (defrule

Thank you so much in advance

1

1 Answers

0
votes

If you already have code loaded, issue a clear command before you try to load the same code a second time. That will remove the [CSTRCPSR4] error message.

You have missing parentheses in the sister and predecessor rules. Correcting these will allow the rules to load without errors.

(defrule sister
    (children ?z ?x)
    (children ?z ?y)
    (female ?x)
    (not (test (eq ?x ?y)))
=>
    (assert (sister ?x ?y))
    (printout t ?x "is a sister to " ?y crlf))

(defrule predecessor
(or
    (children ?x ?y)
    (and (children ?x ?z)(predecessor ?z ?y))
)
=>
(assert (predecessor ?x ?y))
(printout t ?x "is a predecessor to " ?y crlf))

These rules will still not execute with your existing code because they require children and female facts and none of your rules assert these facts.

It's not clear what you're trying to do with your old rule, but since you're trying to match two values in the age slot this rule will generate errors because that slot can only contain one value.