CLIPS deftemplate неверный тип слота

Я очень озадачен КЛИПСАМИ. Я определил в файле .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?!

Как это возможно? Я определил оценку как INTEGER и даже указал диапазон. Как я могу это остановить?


person James    schedule 01.04.2017    source источник


Ответы (1)


Из раздела 11 «Атрибуты ограничений» Руководства по основному программированию:

Поддерживаются два типа проверки ограничений: статическая и динамическая. Когда проверка статических ограничений включена, нарушения ограничений проверяются при анализе вызовов функций и конструкций. Это включает проверку ограничений между шаблонами на LHS правила, когда переменные используются более чем в одном слоте. Когда включена динамическая проверка ограничений, для вновь созданных объектов данных (например, фактов и экземпляров deftemplate) значения слотов проверяются на нарушение ограничений. По сути, проверка статических ограничений происходит при загрузке программы CLIPS, а проверка динамических ограничений происходит при выполнении программы CLIPS. По умолчанию проверка статических ограничений включена, а проверка динамических ограничений отключена. Поведение по умолчанию можно изменить с помощью функций set-static-constraint-check и set-dynamic-constraint-check.

Если вы включите динамическую проверку ограничений, при запуске программы вы получите сообщение об ошибке:

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> 
person Gary Riley    schedule 01.04.2017