如何对JESS的人进行排序?

时间:2015-10-29 15:13:27

标签: jess

这是我的计划的代码,用于对性别明智和年龄明智的人进行排序。我得到的输出但不是预期的。

(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“

我需要做些什么更改才能将输出作为列表并对其进行排序?谢谢。

1 个答案:

答案 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(第二版)中添加类似的打印输出函数调用。