2010-03-04 2 views
0

J'essaie de clarifier ma compréhension de la sémantique dans le système expert Clips, donc j'essaie d'écrire quelques règles simples pour agréger une liste de faits pour trouver le fait avec la valeur de slot la plus élevée. La métaphore que j'utilise est celle d'un simple agent essayant de décider s'il doit manger ou dormir. Les faits décrivant les états de l'agent sont développés en actions potentielles, puis une règle tente de trouver l'action finale avec l'utilitaire le plus élevé.Agrégation des faits dans le système expert CLIPS pour trouver un maximum

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 avoir couru, je me attends à la dernière action à:

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

Cependant, clips évalue à:

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

indiquant que la règle find-final-action ne s'active jamais. Pourquoi est-ce? Comment allez-vous parcourir un groupe de faits et trouver celui avec la valeur de slot min/max?

Répondre

1

Votre règle comportait quelques erreurs. 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)) 
Questions connexes