CLIPS(recursion) - 家庭关系:如何正确实现作为祖先的关系?

CLIPS(recursion) - family relations: how to implement correctly the relation of being an ancestor?

简介

我正在尝试用 CLIPS 语言实现一个规则——一个人是另一个人的祖先的关系。 约束是这样的规则只能从以下前提推导出来:

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

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

(?x?y 的母亲) ("x is a mother of y")

(?x?y 的父亲) ("x is a father of y")

我的尝试

我写了下面的代码:

    (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 ancestor
    (or 

        (mother-of (mother ?x) (child ?w))
        (father-of (father ?x) (child ?w))


        (and
            (mother-of (mother ?x) (child ?y))
            (or
                (mother-of (mother ?y) (child ?w))
                (father-of (father ?y) (child ?w))  
            )
        )

        (and
            (father-of (father ?x) (child ?y))
            (or
                (mother-of (mother ?y) (child ?w))
                (father-of (father ?y) (child ?w))  
            )
        )
    )
    =>
    (printout t ?x " is an ancestor of " ?w crlf) 
    (assert (ancestor ?x ?w))   
)

问题的要点

以上代码编译returns "true"(换句话说,构造的规则在逻辑上是正确的)并在这样的事实列表的情况下输出预期结果。

但是,有一个微妙的问题:

此代码仅适用于确定第一代和第二代祖先

换句话说,它仅在某人是某人的father/mother或某人的grandfather/grandmother的情况下有效,但不适用于检查如果某人是某人的曾曾 grandfather/great 祖母或曾曾曾 grandfather/great 曾曾祖母等

以上代码没有处理这个问题。

如何克服这个问题?

CLIPS> 
(deftemplate father-of 
   (slot father)
   (slot child))
CLIPS> 
(deftemplate mother-of 
   (slot mother)
   (slot child))
CLIPS> 
(deffacts family
   (father-of (father Bob) (child Frank))
   (mother-of (mother Linda) (child Frank))
   (father-of (father Frank) (child John))
   (mother-of (mother Susan) (child John))
   (father-of (father John) (child Mark))
   (mother-of (mother Alice) (child Mark)))
CLIPS> 
(defrule ancestor
   (or (mother-of (mother ?x) (child ?w))
       (father-of (father ?x) (child ?w))
       (and (ancestor ?x ?y)
            (ancestor ?y ?w)))
   (not (ancestor ?x ?w))
   =>
   (printout t ?x " is an ancestor of " ?w crlf) 
   (assert (ancestor ?x ?w)))
CLIPS> (reset)
CLIPS> (run)
Alice is an ancestor of Mark
John is an ancestor of Mark
Susan is an ancestor of John
Susan is an ancestor of Mark
Frank is an ancestor of John
Frank is an ancestor of Mark
Linda is an ancestor of Frank
Linda is an ancestor of Mark
Linda is an ancestor of John
Bob is an ancestor of Frank
Bob is an ancestor of Mark
Bob is an ancestor of John
CLIPS>