Domanda

Sto cercando di chiarire la mia comprensione della semantica nelle clip del sistema esperto, quindi sto cercando di scrivere alcune semplici regole per aggregare un elenco di fatti per trovare il fatto con il valore più alto di slot. La metafora che sto utilizzando è quella di un agente semplice cercando di decidere se deve mangiare o dormire. I fatti che descrivono gli stati dell'agente sono espanse in potenziali azioni, e quindi una regola cerca di trovare l'azione finale con la più alta utilità.

Questo è il mio codice:

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

Dopo l'esecuzione di questo, io mi aspetterei che l'azione finale di essere:

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

Tuttavia, clip lo valuta a:

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

che indica la regola find-finale-action mai attiva. Perchè è questo? Come sarebbe di eseguire iterazioni su un gruppo di fatti e di trovare quello con il valore di slot min / max?

È stato utile?

Soluzione

La regola ha avuto un paio di errori in esso. Ecco la versione corretta:

(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 metodo alternativo che non richiede la memorizzazione di calcoli intermedi e molteplici cotture regola è questa:

(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))
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top