2017-04-01 5 views
0

私はCLIPSに非常に困惑しています。 .clpファイルにdeftemplateとルールを定義しました。CLIPS deftemplateの間違ったスロットタイプ

I()(取得-CH TRUEをアサート)と(実行)、それはCH名とスコアのために私を促し
(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) 
) 

。しかし、スコアの文字列を入力すると、文字列スコアはルールによってアサートされます!例:

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

これはどのように可能ですか?私はスコアをINTEGERと定義し、範囲を指定しました。どうすればこれをやめることができますか?第11節から

答えて

2

は、制約は、基本的なプログラミングガイドの、属性:制約チェックの

二つのタイプがサポートされています:静的および動的。 静的制約チェックを有効にすると、関数呼び出しと構文が解析されるときに制約違反が確認されます( )。これには、 変数が複数のスロットで使用されている場合に、ルールのLHS上のパターン間の制約チェックが含まれます。動的制約 チェックが有効な場合、新しく作成されたデータオブジェクト(deftemplate ファクトとインスタンスなど)のスロット値は、制約 の違反をチェックされます。本質的には、 CLIPSプログラムがロードされ、 CLIPSプログラムが実行されているときに動的制約チェックが行われたときに静的制約チェックが行われます。デフォルトでは、静的制約チェックは であり、動的制約チェックは無効です。デフォルトの の動作は、set-static-constraint-checking および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> 
関連する問題