【问题标题】:CLIPS How to find facts based on deftemplate relation slotsCLIPS 如何根据 deftemplate 关系槽查找事实
【发布时间】:2020-01-17 11:41:35
【问题描述】:

我正在使用deftemplates 构建家谱。我使用deffacts family 通过断言人们的母亲和父亲来声明初始事实基础。然后我设置了一堆规则来断言兄弟姐妹,祖父母,堂兄弟等。我想从用户那里得到两个名字,然后根据事实,它会告诉我他们之间的关系是什么。我被这个问题难住了,请帮忙。

我一直在尝试使用find-all-factsfind-fact,但我不知道如何正确使用查询语法。我需要一个循环来遍历每个事实吗?

我正在使用的定义模板:

(deftemplate father-of   (slot father)  (slot child))
(deftemplate mother-of   (slot mother)  (slot child))
(deftemplate parent-of  (slot parent)   (slot child))
(deftemplate sister-of  (slot sister)   (slot sibling))
(deftemplate brother-of (slot brother)  (slot sibling))
(deftemplate aunt-of    (slot aunt)     (slot nephew-or-niece))
(deftemplate uncle-of   (slot uncle)    (slot nephew-or-niece))
(deftemplate cousin-of  (slot cousin-1) (slot cousin-2))
...

最初的事实基础被剪断:

(deffacts family
    ;GreatGrandParents
    (father-of (father "Henry") (child "Bob"))
    (father-of (father "Henry") (child "Susie"))
    (father-of (father "Henry") (child "Anton"))
    (mother-of (mother "Georgette") (child "Bob"))
    ...)

我一直在尝试的:

(defrule get-relationship ""
    =>
    (printout t crlf "Enter a person in the family: ")
    (bind ?p1 (read))
    (printout t crlf "Enter another person in the family: ")
    (bind ?p2 (read))
    (find-all-facts
        ($a?-of ($a? ?p1) ($b? ?p2))               ;any fact that contains both names entered
        ((!= 0 (str-compare ?p1 ?p2))              ;given ?p1 and ?p2 are dissimilar
        (printout t ?p1 "is a" $a? "of" $b? crlf)) ;display the relationship found
)

【问题讨论】:

    标签: clips expert-system


    【解决方案1】:

    使用查询:

             CLIPS (6.31 6/12/19)
    CLIPS> 
    (deftemplate of
       (slot relation)
       (slot p1)
       (slot p2))
    CLIPS> 
    (deffacts family
       (of (relation father) (p1 "Henry") (p2 "Bob"))
       (of (relation father) (p1 "Henry") (p2 "Susie"))
       (of (relation father) (p1 "Henry") (p2 "Anton"))
       (of (relation mother) (p1 "Georgette") (p2 "Bob")))
    CLIPS>    
    (defrule get-relationship ""
        =>
        (printout t "Enter a person in the family: ")
        (bind ?p1 (readline))
        (printout t "Enter another person in the family: ")
        (bind ?p2 (readline))
        (do-for-all-facts ((?o of)) 
           (and (eq ?p1 ?o:p1)
                (eq ?p2 ?o:p2))
           (printout t ?p1 " is a " ?o:relation " of " ?p2 crlf)))
    CLIPS> (reset)
    CLIPS> (run)
    Enter a person in the family: Henry
    Enter another person in the family: Susie
    Henry is a father of Susie
    CLIPS>
    

    使用模式:

    CLIPS> (clear)
    CLIPS> 
    (deftemplate of
       (slot relation)
       (slot p1)
       (slot p2))
    CLIPS> 
    (deftemplate find
       (slot p1)
       (slot p2))
    CLIPS>   
    (deffacts family
       (of (relation father) (p1 "Henry") (p2 "Bob"))
       (of (relation father) (p1 "Henry") (p2 "Susie"))
       (of (relation father) (p1 "Henry") (p2 "Anton"))
       (of (relation mother) (p1 "Georgette") (p2 "Bob")))
    CLIPS>    
    (defrule get-find ""
        =>
        (printout t "Enter a person in the family: ")
        (bind ?p1 (readline))
        (printout t "Enter another person in the family: ")
        (bind ?p2 (readline))
        (assert (find (p1 ?p1) (p2 ?p2))))
    CLIPS>     
    (defrule get-relationship
       (find (p1 ?p1) (p2 ?p2))
       (of (relation ?relation) (p1 ?p1) (p2 ?p2))
       =>
       (printout t ?p1 " is a " ?relation " of " ?p2 crlf)))
    CLIPS> 
    (defrule done-find ""
        (declare (salience -10))
        ?f <- (find)
        =>
        (retract ?f))
    CLIPS> (reset)
    CLIPS> (run)
    Enter a person in the family: Georgette
    Enter another person in the family: Bob
    Georgette is a mother of Bob
    CLIPS>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-15
      • 2014-07-09
      相关资源
      最近更新 更多