CLIPS 如何根据 detemplate 关系槽查找事实
CLIPS How to find facts based on deftemplate relation slots
我正在使用 deftemplates
构建家谱。我通过断言人们的母亲和父亲使用 deffacts family
声明初始事实基础。然后我设置了一堆规则来断言兄弟姐妹、祖父母、堂兄弟姐妹等。我想从用户那里得到两个名字,然后根据事实告诉我他们之间的关系是什么。我对这个问题很困惑,请帮忙。
我一直在尝试使用 find-all-facts
、find-fact
,但我不知道如何正确使用查询语法。我需要一个循环来遍历每个事实吗?
我正在使用的 deftemplates:
(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 (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>
我正在使用 deftemplates
构建家谱。我通过断言人们的母亲和父亲使用 deffacts family
声明初始事实基础。然后我设置了一堆规则来断言兄弟姐妹、祖父母、堂兄弟姐妹等。我想从用户那里得到两个名字,然后根据事实告诉我他们之间的关系是什么。我对这个问题很困惑,请帮忙。
我一直在尝试使用 find-all-facts
、find-fact
,但我不知道如何正确使用查询语法。我需要一个循环来遍历每个事实吗?
我正在使用的 deftemplates:
(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 (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>