我对 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)
)
当 i (assert (get-ch TRUE)) 和 (run) 时,它会提示我输入 ch 名称和分数。但是,如果我为分数输入字符串,则字符串分数会被规则断言!例如:
Enter ch name
hello
Enter ch score
hello
;(basic-ch (ch-name hello)(score hello)) get asserted?!
这怎么可能?我已将分数定义为整数,甚至提供了范围。我怎么能阻止这个?
来自基本编程指南的第 11 节,约束属性:
支持两种类型的约束检查:静态和动态。启用静态约束检查后,会在解析函数调用和构造时检查约束违规。这包括当变量用于多个插槽时,规则的 LHS 上的模式之间的约束检查。启用动态约束检查后,新创建的数据对象(例如 deftemplate 事实和实例)会检查其槽值是否违反约束。本质上,静态约束检查发生在加载 CLIPS 程序时,而动态约束检查发生在 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>
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句