CLIPS非常困惑。我在.clp文件中定义了一个deftemplate和一个规则。
(deftemplate basic-ch "Basic characteristics template"
(slot ch-name
(type SYMBOL)
(default ?DERIVE)
)
(slot score
(type INTEGER)
(default 1)
(range 1 5)
)
)
(defrule make-ch
?get-ch <- (get-ch TRUE)
=>
(printout t "Enter ch name" crlf)
(bind ?name (read))
(printout t "Enter ch score" crlf)
(bind ?score (read))
(assert (basic-ch (ch-name ?name) (score ?score)))
(retract ?get-ch)
)
当我(断言(get-ch TRUE))和(跑步)时,它会提示我输入名称和分数。但是,如果我输入分数的字符串,则规则会断言字符串分数!例如:
Enter ch name
hello
Enter ch score
hello
;(basic-ch (ch-name hello)(score hello)) get asserted?!
这怎么可能?我已将得分定义为INTEGER,甚至提供了范围。我怎么能阻止这个?
答案 0 :(得分:2)
基本编程指南的第11节“约束属性”:
支持两种类型的约束检查:静态和动态。 启用静态约束检查时,违反约束条件 在解析函数调用和构造时检查。这包括 当规则的LHS上的模式之间的约束检查 变量用于多个槽中。当动态约束时 检查已启用,新创建的数据对象(例如deftemplate 事实和实例)检查其槽值是否有约束 违法行为。本质上,静态约束检查发生在a 加载CLIPS程序并在a时发生动态约束检查 CLIPS程序正在运行。默认情况下,静态约束检查是 启用并禁用动态约束检查。默认 可以使用set-static-constraint-checking来更改行为 和set-dynamic-constraint-checking函数。
如果启用动态约束检查,则在运行程序时会出现错误:
CLIPS> (set-dynamic-constraint-checking TRUE)
TRUE
CLIPS> (assert (get-ch TRUE))
<Fact-1>
CLIPS> (run)
Enter ch name
hello
Enter ch score
hello
[CSTRNCHK1] Slot value hello found in fact f-2
does not match the allowed types for slot score.
[PRCCODE4] Execution halted during the actions of defrule make-ch.
CLIPS>
因为它会生成错误,所以动态约束检查对于测试很有用,但不适用于在程序执行时验证用户输入。如果要验证使用输入,请定义一些实用程序方法:
CLIPS>
(defmethod get-integer ((?query STRING))
(bind ?value FALSE)
(while (not (integerp ?value))
(printout t ?query " ")
(bind ?value (read)))
?value)
CLIPS>
(defmethod get-integer ((?query STRING) (?lower INTEGER) (?upper INTEGER))
(bind ?value FALSE)
(while (or (not (integerp ?value)) (< ?value ?lower) (> ?value ?upper))
(printout t ?query " (" ?lower " - " ?upper ") ")
(bind ?value (read)))
?value)
CLIPS> (get-integer "Pick an integer:")
Pick an integer: hello
Pick an integer: 3
3
CLIPS> (get-integer "Pick an integer" 1 5)
Pick an integer (1 - 5) -1
Pick an integer (1 - 5) hello
Pick an integer (1 - 5) 8
Pick an integer (1 - 5) 4
4
CLIPS>