不使用declare salience实现规则执行顺序:规则依赖场景咨询
不用
declare salience实现CLIPS规则执行顺序的方法 嘿,这个问题其实可以靠CLIPS本身的事实驱动特性和一些内置机制来解决,完全不需要硬指定优先级~ 你的场景里第二条规则依赖第一条的输出事实,刚好可以利用规则的匹配逻辑来自然保证顺序,下面给你几种实用的方案:
1. 利用事实依赖(最适合你的场景)
你的creategroup规则本身就依赖filterage断言的is-equal-to-22事实——也就是说,只有当filterage执行并生成这些事实后,creategroup才会被激活到议程里。CLIPS会自动处理这种依赖关系,根本不需要额外设置。
先把你不完整的代码补全,完整版本如下:
(deftemplate person (slot name (type STRING)) (slot age (type STRING)) ) (deffacts start (person(name "Mike")(age "20")) (person(name "Laura")(age "22")) (person(name "Dean")(age "22")) (person(name "Charlie")(age "22")) ) (defrule filterage (person (name ?n)(age ?a)) (test (eq ?a "22")) => (assert (is-equal-to-22 ?n)) (printout t "Filtered: " ?n crlf) ) (defrule creategroup (is-equal-to-22 ?c) => (assert (is-in-22-year-group ?c)) (printout t "Added to group: " ?c crlf) )
运行这段代码时,CLIPS会先激活所有匹配filterage的规则实例(因为初始事实里有三个22岁的person),执行后断言三个is-equal-to-22事实,这些新事实会触发creategroup规则的激活和执行,完美保证顺序。
2. 用激活组(Activation Groups)做阶段控制
如果你的场景更复杂,比如有多个规则需要分批次执行,可以给规则分配激活组,通过focus命令控制执行顺序:
(defrule filterage (declare (activation-group filter-phase)) ; 分配到过滤阶段组 (person (name ?n)(age ?a)) (test (eq ?a "22")) => (assert (is-equal-to-22 ?n)) (printout t "Filtered: " ?n crlf) ) (defrule creategroup (declare (activation-group group-phase)) ; 分配到分组阶段组 (is-equal-to-22 ?c) => (assert (is-in-22-year-group ?c)) (printout t "Added to group: " ?c crlf) ) ; 在启动时设置执行顺序 (deffacts setup (initial-focus) ) (defrule init-focus (initial-focus) => (focus filter-phase) ; 先执行过滤组 (focus group-phase) ; 再执行分组组 (retract (initial-focus)) )
激活组的特点是:只有当前聚焦的组里的规则会被执行,直到该组没有激活的规则后,才会切换到下一个聚焦的组。
3. 用模块(Modules)隔离并控制执行
对于大型规则系统,可以把不同逻辑的规则放到不同模块里,通过切换当前模块来控制执行顺序:
; 定义过滤模块 (defmodule FILTER-MODULE) (in-module FILTER-MODULE) (defrule filterage (person (name ?n)(age ?a)) (test (eq ?a "22")) => (assert (is-equal-to-22 ?n)) (printout t "Filtered: " ?n crlf) ) ; 定义分组模块 (defmodule GROUP-MODULE) (in-module GROUP-MODULE) (defrule creategroup (is-equal-to-22 ?c) => (assert (is-in-22-year-group ?c)) (printout t "Added to group: " ?c crlf) ) ; 切换回主模块控制执行 (in-module MAIN) (deffacts setup (start-execution) ) (defrule run-phases (start-execution) => (set-current-module FILTER-MODULE) (run) ; 执行过滤模块的所有规则 (set-current-module GROUP-MODULE) (run) ; 执行分组模块的所有规则 (retract (start-execution)) )
模块可以隔离规则、事实和议程,适合复杂系统的分阶段执行。
内容的提问来源于stack exchange,提问作者Keka Bron
相关产品推荐
相关产品推荐

