2015-10-29 35 views
0

這是我的程序的代碼,以人的性別明智和聰明的年齡排序。我得到的輸出,但不是預期的。如何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

男性40b的

女25℃

女50 d」

什麼改變我必須使輸出成爲一個列表並對其進行排序?謝謝。

回答

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)) 

斷言某人( 「deffacts人」)不MAK電子感覺。

刪除第一個defrule的FindFirst - 還有另外一個名稱相同。

你需要一個規則來定義一個人:

 
(defrule define-person 
    ?gf 
    (retract ?gf ?af ?nf) 
    (assert (person (age ?age)(name ?name)(gender ?gender))) 
    (ask-start-again)) 

規則的人老/ yound,男/女是沒有用的 - 他們只是收回早前收集到的數據。而且,所有人都無法打印排序的事實;在規則findFirst(第二個版本)中添加一個類似的打印輸出函數調用。

+0

您好,感謝您的幫助。我已經提出了改變,我沒有錯誤,但仍然得到相同的輸出。沒有改變。還有什麼我需要添加或我缺少什麼?謝謝 –