在CLIPS专家系统中聚合事实以找到最大值

时间:2010-03-04 20:54:49

标签: expert-system clips

我试图澄清我对Clips专家系统中语义的理解,所以我试图编写一些简单的规则来聚合事实列表以找到具有最高槽值的事实。我正在使用的比喻是一个简单的代理人试图决定它应该吃还是睡觉。描述代理状态的事实被扩展为潜在的操作,然后规则试图找到具有最高效用的最终操作。

这是我的代码:

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

运行之后,我希望最后的行动是:

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

但是,Clips将其评估为:

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

表示查找最终操作规则永远不会激活。为什么是这样?你将如何迭代一组事实并找到具有最小/最大槽值的那个?

1 个答案:

答案 0 :(得分:1)

你的规则中有一些错误。这是更正后的版本:

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

另一种不需要存储中间计算和多次规则激活的方法是这样的:

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