Клипы (рекурсия) - семейные отношения: как правильно реализовать отношение предка? - PullRequest
0 голосов
/ 26 октября 2018

Введение

Я пытаюсь реализовать правило на языке CLIPS - отношение, согласно которому человек является предком другого человека.Ограничение состоит в том, что такое правило должно быть получено только из следующих предпосылок:

(мужчина? X) ("x - мужчина")

(женщина? Y) ("y - это мужчина"женщина ")

(мать? x? y) (" x - мать y ")

(отец? x? y) (" x - отец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))   
)

Суть проблемы

Приведенный выше код компилирует и возвращает «true» (другими словами, построенное правило логически верно) и выдает ожидаемые результаты в случае такого списка фактов.

Однако , есть тонкая проблема:

Этот код работает для определения предков первого и второго поколения только .

Другими словами, это работает только в том случае, если кто-то является отцом / матерью кого-то или дедушкой / бабушкой кого-то, , но не для проверки, является ли кто-то прадедом /прабабушка или прапрадедушка / прапрабабушка кого-то и т. д.

Приведенный выше код не решает эту проблему.

Как преодолеть эту проблему?

1 Ответ

0 голосов
/ 27 октября 2018
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> 
...