题
我想澄清我的剪辑专家系统语义的理解,所以我尝试写一些简单的规则来聚合事实的列表中找到具有最高插槽值的事实。我使用的比喻是一个简单的代理,试图决定是否应少吃或睡眠。描述代理的状态的事实被扩展到潜在行动,然后通常试图找到具有最高效用的最终行动。
这是我的代码:
(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))
然而,剪辑它的计算结果为:
(action (name none) (utility 0.0) (final 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))
不隶属于 StackOverflow