Reputation: 63
I have a family tree. I need to find a person's brother-in-law using CLIPS.
Family Tree
Rules to find Brother-In-Law
Rule-1 (to find spouse's brother)
(defrule MAIN::fnd_BrthrsNLaw1 ;spouse's brother
(findRelative (person ?pn) (relationship b_i_lw)) ;Brothers-in-Law
(and
(and (and (or (marriage-between (personA ?pn) (personB ?sp))
(marriage-between (personA ?sp) (personB ?pn))
)
(child-of (relationship ?x) (person ?sp) (mother ?m) (father ?f))
)
(child-of (relationship son-of) (person ?pn2) (mother ?m) (father ?f))
)
(not (marriage-between (personA ?pn) (personB ?pn2)))
)
=>
(printout t ?pn "'s brothers-in-Law: (spouse's brother) " ?pn2 crlf)
)
Rule-2 (to find spouse's sister's husband)
(defrule MAIN::fnd_BrthrsNLaw2 ;spouse's sister's husband
(findRelative (person ?pn) (relationship b_i_lw)) ;Brothers-in-Law
(and
(and
(and
(or
(marriage-between (personA ?pn) (personB ?sp))
(marriage-between (personA ?sp) (personB ?pn))
)
(and
(child-of (relationship ?x) (person ?sp) (mother ?a) (father ?b))
(child-of (relationship daughter-of) (person ?p2) (mother ?a) (father ?b))
)
)
(and
(not (eq ?sp ?p2))
(marriage-between (personA ?p2) (personB ?px2))
)
)
=>
(printout t ?pn "'s brothers-in-Law: (spouse's sister's husband) " ?px2 " <sister = " ?p2 " ; spouse = " ?sp " ; spouse's parents: " ?a " , " ?b ">" crlf)
)
Rule-3 (to find sister's husband)
(defrule MAIN::fnd_BrthrsNLaw3 ;sister's husband
(findRelative (person ?p) (relationship b_i_lw)) ;Brothers-in-Law
(and
(and
(child-of (relationship ?y) (person ?p) (mother ?c) (father ?d))
(child-of (relationship daughter-of) (person ?sist) (mother ?c) (father ?d))
)
(and
(not (eq ?p ?sist))
(marriage-between (personA ?sist) (personB ?p2))
)
)
=>
(printout t ?p "'s brothers-in-Law: (sister's husband) " ?p2 <sister = " ?sist " ; " ?p "'s parent = " ?sp " ; spouse's parents: " ?c " , " ?d ">"crlf)
(reset)
)
Templates
(deftemplate MAIN::marriage-between
(slot personA)
(slot personB))
(deftemplate MAIN::child-of
(slot relationship (type SYMBOL) (allowed-symbols son-of daughter-of))
(slot person)
(slot mother)
(slot father))
(deftemplate MAIN::findRelative
(slot relationship (type SYMBOL)
(allowed-symbols g_g_p ;Great-GrandParents
g_ch ;GrandChildren
b_i_lw)) ;Brothers-in-Law
(slot person))
Now for - 1)Diana, brother-in-law ( or b_i_lw) have to be Andrew, Mark and Edward 2)Mark, b_i_lw's are Andrew, Edward and Charles. 3)Charles, b_i_lw' has to be Mark.
But my outputs are not completely correct as some wrong info is also deduced with the correct ones for rules of spouse's brother's sister (rule named "fnd_BrthrsNLaw2") and sister's husband (rule named "fnd_BrthrsNLaw3").
Output for Mark, Diana and Charles are given below:
Output for searching for Diana:
CLIPS> (assert (findRelative (person Diana) (relationship b_i_lw)))
<Fact-20>
CLIPS> (run)
Diana's brothers-in-Law: (spouse's brother) Edward
Diana's brothers-in-Law: (spouse's brother) Andrew
Diana's brothers-in-Law: (spouse's sister's husband) Mark <sister = Anne ; spouse = Charles ; Charles's parents: Elizabeth , Phillip>
Diana's brothers-in-Law: (sister's husband) Charles <sister = Diana ; Diana's parent: Kydd , Spencer>
Output for searching for Mark:
CLIPS> (assert (findRelative (person Mark) (relationship b_i_lw)))
<Fact-20>
CLIPS> (run)
Mark's brothers-in-Law: (spouse's brother) Edward
Mark's brothers-in-Law: (spouse's brother) Andrew
Mark's brothers-in-Law: (spouse's brother) Charles
Mark's brothers-in-Law: (spouse's sister's husband) Mark <sister = Anne ; spouse = Anne ; Anne's parents: Elizabeth , Phillip>
Output for searching for Charles:
CLIPS> (assert (findRelative (person Charles) (relationship b_i_lw)))
<Fact-20>
CLIPS> (run)
Charles's brothers-in-Law: (spouse's sister's husband) Charles <sister = Diana ; spouse = Diana ; Diana's parents: Kydd , Spencer>
Charles's brothers-in-Law: (sister's husband) Mark <sister = Anne ; Anne's parent: Elizabeth , Phillip>
My assumption is use of (not (eq )) in rule-2 and rule-3 is not affecting the 'and' blocks they are inside, though I have tested that (not (eq )) is giving true when and is not equal and false when they are equal, which I intend to get.
Upvotes: 0
Views: 183
Reputation: 10757
You need to use the test CE to evaluate expressions in the conditions of a rule. For example, instead of
(not (eq ?sp ?p2))
use
(test (not (eq ?sp ?p2)))
or
(test (neq ?sp ?p2))
Your existing rules are attempting to match a fact with relation name eq rather than calling the eq function to compare values.
Also, calling the reset command in the fnd_BrthrsNLaw3 rule actions is something you probably don't want to be doing.
Upvotes: 2