2017-04-01 3 views
0

Je suis très intrigué par CLIPS. J'ai défini dans un fichier .clp un deftemplate et une règle.CLIPS deftemplate type d'emplacement incorrect

(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) 
) 

Quand je (assert (get-ch TRUE)) et (course), il me demande le nom de ch et le score. Cependant, si j'entre une chaîne pour le score, le score de la chaîne est confirmé par la règle! Par exemple:

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

Comment est-ce possible? J'ai défini le score pour être INTEGER et même fourni la gamme. Comment puis-je arrêter cela?

Répondre

2

De la section 11, Attributs Constraint, du Guide de base de la programmation:

Deux types de contraintes de contrôle sont pris en charge: statique et dynamique. Lorsque la vérification des contraintes statiques est activée, les violations de contrainte sont vérifiées lorsque les appels de fonction et les constructions sont analysés. Cela inclut la vérification des contraintes entre les modèles sur la LHS d'une règle lorsque variables sont utilisées dans plusieurs emplacements. Lorsque la vérification de contrainte dynamique est activée, les objets de données nouvellement créés (tels que deftemplate faits et instances) ont leurs valeurs d'emplacement vérifiées pour les violations . Essentiellement, la vérification statique des contraintes se produit lorsqu'un programme CLIPS est chargé et qu'une vérification dynamique des contraintes se produit lorsqu'un programme CLIPS est en cours d'exécution. Par défaut, la vérification des contraintes statiques est activée et la vérification dynamique des contraintes est désactivée. Le comportement par défaut peut être modifié à l'aide des fonctions set-static-constraint-checking et set-dynamic-constraint-checking.

Si vous activez la contrainte dynamique de vérification, vous obtenez une erreur lorsque vous exécutez votre programme:

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> 

Parce qu'il génère une erreur, le contrôle dynamique de contraintes est utile pour les tests, mais pas pour valider entrée utilisateur pendant l'exécution d'un programme. Si vous souhaitez valider l'utilisation de l'entrée, définissez certaines méthodes d'utilitaire:

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>