Pregunta

Estoy tratando de aclarar mi entendimiento de la semántica de los clips de sistemas expertos, por lo que estoy tratando de escribir algunas reglas simples para agregar una lista de datos para encontrar el hecho con el valor más alto de la ranura. La metáfora que estoy usando es el de un simple agente tratando de decidir si debe comer o dormir. Datos que describen los estados del agente se expanden en las acciones posibles, y luego una regla trata de encontrar la acción final con la mayor utilidad.

Este es mi código:

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

Después de ejecutar esto, yo esperaría que la acción final sea:

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

Sin embargo, clips evalúa a:

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

que indica la regla hallazgo de final de acción nunca se activa. ¿Por qué es esto? ¿Cómo le iterar sobre un grupo de hechos y encontrar el uno con el valor ranura min / max?

¿Fue útil?

Solución

Su regla tenía un par de errores en ella. Esta es la versión corregida:

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

Un método alternativo que no requiere el almacenamiento de cálculos intermedios y múltiples activaciones de regla es la siguiente:

(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))
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top