我已经测试了 Adventures 书中获取命令的建议方法 基于规则的编程(第 3C 章)。
思路是输入带事实的命令,判断是否有未知命令。 我已经尝试了两种令人惊讶的不同行为:
(defrule read-command
(declare (salience -10))
(not (command))
=>
(bind $?com (readline))
)
(defrule bad-command
(declare (salience -10))
?com <- (command (action $?act))
=>
(println "Unknown command " ?act)
(rectract ?com)
)
;next, there would be right commands rules, with higher priority
使用 (run) 时,会触发 read-command 规则,如果用户引入未知命令,则会触发 bad-command。这永远发生在循环中。没关系。
但是,对命令事实使用有序向量会产生不同的行为。当引入错误命令时,错误命令规则会触发,但规则 read-command 不会。程序到此结束,并没有想要的循环
这有什么意义?
在将缺少的 deftemplate 添加到您的代码片段并修复缩回的拼写错误后,您的代码片段的行为与您描述的行为不匹配:
CLIPS> (clear)
CLIPS>
(deftemplate command
(multislot action))
CLIPS>
(defrule read-command
(declare (salience -10))
(not (command))
=>
(bind $?com (readline)))
CLIPS>
(defrule bad-command
(declare (salience -10))
?com <- (command (action $?act))
=>
(println "Unknown command " ?act)
(retract ?com))
CLIPS> (reset)
CLIPS> (agenda)
-10 read-command: *
For a total of 1 activation.
CLIPS> (run)
drink potion
CLIPS> (facts)
CLIPS>
read-command 中的 readline 调用将从用户那里获得一行输入,但是你正在分配给变量 $?com 并且没有对该变量做任何进一步的事情所以没有办法触发 bad-command 规则.