Question

Je suis en train de clarifier ma compréhension de la sémantique dans le système expert CLIPS, donc je suis en train d'écrire quelques règles simples pour agréger une liste de faits pour trouver le fait avec la plus grande valeur de l'emplacement. La métaphore que je utilise est celle d'un simple agent essayant de décider si elle doit manger ou dormir. Les faits qui décrivent les états de l'agent sont développés en actions potentielles, puis une règle tente de trouver l'action finale avec la plus haute utilité.

Ceci est mon code:

(clear)

(deftemplate state 
    (slot name) 
    (slot level (type NUMBER)) 
) 
(deftemplate action 
    (slot name) 
    (slot utility (type NUMBER)) 
    (slot final (type INTEGER) (default 0)) 
) 
(defrule eat-when-hungry "" 
    (state (name hungry) (level ?level)) 
    => 
    (assert (action (name eat) (utility ?level))) 
) 
(defrule sleep-when-sleepy "" 
    (state (name sleepy) (level ?level)) 
    => 
    (assert (action (name sleep) (utility ?level))) 
) 
(defrule find-final-action "" 
    ?current_final <- (action (name ?current_final_action) (utility ? 
current_final_utility) (final 1)) 
    (action (name ?other_action) (utility ?other_utility) (final 0)) 
    (neq ?current_final_action ?other_action) 
    (< ?current_final_action ?other_action) 
    => 
    (modify ?current_final (name ?other_action) (utility ? 
other_utility)) 
) 
(assert (action (name none) (utility 0.0) (final 1))) 
(assert (state (name hungry) (level 0.5))) 
(assert (state (name sleepy) (level 0.1))) 
(run) 
(facts)

Après l'exécution, je me attends la décision finale soit:

(action (name eat) (utility 0.5) (final 1)) 

Cependant, clips évalue à:

(action (name none) (utility 0.0) (final 1)) 

indiquant la règle find-action finale active jamais. Pourquoi est-ce? Comment voulez-vous itérer sur un ensemble de faits et de trouver celui avec la valeur de l'emplacement min / max?

Était-ce utile?

La solution

Votre règle avait quelques erreurs en elle. Voici la version corrigée:

(defrule find-final-action "" 
    ?current_final <- (action (name ?current_final_action) 
                              (utility ?current_final_utility) (final 1)) 
    (action (name ?other_action) (utility ?other_utility) (final 0)) 
    (test (neq ?current_final_action ?other_action))
    (test (< ?current_final_utility ?other_utility)) 
    => 
    (modify ?current_final (name ?other_action) (utility ?other_utility)))

Une autre méthode qui ne nécessite pas le stockage des calculs intermédiaires et des multiples règles mises à feu est la suivante:

(defrule find-final-action-2 "" 
    (declare (salience -10)) ; lower salience to allow all actions to be asserted first
    (action (name ?action) (utility ?utility)) 
    (not (action (utility ?other_utility&:(> ?other_utility ?utility))))
    => 
    (printout t "Final action is " ?action crlf))
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top