CLIPS detemplate 插槽类型不正确

CLIPS deftemplate incorrect slot type

我对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)
)

当我 (assert (get-ch TRUE)) 和 (运行) 时,它会提示我输入 ch 名称和分数。但是,如果我为分数输入一个字符串,则该字符串分数会被规则断言!例如:

Enter ch name
hello
Enter ch score
hello
;(basic-ch (ch-name hello)(score hello)) get asserted?!

这怎么可能?我已将分数定义为 INTEGER,甚至提供了范围。我该如何阻止它?

摘自《基本编程指南》第 11 节约束属性:

Two types of constraint checking are supported: static and dynamic. When static constraint checking is enabled, constraint violations are checked when function calls and constructs are parsed. This includes constraint checking between patterns on the LHS of a rule when variables are used in more than one slot. When dynamic constraint checking is enabled, newly created data objects (such as deftemplate facts and instances) have their slot values checked for constraint violations. Essentially, static constraint checking occurs when a CLIPS program is loaded and dynamic constraint checking occurs when a CLIPS program is running. By default, static constraint checking is enabled and dynamic constraint checking is disabled. The default behavior can be changed by using the set-static-constraint-checking and set-dynamic-constraint-checking functions.

如果您启用动态约束检查,当您 运行 您的程序时会出现错误:

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>