2015-11-05 2 views
0

Bonjour tout d'abord l'anglais n'est pas ma langue principale désolé pour les erreurs orthographiques ou peut-être faire des questions dans le mauvais sens. J'utilise Clips 6.3 version 64bit.La ligne de commande redémarre lorsque 2 éléments avec les mêmes attributs trouvés

J'apprends ce pour l'école, mais mon professeur ne nous donne pas beaucoup d'informations au sujet de la partie de la programmation, où l'apprentissage seulement la théorie derrière tout cela, donc mon problème est que je suis en ce beau programme https://github.com/JherezTaylor/cheese-classification/blob/master/wichCheese.clp sur mes clips pour voir comment cela fonctionne, et tout fonctionne bien sauf quand 2 éléments ont les mêmes attributs, il ne va pas continuer à filtrer il vide juste la ligne de commande et je dois recommencer, plus spécifique quand je lance le programme et réponds premières questions avec 1. Bleu 2. Crémeux il fait l'erreur dont je parle, ma première pensée est que son plantage parce qu'il y a plus de 1 registre qui commence avec ces 2 attributs.

Désolé pour le texte long demandant la première fois, toute aide est appréciée et tout commentaire sur ma façon de poser est bien reçu.

merci d'avance à toute personne désireuse d'aider.

Répondre

0

La question est que la règle des contrôles faits-à-texture supprime le fait nécessaire pour activer la règle mainQuestion-Color:

(defrule check-facts-at-texture 
    ?f <- (cheeseTexture ?) 
=> 
    (cheeseFound) 
    (cheeseNotFound) 
    (retract ?f) 
) 

(defrule mainQuestion-Colour 
    (cheeseTexture ?tx) 
    => 
    (bind ?colour (ask-question "### What is the general colour of the cheese? (white yellow pale-yellow green) ### " "" "" white yellow pale-yellow green)) 
    (assert (cheeseColour ?colour)) 
) 

Le programme arrête parce qu'il n'y a pas de règles plus applicables. Si vous apportez des modifications appropriées à ces règles, vous pouvez les obtenir au feu correctement:

(defrule check-facts-at-texture 
    ?f <- (cheeseTexture ?) 
=> 
    (assert (ask-color)) 
    (cheeseFound) 
    (cheeseNotFound) 
    (retract ?f) 
) 

(defrule mainQuestion-Colour 
    (declare (salience -10)) 
    (ask-color) 
    ;; only ask if there are at least two cheeses left 
    (exists (cheese (name ?name)) 
      (cheese (name ~?name))) 
    => 
    (bind ?colour (ask-question "### What is the general colour of the cheese? (white yellow pale-yellow green) ### " "" "" white yellow pale-yellow green)) 
    (assert (cheeseColour ?colour)) 
) 

Vous allez rencontrer le même problème avec les règles suivantes dans le programme et ceux-ci devront être changé.

Vous pouvez simplifier le programme d'origine en écrivant des règles génériques pour poser les questions et supprimer les fromages qui ne correspondent pas. Les globales et les fonctions qui suivent le nombre de fromages sont également inutiles. Gardez le deftemplate de fromage original et la liste de fromages deffacts.

(deftemplate cheese 
    (multislot name) 
    (multislot milk-source) 
    (multislot country) 
    (multislot type) 
    (multislot texture) 
    (multislot colour) 
    (multislot flavour) 
    (multislot aroma) 
    (multislot common-useage)) 

(deffacts cheese-list 
    (cheese (name "gouda") 
     (milk-source cow) 
     (country "netherlands") 
     (type semi-hard) 
     (texture firm) 
     (colour yellow) 
     (flavour rich) 
     (aroma pungent) 
     (common-useage table-cheese)) 
    . 
    . 
    .   
) 

Supprimez l'autre code. Utilisez le code suivant pour poser des questions:

(deffunction ask-question (?question $?allowed-values) 
    (printout t ?question " " ?allowed-values " ") 
    (bind ?answer (read)) 
    (if (lexemep ?answer) 
     then (bind ?answer (lowcase ?answer))) 
    (while (not (member ?answer ?allowed-values)) do 
     (printout t ?question " " ?allowed-values " ") 
     (bind ?answer (read)) 
     (if (lexemep ?answer) 
      then (bind ?answer (lowcase ?answer)))) 
    ?answer) 

(deftemplate question 
    (slot text) 
    (slot priority (default 0)) 
    (slot attribute) 
    (multislot values)) 

(deftemplate response 
    (slot attribute) 
    (slot value)) 

(deffacts questions 
    (question (text "What type of cheese is it?") 
      (priority 1) 
      (attribute type) 
      (values semi-soft soft semi-hard hard blue)) 
    (question (text "How would you describe the texture of the cheese?") 
      (priority 2) 
      (attribute texture) 
      (values crumbly springy firm creamy smooth)) 
    (question (text "What is the general colour of the cheese?") 
      (priority 3) 
      (attribute colour) 
      (values white yellow pale-yellow green)) 
    (question (text "How would you describe the flavour of the cheese?") 
      (priority 4) 
      (attribute flavour) 
      (values strong mild rich sweet spicy creamy)) 
    (question (text "How would you describe the aroma of the cheese?") 
      (priority 5) 
      (attribute aroma) 
      (values strong mild pleasant pungent none)) 
    (question (text "What is the most common use of the cheese?") 
      (priority 6) 
      (attribute common-useage) 
      (values table-cheese bread cooking pasta salad melting dip dessert dressing pizza cheesecake))) 

(defrule ask-question 
    (declare (salience -10)) 
    ?f <- (question (text ?text) 
        (priority ?p) 
        (attribute ?attribute) 
        (values $?values)) 
    ;; Verify that this is the highest priority question 
    (not (question (priority ?p2&:(< ?p2 ?p)))) 
    ;; Keep asking questions as long there 
    ;; are at least two cheeses 
    (exists (cheese (name ?name)) 
      (cheese (name ~?name))) 
    => 
    (retract ?f) 
    (bind ?response (ask-question ?text ?values)) 
    (assert (response (attribute ?attribute) (value ?response)))) 

Utilisez la règle suivante pour filtrer les fromages sur la base des réponses:

(defrule filter-response 
    (declare (salience 10)) 
    (response (attribute ?attribute) (value ?value)) 
    ?f <- (cheese) 
    (test (not (member$ ?value (fact-slot-value ?f ?attribute)))) 
    => 
    (retract ?f)) 

Utilisez le code suivant pour détecter les fromages correspondant:

(deffunction fsv (?fact ?slot) 
    (nth$ 1 (fact-slot-value ?fact ?slot))) 

(defrule match-not-found 
    (not (cheese)) 
    => 
    (printout t crlf "No matching cheese found." crlf)) 

(defrule match-found 
    ?f <- (cheese (name ?name)) 
    (not (cheese (name ~?name))) 
    => 
    (printout t crlf "Cheese found:" crlf) 
    (printout t " Name: " ?name crlf) 
    (printout t " Milk Source: " (fsv ?f milk-source) crlf) 
    (printout t " Type: " (fsv ?f type) crlf) 
    (printout t " Country: " (fsv ?f country) crlf) 
    (printout t " Texture: " (fsv ?f texture) crlf) 
    (printout t " Colour: " (fsv ?f colour) crlf) 
    (printout t " Flavour: " (fsv ?f flavour) crlf) 
    (printout t " Aroma: " (fsv ?f aroma) crlf) 
    (printout t " Common Useage: " (fsv ?f common-useage) crlf)) 

(defrule multiple-matches-found 
    (exists (cheese (name ?name)) 
      (cheese (name ~?name))) 
    (not (question)) 
    => 
    (printout t crlf "Multiple matching cheeses: ") 
    (do-for-all-facts ((?c cheese)) TRUE 
    (printout t (fsv ?c name) " ")) 
    (printout t crlf)) 

Le programme résultant aura maintenant 5 règles plutôt que 19 dans le programme original.