0
votes

Introduction

I am trying to implement a rule in CLIPS language - the relation that a person is a brother of other person. The constraint is that such rule must be derived only from the following premises:

(male ?x) ("x is a female")

(female ?y) ("y is a female")

(mother-of ?x ?y) ("x is a mother of y")

(father-of ?x ?y) ("x is a father of y")

My attempt

I wrote the following code:

(deftemplate father-of 
    (slot father)
    (slot child)
)

(deftemplate mother-of 
    (slot mother)
    (slot child)
)

(deftemplate male 
    (slot person)
)

(deftemplate female
     (slot person)
)

(deffacts family
    (father-of (father John) (child Mark))
    (father-of (father John) (child Mary))
    (mother-of (mother Alice) (child Mark))
    (mother-of (mother Alice) (child Mary))
    (male (person John))
    (male (person Mark))
    (female (person Alice))
    (female (person Mary))
)

(defrule brother
    (and
        (male (person ?alpha))
        (mother-of (mother ?x) (child ?alpha))
        (father-of (father ?y) (child ?alpha))
        (mother-of (mother ?x) (child ?beta))
        (father-of (father ?y) (child ?beta))
    )
    =>
    (printout t ?alpha " is a brother of " ?beta crlf)
    (assert (brother ?alpha ?beta))
)

The gist of the problem

The above code compiles and returns "true"(in other words, the construced rule is logically correct).

However, there is a subtle problem:

How to avoid the problem of adding a fact that e.g. "Mark is a brother of Mark" (we assume that each name is unique, so the same name correspondes to the same person)? Obviously, such fact is false, but my rule outputs such stupidity.

The above code does not handle this issue.

How to overcome this problem?

Acknowledgements

I would be thankful for help in this issue!!!

2

2 Answers

1
votes

Change the constraint ?beta in the second mother-of pattern to ?beta&~?alpha.

(defrule brother
    (and
        (male (person ?alpha))
        (mother-of (mother ?x) (child ?alpha))
        (father-of (father ?y) (child ?alpha))
        (mother-of (mother ?x) (child ?beta&~?alpha))
        (father-of (father ?y) (child ?beta))
    )
    =>
    (printout t ?alpha " is a brother of " ?beta crlf)
    (assert (brother ?alpha ?beta))
)
0
votes

Here is my independent solution:

(defrule brother
    (and
        (male (person ?alpha))

        (or
             (male (person ?beta))
             (female (person ?beta))
         )

        (mother-of (mother ?x) (child ?alpha))
        (father-of (father ?y) (child ?alpha))
        (mother-of (mother ?x) (child ?beta))
        (father-of (father ?y) (child ?beta))
        (test (neq ?alpha ?beta))
    )
    =>
    (printout t ?alpha " is a brother of " ?beta crlf)
    (assert (brother ?alpha ?beta))
)