这是我的计划的代码,用于对性别明智和年龄明智的人进行排序。我得到的输出但不是预期的。
(deffacts initial-phase
(phase choose-gender)
(phase choose-age)
(phase choose-name))
(deffacts person (gender) (age) (name))
(deffunction ask-start-again ()
(printout t "Enter another person? (y/n) ")
(if (eq (read) y) then
(assert (phase choose-gender)
(phase choose-age)
(phase choose-name))))
(deffunction comparePerson(?pa ?pb $?comp)
(if (< ((nth$ 1 $?comp) ?pa ?pb) 0) then (return -1))
(if (> ((nth$ 1 $?comp) ?pa ?pb) 0) then (return 1))
(if (= (length$ $?comp) 1) then (return 0))
(return (comparePerson ?pa ?pb (rest$ $?comp))))
;RULES
(defrule gender-select
(phase choose-gender)
=>
(printout t "what is your gender (Male: m "
"Female: f)? ")
(assert (gender-select (read))))
(defrule good-gender-choice
?phase <- (phase choose-gender)
?choice <- (gender-select ?gender&:(or (eq ?gender m) (eq ?gender f)))
=>
(retract ?phase ?choice)
(assert (gender ?gender))
(assert (phase select-age)))
(defrule bad-gender-choice
?phase <- (phase choose-gender)
?choice <- (gender-select ?player&~m&~f)
=>
(retract ?phase ?choice)
(assert (phase choose-gender))
(printout t "Choose m or f." crlf))
(defrule age-select
(phase select-age)
=>
(printout t "What is your age? ")
(assert (age-select (read))))
(defrule good-age-choice
?phase <- (phase select-age)
?choice <- (age-select ?age&:(integerp ?age)
&:(> ?age 0))
=>
(retract ?phase ?choice)
(assert (age ?age))
(assert (phase select-name)))
(defrule bad-age-choice
?phase <- (phase select-age)
?choice <- (age-select ?age&:(or (not (integerp ?age))
(<= ?age 0)))
=>
(retract ?phase ?choice)
(assert (phase select-age))
(printout t "Choose an integer greater than zero."
crlf))
(defrule name-select
(phase select-name)
=>
(printout t "What is your name? ")
(assert (name-select (read))))
(defrule good-name-choice
?phase <- (phase select-name)
?choice <- (name-select ?name&:(or (not (integerp ?name))))
=>
(retract ?phase ?choice)
(assert (name ?name)))
(defrule bad-name-choice
?phase <- (phase select-name)
?choice <- (name-select ?name&:(integerp ?name))
=>
(retract ?phase ?choice)
(assert (phase select-name))
(printout t "Please enter a name."
crlf))
(defrule person-old-female
?gender <- (gender f)
?age <- (age ?b&:(> ?b 35))
=>
(printout t "Person is female & older. This Person must go first!" crlf)
(retract ?gender)
(retract ?age)
(ask-start-again))
(defrule person-young-female
?gender <- (gender f)
?age <- (age ?age&:(<= ?age 35))
=>
(printout t "Person is female & younger. This Person must go after older males!" crlf)
(retract ?gender)
(retract ?age)
(ask-start-again))
(defrule person-old-male
?gender <- (gender m)
?age <- (age ?a&:(> ?a 35))
=>
(printout t "Person is male & older. This Person must go after older females!" crlf)
(retract ?gender)
(retract ?age)
(ask-start-again))
(defrule person-young-male
?gender <- (gender m)
?age <- (age ?age&:(<= ?age 35))
=>
(printout t "Person is male & younger. This Person must go after younger females!" crlf)
(retract ?gender)
(retract ?age)
(ask-start-again))
(defrule print-solution
=>
(printout t "Name Age Gender" crlf)
(printout t "--------------------------------------" crlf))
(defrule print-all-persons
(declare (salience -1000))
(person (name ?name) (age ?age) (gender ?gender))
=>
(printout t ?name ?age ?gender crlf))
(defrule findFirst
?p1 <- (person)
(not (and ?p2 <- (person)
(test (< (comparePerson ?p2 ?p1) 0))))
=>
(retract ?p1))
(defrule findFirst
?phase <- (phase sort-persons)
?p1 <- (person)
(not (and ?p2 <- (person)
(test (< (comparePerson ?p2 ?p1 ?*compAge* ?*compGender*) 0))))
=>
(printout t (fact-slot-value ?p1 name) " selected" crlf)
(retract ?p1))
(defglobal ?*compAge* =
(lambda (?pa ?pb)
(- (fact-slot-value ?pb age) (fact-slot-value ?pa age) )))
(defglobal ?*compGender* =
(lambda (?pa ?pb)
(- (asc (fact-slot-value ?pa gender))
(asc (fact-slot-value ?pb gender)))))
(reset)
(run)
这是output它不会将输出显示为人员列表。我不知道我错过了什么。
是否可以获得类似
的输出“男性30岁
男性40 b
女性25岁女性50 d“
我需要做些什么更改才能将输出作为列表并对其进行排序?谢谢。
答案 0 :(得分:0)
一次断言一个阶段:
(deffacts initial-phase (phase choose-gender))
并确保在所有输入后断言排序阶段:
(deffunction ask-start-again () (printout t "Enter another person? (y/n) ") (if (eq (read) y) then (assert (phase choose-gender)) else (assert (phase sort-persons))))
使用正确的语法来定义模板:
(deftemplate person (slot gender) (slot age) (slot name))
断言一个人(&#34; deffacts person&#34;)没有意义。
删除第一个defrule findFirst - 还有另一个具有相同名称的规则。
您需要一个规则来定义一个人:
(defrule define-person ?gf (retract ?gf ?af ?nf) (assert (person (age ?age)(name ?name)(gender ?gender))) (ask-start-again))
规则老人/男性/男性/女性并不实用 - 他们只是收回先前收集的数据。此外,印刷所有人并不帮助打印分类的事实;在规则findFirst(第二版)中添加类似的打印输出函数调用。