CLIPS中用户输入的比较运算符使用问题及调试求助
CLIPS程序问题求助
问题描述
- 作为CLIPS初学者,编写程序用于返回与用户人口统计信息最匹配的公司名称。将用户性别、种族、年龄分别存入对应变量,但使用比较运算符判断时出错:规则中的
(= 1 input)语句提示"Function '=' expected argument #2 to be of type integer or float",尽管已限制用户仅输入整数。 - 简化代码后仍无法访问历史用户输入,请求技术帮助。
原代码
(deftemplate company (slot name) (slot men) (slot women) (slot Asian) (slot Black) (slot Latinx) (slot Indigenous) (slot White) (slot Other) (slot <18) (slot 18-20) (slot 21-29) (slot 30-39) (slot 40+)) (deffacts demographics (company (name Google)(men 0.669)(women 0.331)(Asian 0.428)(Black 0.088)(Latinx 0.088)(Indigenous 0.007)(White 0.445)(Other 0)(<18 0.02)(18-20 0.11)(21-29 0.59)(30-39 0.19)(40+ 0.07)) (company (name Apple)(men 0.652)(women 0.348)(Asian 0.279)(Black 0.094)(Latinx 0.148)(Indigenous 0.007)(White 0.438)(Other 0.032)(<18 0.01)(18-20 0.1)(21-29 0.57)(30-39 0.22)(40+ 0.06))) (defrule begin => (assert (phase select-gender))) (defrule menu (phase select-gender) => (printout t "Do you identify as a (1) man or (2) woman?: ") (assert (userinput (read)))) (defrule selection-okay ?phase <- (phase select-gender) ?input <- (userinput ?select&1|2) => (retract ?phase) (assert (selection ?select)) (assert (phase select-ethnicity))) (defrule selection-nokay ?phase <- (phase select-gender) ?input <- (userinput ?select&~1&~2) => (retract ?phase) (assert (phase select-gender)) (printout t ?select " is not a valid response. Please enter 1 or 2."crlf)) (defrule menu2 (phase select-ethnicity) => (printout t "Do you identify as (1)Asian, (2)Black, (3)Latinx, (4)Indigenous, (5)White, or (6)Other?: ") (assert (userinput2 (read)))) (defrule selection-okay2 ?phase <- (phase select-ethnicity) ?input2 <- (userinput2 ?select&1|2|3|4|5|6) => (retract ?phase) (assert (selection ?select)) (assert (phase select-age))) (defrule selection-nokay2 ?phase <- (phase select-ethnicity) ?input2 <- (userinput2 ?select&~1&~2&~3&~4&~5&~6) => (retract ?phase) (assert (phase select-ethnicity)) (printout t ?select " is not a valid response. Please enter 1 through 6."crlf)) (defrule menu3 (phase select-age) => (printout t "You are age: (1)<18, (2)18-20, (3)20-30, (4)30-40, (5)40+?: ") (assert (userinput3 (read)))) (defrule selection-okay3 ?phase <- (phase select-age) ?input3 <- (userinput3 ?select&1|2|3|4|5) => (retract ?phase) (assert (selection ?select)) (assert (phase company-gender-men))) (defrule selection-nokay3 ?phase <- (phase select-age) ?input3 <- (userinput3 ?select&~1&~2&~3&~4&~5) => (retract ?phase) (assert (phase select-age)) (printout t ?select " is not a valid response. Please enter 1 through 5."crlf)) (defrule get-company-by-gender-men ?phase <- (company-gender-men) (= 1 input) (> (fact-slot-value 1 men) (fact-slot-value 2 men)) => (retract ?phase) (printout t (fact-slot-value 1 name) crlf)) ;(fact-slot-value 1 name) ;(> (fact-slot-value 1 men) (fact-slot-value 2 men))
简化测试代码
(deftemplate company (slot name) (slot men) (slot women) (slot Asian) (slot Black) (slot Latinx) (slot Indigenous) (slot White) (slot Other) (slot <18) (slot 18-20) (slot 21-29) (slot 30-39) (slot 40+)) (deffacts demographics (company (name Google)(men 0.669)(women 0.331)(Asian 0.428)(Black 0.088)(Latinx 0.088)(Indigenous 0.007)(White 0.445)(Other 0)(<18 0.02)(18-20 0.11)(21-29 0.59)(30-39 0.19)(40+ 0.07)) (company (name Apple)(men 0.652)(women 0.348)(Asian 0.279)(Black 0.094)(Latinx 0.148)(Indigenous 0.007)(White 0.438)(Other 0.032)(<18 0.01)(18-20 0.1)(21-29 0.57)(30-39 0.22)(40+ 0.06))) (defrule begin => (assert (phase select-gender))) (defrule menu (phase select-gender) => (printout t "Do you identify as a (1) man or (2) woman?: ") (assert (userinput (read)))(assert(phase select-ethnicity))) (defrule menu2 (phase select-ethnicity) => (printout t "Do you identify as (1)Asian, (2)Black, (3)Latinx, (4)Indigenous, (5)White, or (6)Other?: ") (assert (userinput2 (read)))(assert(phase select-age))) (defrule menu3 (phase select-age) => (printout t "You are age: (1)<18, (2)18-20, (3)20-30, (4)30-40, (5)40+?: ") (assert (userinput3 (read)))(assert(phase company-gender-men))) (defrule get-company-by-gender-men ?phase <- (company-gender-men) (userinput ?userinput) => (retract ?phase) (printout t ?userinput "can see user input"crlf))
问题解决思路
1. 比较运算符类型错误修复
原规则get-company-by-gender-men中的(= 1 input)写法错误,input不是合法变量,需先匹配userinput事实并绑定变量,再通过test函数进行比较。修正后的规则:
(defrule get-company-by-gender-men ?phase <- (phase company-gender-men) (userinput ?select) (test (= ?select 1)) ?c1 <- (company (name ?n1) (men ?m1)) ?c2 <- (company (name ?n2&~?n1) (men ?m2)) (test (> ?m1 ?m2)) => (retract ?phase) (printout t ?n1 crlf))
- 通过
(userinput ?select)将用户输入的性别选择绑定到?select变量 - 用
(test (= ?select 1))判断用户选择男性 - 匹配两家公司事实并比较男性占比,输出占比更高的公司名称
2. 历史用户输入访问问题修复
简化代码中规则触发顺序易导致输入事实无法被匹配,建议将用户所有人口统计信息整合到一个事实中,避免事实分散:
; 修改性别选择规则,将输入存入统一的demographic事实 (defrule selection-okay ?phase <- (phase select-gender) ?input <- (userinput ?select&1|2) => (retract ?phase ?input) (assert (demographic (gender ?select))) (assert (phase select-ethnicity))) ; 种族选择规则,补充demographic事实的种族字段 (defrule selection-okay2 ?phase <- (phase select-ethnicity) ?input2 <- (userinput2 ?select&1|2|3|4|5|6) ?demo <- (demographic (gender ?g)) => (retract ?phase ?input2 ?demo) (assert (demographic (gender ?g) (ethnicity ?select))) (assert (phase select-age))) ; 年龄选择规则,补充demographic事实的年龄字段 (defrule selection-okay3 ?phase <- (phase select-age) ?input3 <- (userinput3 ?select&1|2|3|4|5) ?demo <- (demographic (gender ?g) (ethnicity ?e)) => (retract ?phase ?input3 ?demo) (assert (demographic (gender ?g) (ethnicity ?e) (age ?select))) (assert (phase company-match)))
后续匹配公司的规则可直接通过(demographic (gender ?g) (ethnicity ?e) (age ?a))获取所有用户输入,解决历史输入访问问题。
内容的提问来源于stack exchange,提问作者Nicholas Chiu
相关产品推荐
相关产品推荐

