CLIPS报错[EXPRNPSR3]:Agriculture无函数声明,撤回deftemplate事实失败求助
问题分析与解决方案
你遇到的报错[EXPRNPSR3] Missing function declaration for Agriculture,根源是在input规则的动作(=>之后)部分错误地使用了事实匹配语法,CLIPS把它当成了函数调用。
看你的input规则里的这行代码:
?d <- (Agriculture(crop ?a) (weed ?b) (organic-matter ?c))
在CLIPS中,?var <- (事实模板名 ...)这种语法是专门用于规则条件部分(=>之前)匹配事实的,你把它放在动作部分后,CLIPS会误认为你要调用名为Agriculture的函数,但你并没有定义这个函数,所以就抛出了缺失函数声明的报错。
正确的修改方式
从你的代码逻辑来看,你是想撤回刚断言的三个Agriculture事实,最简单的做法是在断言时就把每个事实绑定到变量,之后直接撤回这些变量对应的事实:
修正后的input规则:
(defrule input (initial-fact) => (printout t crlf "What is the crop? (C:corn,S:soybean)") (bind ?a (read)) (bind ?crop-fact (assert(Agriculture(crop ?a)))) ; 绑定断言的作物事实到变量 (printout t crlf "What is the weed problem? (B:broadleaf, G:grass)") (bind ?b (read)) (bind ?weed-fact (assert(Agriculture(weed ?b)))) ; 绑定杂草事实到变量 (printout t crlf "What is the % of organic matter content? (1:<2%,2:2-4%,3:>4%)") (bind ?c (read)) (bind ?om-fact (assert(Agriculture(organic-matter ?c)))) ; 绑定有机质事实到变量 (printout t ""crlf crlf "RECOMMENDATIONS:"crlf) (retract ?crop-fact ?weed-fact ?om-fact) ; 一次性撤回三个事实 )
额外的优化建议
其实你的规则设计有点冗余——现在每个规则都要匹配三个独立的Agriculture事实,更合理的做法是断言一个包含所有三个槽的完整Agriculture事实,这样规则只需要匹配一个事实即可:
比如修改input规则断言完整事实:
(defrule input (initial-fact) => (printout t crlf "What is the crop? (C:corn,S:soybean)") (bind ?a (read)) (printout t crlf "What is the weed problem? (B:broadleaf, G:grass)") (bind ?b (read)) (printout t crlf "What is the % of organic matter content? (1:<2%,2:2-4%,3:>4%)") (bind ?c (read)) (bind ?full-fact (assert(Agriculture(crop ?a) (weed ?b) (organic-matter ?c)))) ; 断言一个包含所有槽的事实 (printout t ""crlf crlf "RECOMMENDATIONS:"crlf) (retract ?full-fact) )
然后修改所有规则,合并三个Agriculture条件为一个:
(defrule Sencor-1 (Agriculture(weed B) (crop C|S) (organic-matter 1)) => (printout t "Do not use Sencor!!"crlf) ) (defrule Sencor-2 (Agriculture(weed B) (crop C|S) (organic-matter 2|3)) => (printout t " " crlf "Use 3/4 pt/ac of Sencor" crlf ) ) ; 其他规则以此类推,把分散的三个Agriculture条件合并成一个
这样不仅更符合逻辑(一个农业场景对应一个事实),还能避免规则匹配时出现的潜在错误。
内容的提问来源于stack exchange,提问作者melo
相关产品推荐
相关产品推荐

