【问题标题】:How to sort people in JESS?如何在 JESS 中对人进行排序?
【发布时间】:2015-10-30 23:52:56
【问题描述】:

这是我的程序代码,用于按性别和年龄对人进行分类。我得到了输出,但没有达到预期。

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

女性 50 d"

我必须进行哪些更改才能将输出作为列表进行排序?谢谢。

【问题讨论】:

    标签: jess


    【解决方案1】:

    一次断言一个阶段:

    (deffacts 初始阶段(阶段选择性别))

    并确保在所有输入后断言排序阶段:

    (deffunction ask-start-again () (打印输出 t“输入另一个人?(y/n)”) (如果(eq(读取)y)那么 (断言(阶段选择-性别)) 别的 (assert (phase sort-persons))))

    使用正确的语法定义模板

    (deftemplate person (slot 性别) (slot age) (slot name))

    断言一个人(“deffacts person”)没有意义。

    删除第一个 defrule findFirst - 还有另一个同名的。

    你需要一个规则来定义一个人:

    (defrule 定义人 ?gf (收回 ?gf ?af ?nf) (assert (person (age ?age)(name ?name)(gender ?gender))) (重新开始))

    人老/年轻男性/女性的规则没有用 - 他们只是收回之前收集的数据。此外, print-all-persons 无助于打印排序后的事实。在规则 findFirst(第二版)中添加类似的打印输出函数调用。

    【讨论】:

    • 您好,感谢您的帮助。我已经做出了建议的更改,我没有错误,但我仍然得到相同的输出。没有改变。还有什么我需要添加的还是我遗漏了什么?谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-25
    • 2017-03-22
    • 1970-01-01
    • 2015-04-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多