??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲一区精品伊人久久伊人,精品亚洲成α人无码成α在线观看 ,亚洲国产av美女网站http://www.tkk7.com/clant/category/17974.htmlzh-cnFri, 02 Mar 2007 21:54:11 GMTFri, 02 Mar 2007 21:54:11 GMT60Java规则引擎工作原理?qing)其应?/title><link>http://www.tkk7.com/clant/articles/87951.html</link><dc:creator>BPM </dc:creator><author>BPM </author><pubDate>Fri, 15 Dec 2006 07:19:00 GMT</pubDate><guid>http://www.tkk7.com/clant/articles/87951.html</guid><wfw:comment>http://www.tkk7.com/clant/comments/87951.html</wfw:comment><comments>http://www.tkk7.com/clant/articles/87951.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/clant/comments/commentRss/87951.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/clant/services/trackbacks/87951.html</trackback:ping><description><![CDATA[ <strong>??/strong> Java规则引擎是一U嵌入在JavaE序中的lgQ它的Q务是把当前提交给引擎的Java数据对象与加载在引擎中的业务规则q行试和比对,Ȁz那些符合当前数据状态下的业务规则,Ҏ(gu)业务规则中声明的执行逻辑Q触发应用程序中对应的操作?<b>引言</b>目前QJavaC֌推动q发展了一U引人注目的新技术——Java规则引擎QRule EngineQ。利用它?yu)可以在应用pȝ中分d业决{者的商业决策逻辑和应用开发者的技术决{,q把q些商业决策攑֜中心数据库或其他l一的地方,让它们能在运行时可以动态地理和修改,从而ؓ(f)企业保持灉|性和竞争力提供有效的技术支持?br /><b><br />规则引擎的原?br /></b><strong>1、基于规则的专家pȝQRBESQ简?/strong>Java规则引擎h于基于规则的专家pȝQ而基于规则的专家pȝ又是专家pȝ的其中一个分支。专家系l属于h工智能的范畴Q它模仿人类的推理方式,使用试探性的Ҏ(gu)q行推理Qƈ使用人类能理解的术语解释和证明它的推理结论。ؓ(f)了更深入C解Java规则引擎Q下面简要地介绍Z规则的专家系l。RBES包括三部分:(x)Rule BaseQknowledge baseQ、Working MemoryQfact baseQ和Inference Engine。它们的l构如下pȝ所C:(x) <center><img src="http://www.85flash.com/Files/BeyondPic/2006-10/22/06102213335938787.gif" border="0" /></center><p></p><p style="TEXT-INDENT: 2em" align="center">? Z规则的专家系l构成如?所C,推理引擎包括三部分:(x)模式匚w器(Pattern MatcherQ、议E(AgendaQ和执行引擎QExecution EngineQ。推理引擎通过军_哪些规则满事实或目标,q授予规则优先Q满事实或目标的规则被加入议程。模式匹配器军_选择执行哪个规则Q何时执行规则;议程理模式匚w器挑选出来的规则的执行次序;执行引擎负责执行规则和其他动作。和人类的思维相对应,推理引擎存在两者推理方式:(x)演绎法(F(tun)orward-ChainingQ和归纳法(Backward-ChainingQ。演l法从一个初始的事实出发Q不断地应用规则得出l论Q或执行指定的动作)(j)。而归Ux则是Ҏ(gu)假设Q不断地LW合假设的事实。Rete法是目前效率最高的一个Forward-Chaining推理法Q许多Java规则引擎都是ZRete法来进行推理计的。推理引擎的推理步骤如下Q?1)初始数据(factQ输入Working Memory?2)使用Pattern Matcher比较规则库(rule baseQ中的规则(ruleQ和数据QfactQ?3)如果执行规则存在冲突QconflictQ,卛_时激zM多个规则Q将冲突的规则放入冲H集合?4)解决冲突Q将Ȁzȝ规则按顺序放入Agenda?5)使用执行引擎执行Agenda中的规则。重复步??Q直到执行完毕所有Agenda中的规则。上q即是规则引擎的原始架构QJava规则引擎是从这一原始架构演变而来的?strong>2、规则引擎相x?/strong>规则引擎是一U根据规则中包含的指定过滤条Ӟ判断其能否匹配运行时ȝ实时条g来执行规则中所规定的动作的引擎。与规则引擎相关的有四个基本概念Qؓ(f)更好地理解规则引擎的工作原理Q下面将对这些概念进行逐一介绍?)信息元(Information UnitQ信息元是规则引擎的基本建筑块,它是一个包含了特定事g的所有信息的对象。这些信息包括:(x)消息、生事件的应用E序标识、事件生事件、信息元cd、相兌则集、通用Ҏ(gu)、通用属性以?qing)一些系l相关信息等{?2)信息服务QInformation ServicesQ信息服务生信息元对象。每个信息服务生它自己cd相对应的信息元对象。即特定信息服务Ҏ(gu)信息元所产生每个信息元对象有相同的格式,但可以有不同的属性和规则集。需要注意的是,在一台机器上可以q行许多不同的信息服务,q可以运行同一信息服务的不同实例。但无论如何Q每个信息服务只产生它自q型相对应的信息元?)规则集(Rule SetQ顾名思义Q规则集是许多规则的集合。每条规则包含一个条件过滤器和多个动作。一个条件过滤器可以包含多个qo(h)条g。条件过滤器是多个布?yu)(dng)表辑ּ的组合,其组合结果仍然是一个布?yu)(dng)类型的。在E序q行Ӟ动作会(x)在条件过滤器gؓ(f)真的情况下执行。除了一般的执行动作Q还有三cL较特别的动作Q它们分别是Q放弃动作(Discard ActionQ、包含动作(Include ActionQ和使信息元对象内容持久化的动作。前两种动作cd的区别将?.3规则引擎工作机制节介绍?)队列理器(Queue ManagerQ队列管理器用来理来自不同信息服务的信息元对象的队列。下面将研究规则引擎的这些相x件是如何协同工作的。如?所C,处理q程分ؓ(f)四个阶段q行Q信息服务接受事件ƈ其转化Z息元Q然后这些信息元被传l队列管理器Q最后规则引擎接收这些信息元q应用它们自w携带的规则加以执行Q直到队列管理器中不再有信息元?</p><center><img src="http://www.85flash.com/Files/BeyondPic/2006-10/22/06102213335984478.gif" border="0" /></center><p></p><p style="TEXT-INDENT: 2em" align="center">? 处理q程协作?strong>3、规则引擎的工作机制</strong>下面专门研究规则引擎的内部处理过E。如?所C,规则引擎从队列管理器中依ơ接收信息元Q然后依规则的定义顺序检查信息元所带规则集中的规则。如图所C,规则引擎(g)查第一个规则ƈ对其条gqo(h)器求|如果gؓ(f)假,所有与此规则相关的动作皆被忽略ql执行下一条规则。如果第二条规则的过滤器gؓ(f)真,所有与此规则相关的动作皆依定义序执行Q执行完毕l下一条规则。该信息元中的所有规则执行完毕后Q信息元?yu)被销毁,然后从队列管理器接收下一个信息元。在q个q程中ƈ未考虑两个Ҏ(gu)动作Q放弃动作(Discard ActionQ和包含动作QInclude ActionQ。放弃动作如果被执行Q将?x)蟩q其所在信息元中接下来的所有规则,q毁所在信息元Q规则引擎l接攉列管理器中的下一个信息元。包含动作其实就是动作中包含其它现存规则集的动作。包含动作如果被执行Q规则引擎将暂停q进入被包含的规则集Q执行完毕后Q规则引擎还?x)返回原来暂停的地方l箋执行。这一q程递归q行?</p><center><img src="http://www.85flash.com/Files/BeyondPic/2006-10/22/06102213340025059.gif" border="0" /></center><p></p><p style="TEXT-INDENT: 2em" align="center">? 规则引擎工作机制Java规则引擎的工作机制与上述规则引擎机制十分cMQ只不过对上q概念进行了重新包装l合。Java规则引擎Ҏ(gu)交给引擎的Java数据对象q行(g)索,Ҏ(gu)q些对象的当前属性值和它们之间的关p,从加载到引擎的规则集中发现符合条件的规则Q创些规则的执行实例。这些实例将在引擎接到执行指令时、依照某U优先序依次执行。一般来ԌJava规则引擎内部׃面几个部分构成:(x)工作内存QWorking MemoryQ即工作区,用于存放被引擎引用的数据对象集合Q规则执行队列,用于存放被激zȝ规则执行实例;静态规则区Q用于存放所有被加蝲的业务规则,q些规则按照某U数据结构组l,当工作区中的数据发生改变后,引擎需要迅速根据工作区中的对象现状Q调整规则执行队列中的规则执行实例。Java规则引擎的结构示意图如图4所C?</p><center><img src="http://www.85flash.com/Files/BeyondPic/2006-10/22/06102213340010350.gif" border="0" /></center><p></p><p style="TEXT-INDENT: 2em" align="center">? Java规则引擎工作机制当引擎执行时Q会(x)Ҏ(gu)规则执行队列中的优先序逐条执行规则执行实例Q由于规则的执行部分可能?x)改变工作区的数据对象,从而会(x)佉K列中的某些规则执行实例因为条件改变而失效,必须从队列中撤销Q也可能?x)激zd来不满条g的规则,生成新的规则执行实例q入队列。于是就产生了一U“动态”的规则执行链,形成规则的推理机制。这U规则的“链式”反应完全是由工作区中的数据驱动的?M一个规则引擎都需要很好地解决规则的推理机制和规则条g匚w的效率问题。规则条件匹配的效率军_了引擎的性能Q引擎需要迅速测试工作区中的数据对象Q从加蝲的规则集中发现符合条件的规则Q生成规则执行实例?982q美国卡耐基·梅隆大学的Charles L. Forgy发明了一U叫Rete法Q很好地解决了这斚w的问题。目前世界顶的商用业务规则引擎产品基本上都使用Rete法?/p><img src ="http://www.tkk7.com/clant/aggbug/87951.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/clant/" target="_blank">BPM </a> 2006-12-15 15:19 <a href="http://www.tkk7.com/clant/articles/87951.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Q六Q? Drools规则语言详解Q上Q?http://www.tkk7.com/clant/articles/85146.htmlBPM BPM Sun, 03 Dec 2006 01:56:00 GMThttp://www.tkk7.com/clant/articles/85146.htmlhttp://www.tkk7.com/clant/comments/85146.htmlhttp://www.tkk7.com/clant/articles/85146.html#Feedback0http://www.tkk7.com/clant/comments/commentRss/85146.htmlhttp://www.tkk7.com/clant/services/trackbacks/85146.html Drools 规则语言详解Q上Q?br />

<!--[if !supportLists]--> 1Q?span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">  <!--[endif]--> 概述Q?/span>

Drools 3 采用了原生的规则语言Q那是一U非 XML 文本格式。在W号斚wQ这U格式是非常轻量的,q且通过?/span> expanders ”支持符合你问题域的 Domain Specific Language Q?/span> DSL Q。这一章把焦点攑֜?/span> Drools 原生的规则格式。如果你想从技术上了解规则语言的机Ӟ可以参考?/span> drl.g ”源文gQ这是用 Antlr3 语法来描q规则语a。如果你使用 Rule Workbench Q内容助手将?x)?f)你完成大量的规则l构Q例如输入?/span> ru ”,然后?/span> ctrl Q?/span> space Q会(x)Z建立规则l构?br />

<!--[if !supportLists]--> 1.1    <!--[endif]--> 规则文g

一个规则文仉常是一个以 .drl 扩展名结文g。在一?/span> drl 文g中,你可以有多条 rules Q?/span> functions {等。尽如此,你也可以你的规则分布在多个文g中,q有利于理大量的规则。一?/span> DRL 文g是一个简单的文本文g?/span>

1.2 规则的结?/span>

一个规则结构大致如下:(x)

rule  " name "
    ATTRIBUTES
    when
        LHS
    then
        RHS
end

可以看到Q这是非常简单的。通常的标点符号都是不需要的Q甚臌?/span> name ”的双引号都是不需要的?/span> ATTRIBUTES 是简单的Q也是可选的Q来提示规则的行为方式?/span> LHS 是规则的条g部分Q需要按照一定的语法来写?/span> RHS 基本上是一个允许执?/span> Java 语法的代码的块(以后会(x)支持 groovy ?/span> C Q)(j)。Q何在 LHS 中用的变量都可以在 RHS 中用?/span>

注意Q每行开始的I格是不重要的,除非?/span> DSL Q?/span> Domain Specific Language Q语a中有特别的指明?/span>

<!--[if !supportLists]--> 1.3   <!--[endif]--> Domain Specific Language

Domain Specific Language 是对原生规则语言的加强。它们用?/span> expander ”机制?/span> Expander 机制是一U可扩展?/span> API 。你可以使用 .dsl 文gQ来提供从域或自然语a到规则语a和你的域对象的映。你可以?/span> .dsl 文g看成是对你的域模型的映射?/span> DSL 提供了更高的规则可读性,你可以选择使用你自己创建的 DSL Q或者是原生的规则语a?/span>

1.4 保留?/span>

在规则语a中存在一些保留字。你应该避免使用q些保留字,来命名规则文本中的域对象Q属性,Ҏ(gu)Q功能。保留字如下Q?/span> when Q?/span> then Q?/span> rule Q?/span> end Q?/span> contains Q?/span> matches Q?/span> and Q?/span> or Q?/span> modify Q?/span> retract Q?/span> assert Q?/span> salience Q?/span> function Q?/span> query Q?/span> exists Q?/span> eval Q?/span> agenda-group Q?/span> no-loop Q?/span> duration Q?/span> -> Q?/span> not Q?/span> auto-focus ?/span>

<!--[if !supportLists]--> 2.   <!--[endif]--> 注释

2.1 单行注释Q?/span>

Figure 2.1. Single line comment

2.2 多行注释Q?br />

Figure 2.2. Multi line comment

<!--[if !supportLists]-->

3.     <!--[endif]--> Package

一个包?/span> rule 和其他相关结构,?/span> import ?/span> global 的集合?/span> Package 的成员之间通常都是相关联的。一?/span> Package 代表了一个命名空_(d) namespace Q,用来使给定的规则l之间保持唯一性?/span> Package 的名字本w就是命名空_(d)q且与文件或文g夹ƈ无关联?/span>

<!--[if !supportEmptyParas]-->

可以来自不同规则源的规则装配在一P前提是这些规则必d在同一个命名空间中。尽如此,一个通常的结构是处于同一个命名空间中的所有规则都攑֜同一个相同的文g中?/span>

下面?/span> rail-road 图显CZl成一?/span> Package 的所有组件。注意:(x)一?/span> package 必须有一个命名空_(d)q且采用 Java 包名的约定。在一个规则文件中Q各lg出现的位|是L的,除了?/span> package ”和?/span> expander ”语句必d现在M一个规则之前,攑֜文g的顶部。在M情况下,分号都是可选的?/span>


Figure 3.1. package
3.1 import

Figure 3.2. import

Import 语句的用很?/span> Java 中的 import 语句。你需要ؓ(f)你要在规则中使用的对象,指定完整的\径和cd?/span> Drools 自动从相同命名的 java 包中引入所需的类?/span>

3.2 expander

Figure 3.3. expander

expander 语句是可选的Q是用来指定 Domain Specific Language 的配|(通常是一?/span> .dsl 文gQ。这使得解析器可以理解用你自q DSL 语言所写的规则?/span>

3.3 global


Figure 3.4. global

Global 是全局变量。如果多?/span> package 声明了具有相同标识符?/span> global Q那么它们必需是相同的cdQƈ且所有的引用都是相同的。它们通常用来q回数据Q比?/span> actions 的日志,或者ؓ(f) rules 提供所需的数据或服务?/span> global q不是通过 assert 动作攑օ WorkingMemory 的,所有当 global 发生改变Ӟ引擎不?x)知道。所以, global 不能作ؓ(f)U束条gQ除非它们的值是 final 的。将 global 错误的用在U束条g中,?x)生o(h)人惊讶的错误l果?/span>

<!--[if !supportEmptyParas]-->

注意Q?/span> global 只是从你?/span> application 中传?/span> WorkingMemory 的对象的命名实例。这意味着你可以传入Q何你惌的对象。你可以传入一?/span> service locator Q或者是一?/span> service 本n?/span>

<!--[if !supportEmptyParas]-->

下面的例子中Q有一?/span> EmailService 的实例。在你调用规则引擎的代码中,你有一?/span> EmailService 对象Q然后把它放?/span> WorkingMemory 。在 DRL 文g中,你声明了一个类型ؓ(f) EmailService ?/span> global Q然后将它命名ؓ(f)?/span> email ”,像这P(x) global EmailService email Q。然后在你的规则?/span> RHS 中,你可以用它Q像q样Q?/span> email.sendSMS(number,message) {等?/span>

4. Function


Figure 4.1. function

Function 是将代码攑ֈ你的规则源中的一U方法。它们只能做cM Helper cd的事Q实际上~译器在背后帮你生成?/span> Helper c)(j)。在一?/span> rule 中?/span> function 的主要优势是Q你可以保持所有的逻辑都在一个地方,q且你可以根据需要来改变 function Q这可能是好事也可能是坏事)(j)?/span> Function 最有用的就是在规则?/span> RHS 调用 actions Q特别是当那?/span> action 需要反复调用的时候?/span>

<!--[if !supportEmptyParas]-->

一个典型的 function 声明如下Q?/span>

function String calcSomething(String arg) {
return   " hola ! " ;
}

<!--[if !supportEmptyParas]-->

注意Q?/span> function ”关键字的用,它ƈ不真正是 Java 的一部分。?/span> function 的参数就像是一个普通的 method Q如果不需要参数就不用写)(j)。返回类型也跟普通的 method 一栗在一条规则(在它?/span> RHS 中,或可能是一?/span> eval Q中调用 function Q就像调用一?/span> method 一P只需?/span> function 的名字,q传l它参数?/span>

<!--[if !supportEmptyParas]-->

function 的替代品Q可以用一?/span> Helper cM的静态方法:(x) Foo.doSomething() Q或者以 global 的方式传入一?/span> Helper cL服务的实例:(x) foo.doSomething() Q?/span> foo 是一个命名的 global 变量Q?/span>

<!--[if !supportEmptyParas]-->



BPM 2006-12-03 09:56 发表评论
]]>
Q七Q? Drools规则语言详解Q下Q?http://www.tkk7.com/clant/articles/85147.htmlBPM BPM Sun, 03 Dec 2006 01:56:00 GMThttp://www.tkk7.com/clant/articles/85147.htmlhttp://www.tkk7.com/clant/comments/85147.htmlhttp://www.tkk7.com/clant/articles/85147.html#Feedback0http://www.tkk7.com/clant/comments/commentRss/85147.htmlhttp://www.tkk7.com/clant/services/trackbacks/85147.html阅读全文

BPM 2006-12-03 09:56 发表评论
]]>
Q五Q? JBoss Rules 3.0.1 cd介绍 http://www.tkk7.com/clant/articles/85145.htmlBPM BPM Sun, 03 Dec 2006 01:55:00 GMThttp://www.tkk7.com/clant/articles/85145.htmlhttp://www.tkk7.com/clant/comments/85145.htmlhttp://www.tkk7.com/clant/articles/85145.html#Feedback0http://www.tkk7.com/clant/comments/commentRss/85145.htmlhttp://www.tkk7.com/clant/services/trackbacks/85145.html 下蝲地址Q?/span>

http://labs.jboss.com/portal/index.html?ctrl:id=page.default.downloads&project=jbossrules

下蝲文g说明Q?/span>

JBoss Rules 3.0.1 Binaries (includes javadocs) Q?/span> 13MB Q?/span> 仅仅包含 JBoss Rules 的四个核心类库:(x)

<!--[if !supportLists]--> l         <!--[endif]--> drools-core.jarQ?/span>核心引擎Q运行时lg。包含了RETE引擎?/span>LEAPS引擎Q?/span>

<!--[if !supportLists]--> l         <!--[endif]--> drools-compiler.jarQ?/span>规则文g的编译组Ӟ构徏可执行的RuleBaseQ?/span>

<!--[if !supportLists]--> l         <!--[endif]--> drools-jsr94.jarQ?/span>提供?/span>JSR-94的兼容实玎ͼ本质上是drools- compilerlg的包裹层。注意:(x)׃JSR94规约的限Ӟ不是所有的特点都可以通过此接口暴霌Ӏ?/span>

<!--[if !supportLists]--> l         <!--[endif]--> drools-decisiontables.jarQ?/span>决策表的“编译”组Ӟ使用?/span>drools- compilerlgQ。支?/span>excel?/span>CSV输入格式?/span>

JBoss Rules 3.0.1 Binaries with dependencies (includes javadocs) Q?/span> 23 MB Q- 包含?/span> JBoss Rules 的核心类库和它们?/span> dependencies Q?/span>

<!--[if !supportLists]--> l         <!--[endif]--> antlr-2.7.6.jar

<!--[if !supportLists]--> l         <!--[endif]--> antlr-3.0ea8.jar

<!--[if !supportLists]--> l         <!--[endif]--> colt-1.2.0.jar

<!--[if !supportLists]--> l         <!--[endif]--> commons-collections-3.1.jar

<!--[if !supportLists]--> l         <!--[endif]--> commons-io-1.1.jar

<!--[if !supportLists]--> l         <!--[endif]--> commons-jci-core-1.0-406301.jar

<!--[if !supportLists]--> l         <!--[endif]--> commons-jci-eclipse-3.2.0.666.jar

<!--[if !supportLists]--> l         <!--[endif]--> commons-jci-janino-2.4.3.jar

<!--[if !supportLists]--> l         <!--[endif]--> commons-lang-2.1.jar

<!--[if !supportLists]--> l         <!--[endif]--> commons-logging-api-1.0.4.jar

<!--[if !supportLists]--> l         <!--[endif]--> concurrent-1.3.4.jar

<!--[if !supportLists]--> l         <!--[endif]--> core-3.2.0.666.jar

<!--[if !supportLists]--> l         <!--[endif]--> janino-2.4.3.jar

<!--[if !supportLists]--> l         <!--[endif]--> jsr94-1.1.jar

<!--[if !supportLists]--> l         <!--[endif]--> jung-1.7.2.jar

<!--[if !supportLists]--> l         <!--[endif]--> junit-3.8.1.jar

<!--[if !supportLists]--> l         <!--[endif]--> poi-2.5.1-final-20040804.jar

<!--[if !supportLists]--> l         <!--[endif]--> stringtemplate-2.3b6.jar

<!--[if !supportLists]--> l         <!--[endif]--> xercesImpl-2.6.2.jar

<!--[if !supportLists]--> l         <!--[endif]--> xml-apis-1.0.b2.jar

<!--[if !supportLists]--> l         <!--[endif]--> xpp3-1.1.3.4.0.jar

<!--[if !supportLists]--> l         <!--[endif]--> xstream-1.1.3.jar

如果你运行在 Java 1.5 环境下,有一些类库,例如 XML libraries Q可以不需要。需要注意的cd有:(x)

?/span> JCI ”-q是 Apache Java Compiler Interface , 提供了运行时~译能力。可以通过 PackageBuilderConfiguration 实例来设定采?/span> eclipse ?/span> janino ~译器,默认?/span> eclipse Q?/span>

?/span> POI ”-提供了解?/span> Excel 文g的能力;

?/span> antlr ”-提供了解析规则语a的能力?/span>

JBoss Rules IDE 3.0.1 Q?/span> 13 MB Q- q是 JBoss Rules ?/span> Eclipse 插gQ只支持 Eclipse 3.2 或以上版本。它提供了运?/span> JBoss Rules 的所?/span> dependencies 。你可以创徏一?/span> Rule Project Q它能够Z~写规则文g提供自动完成的功能,q且它ؓ(f)你提供了 Agenda view Q?/span> WorkingMemory view Q?/span> Global Data view Q你可以通过 eclipse 视图很清楚的看到 Agenda Q?/span> WorkingMemory ?/span> Global Data 的情c(din)?/span>

你还可以通过 update site 来自动安装这个插?/span> ,URL 是:(x)

http://anonsvn.labs.jboss.com/labs/jbossrules/updates/drools-ide-update/

<!--[if !supportEmptyParas]--> <!--[endif]-->



BPM 2006-12-03 09:55 发表评论
]]>
Q三Q? Drools规则引擎 Q上Q?http://www.tkk7.com/clant/articles/85143.htmlBPM BPM Sun, 03 Dec 2006 01:54:00 GMThttp://www.tkk7.com/clant/articles/85143.htmlhttp://www.tkk7.com/clant/comments/85143.htmlhttp://www.tkk7.com/clant/articles/85143.html#Feedback0http://www.tkk7.com/clant/comments/commentRss/85143.htmlhttp://www.tkk7.com/clant/services/trackbacks/85143.html从今天开始,我们分两期来详l的介绍Drools规则引擎的原理,和各关键cȝ使用Ҏ(gu)?br />
Drools 规则引擎(?

1. 概述 :
Drools 分ؓ(f)两个主要部分Q构建( Authoring Q和q行Ӟ Runtime Q?br />
构徏的过E涉?qing)?/span> .drl ?/span> .xml 规则文g的创建,它们被读入一个解析器Q?/span> ANTLR 3 语法q行解析。解析器对语法进行正性的(g)查,然后产生一U中间结构?/span> descr ”, descr ?/span> AST 来描q规则?/span> AST 然后被传?/span> PackageBuilder Q由 PackagBuilder 来?/span> Packaged 对象?/span> PackageBuilder q承担着一些代码生和~译的工作,q些对于产生 Package 对象都时必需的?/span> Package
对象是一个可以配|的Q可序列化的Q由一个或多个规则l成的对象。下N明了上述q程Q?/font>
 
Figure 1.1
Authoring Components

RuleBase 是一个运行时lgQ它包含了一个或多个 Package 对象。可以在M时刻一?/span> Package 对象加入或移?/span> RuleBase 对象。一?/span> RuleBase 对象可以在Q意时d例化一个或多个 WorkingMemory 对象Q在它的内部保持对这?/span> WorkingMemory 的弱引用?/span> WorkingMemory ׃pd子组件组成。当应用E序中的对象?/span> assert q?/span> WorkingMemory Q可能会(x)D一个或多个 Activation 的生,然后?/span> Agenda 负责安排q些 Activation 的执行。下图说明了上述q程Q?/span>

 
Figure 1.2 . Runtime Components

2Q构建(AuthoringQ:(x)

主要有三个类用来完成构徏q程Q?/span>DrlParser, XmlParser ?/span> PackageBuilder。两个解析器cM传入?/span>Reader实例产生descr AST模型?/span>PackageBuilder提供了简便的APIQ你可以忽略那两个cȝ存在。这两个单的Ҏ(gu)是:(x)?/span>addPackageFromDrl”和?/span>addPackageFromXml”,两个都只要传入一?/span>Reader实例作ؓ(f)参数。下面的例子说明了如何从classpath中的xml?/span>drl文g创徏一?/span>Package对象。注意:(x)所有传入同一?/span>PackageBuilder实例的规则源Q都必须是在相同?/span>package 命名I间Q?/span>namespaceQ中?/span>

PackageBuilder builder = new PackageBuilder();
builder.addPackageFromDrl( 
new InputStreamReader( getClass().getResourceAsStream( "package1.drl" ) ) );
builder.addPackageFromXml( 
new InputStreamReader( getClass().getResourceAsStream( "package2.drl" ) ) );
Package pkg 
= builder.getPackage();


Figure 2.1 PackageBuilder

PackageBuilder是可以配|的Q?/span>PackageBuilderConfiguration。通常Q你可以指定另一?/span>parent ClassLoader和用什么编译器Q?/span>compilerQ,默认?/span>Eclipse JDT。下面显CZ如何指定JANINO~译器:(x)

PackageBuilderConfiguration conf = new PackageBuilderConfiguration();
conf.setCompiler( PackageBuilderConfiguration.JANINO );
PackageBuilder builder 
= new PackageBuilder( conf );

Figure 2.2 . PackageBuilderConfiguration

3
Q?/span>RuleBase:

Figure 3.1 . RuleBase

一?/span>RuleBase包含了多个将被用的规则包(packages of rulesQ。一?/span>RuleBase是可以序列化的,所以它可以被配|到JNDI或其他类似的服务。通常Q第一ơ用时Q一?/span>RuleBase被创建ƈ~存?/span>RuleBase?/span>RuleBaseFactory来实例化Q默认返回一?/span>ReteOO RuleBase。可以传入参数来指定采用ReteOO?/span>Leaps。然后,?/span>addPackageҎ(gu)加入Package实例。你可以加入有相同命名空_(d)namespaceQ的多个Package?/span>

RuleBase ruleBase  = RuleBaseFactory.newRuleBase();
ruleBase.addPackage(pkg);

Figure 3.2. RuleBaseFactory

一?/span> rulebase instance 是线E安全的Q所有你可以在你的应用中Q让一?/span> rulebase instance 在多个线E中׃n。对于一?/span> rulebase 的最通常的操作是产生一个新?/span> WorkingMemory ?/span>

q个 rulebase 保持着到它所产生?/span> WorkingMemoryd 的弱引用Q所以在长时间运行的 WorkingMemory 中,如果 rules 发生改变Q这?/span> WorkingMemory 可以即的根据最新的 rules q行更新Q而不必重?/span> WorkingMemory 。你也可以指?/span> RuleBase 不必保持一个弱引用Q但是你要保?/span> RuleBase 不用更新?/span>

ruleBase.newWorkingMemory();   //  maintains a weak reference.
ruleBase.newWorkingMemory(  false  );  //  do not maintain a weak reference

M时候, Package 可以被加入或U除Q所有的改变都会(x)被反映到现存?/span> WorkingMemory 中。不要忘了调?/span> fireAllRules() ?/span> Activations Ȁ发?/span>

ruleBase.addPackage( pkg  );   //  Add a package instance
ruleBase.removePackage(  " org.com.sample "   );   //  remove a package, and all its parts, by it's namespace
ruleBase.removeRule(  " org.com.sample " " my rule "  );  //  remove a specific rule from a namespace

虽然有删除一个单独规则的Ҏ(gu)Q但是却没有加入一个单独规则的Ҏ(gu)Q要辑ֈq个目的只有加入一个只有一条规则的 package Q?/span>

<!--[if !supportEmptyParas]-->

RuleBaseConfigurator 可以指定 RuleBase 的附加行为。在加入 RuleBase 后, RuleBaseConfiguration 变成不可变对象?/span>

RuleBaseConfiguration conf  =   new  RuleBaseConfiguration();

conf.setProperty( RuleBaseConfiguration.PROPERTY_ASSERT_BEHAVIOR,
                  RuleBaseConfiguration.WM_BEHAVIOR_EQUALITY );

RuleBase ruleBase 
=   new  ReteooRuleBase( conf );

两个主要的属性是Q?/span> PROPERT_ASSERT_BEHAVIOR ?/span> PROPERTY_LOGICAL_OVERRIDE_BEHAVIOR Q在以后的部分中?x)解释?j)。所有的属性值都?/span> RuleBaseConfiguration cM的静态域帔R?/span>


Figure 3.3 RuleBaseConfiguration



BPM 2006-12-03 09:54 发表评论
]]>
Q四Q? Drools规则引擎 Q下Q?http://www.tkk7.com/clant/articles/85144.htmlBPM BPM Sun, 03 Dec 2006 01:54:00 GMThttp://www.tkk7.com/clant/articles/85144.htmlhttp://www.tkk7.com/clant/comments/85144.htmlhttp://www.tkk7.com/clant/articles/85144.html#Feedback0http://www.tkk7.com/clant/comments/commentRss/85144.htmlhttp://www.tkk7.com/clant/services/trackbacks/85144.html Drools 规则引擎(?

4 Q?/span> WorkingMemory:

Figure 4.1 WorkingMemory

WorkingMemory 是运行时规则引擎的主要类。它保持了所有被 asserted q?/span> WorkingMemory 的数据的引用Q直到取消( retracted Q?/span> WorkingMemory 是有状态对象。它们的生命周期可长可短。如果从一个短生命周期的角度来同一个引擎进行交互,意味着你可以?/span> RuleBase 对象来ؓ(f)每个 session 产生一个新?/span> WorkingMemory Q然后在l束 session ?/span> discard q个 WorkingMemory Q生一?/span> WorkingMemory 是一个廉L(fng)操作Q。另一UŞ式,是在一个相当长的时间中Q例如一?/span> conversation Q,保持一?/span> WorkingMemory Qƈ且对于新?/span> facts 保持持箋的更新。当你希?/span> dispose 一?/span> WorkingMemory 的时候,最好的实践是调用 dispose() Ҏ(gu)Q此?/span> RuleBase 中对它的引用会(x)被移除(管q是一个弱引用Q。不怎样最后它?yu)?x)被当成垃圾收集掉。术?/span> WorkingMemory Actions 代表了对 WorkingMemory ?/span> assertions Q?/span> retractions ?/span> modifications ?/span>

4.1 Facts

Facts 是从你的应用中,?/span> assert q?/span> WorkingMemory 中的对象Q?/span> beans Q?/span> Facts 是规则可以访问的L?/span> java 对象。规则引擎中?/span> facts q不是?/span> clone ?/span> facts Q它只是持有C的应用中数据的引用?/span> Facts 是你的应用数据?/span> String 和其他没?/span> getter ?/span> setter 的类不是有效?/span> Fact 。这L(fng)cM能用域U束Q?/span> Field Constraints Q,因ؓ(f)使用域约束要依靠 JavaBean 标准?/span> getter ?/span> setter 来同对象交互?/span>

4.2 Assertion

“Assertion?/span> 是将 facts 告诉 WorkingMemory 的动作,例如 WorkingMemory.assertObject (yourObject) 。当?/span> assert 一?/span> fact Q它?yu)被(g)查是否匹配规则。这意味着所有的匚w工作会(x)?/span> assert 的过E中完成。尽如此,当你完成 assert facts 之后Q你q要调用?/span> fireAllRules() ”方法来执行规则?/span>

当一个对象被 assert 后,?x)返回一?/span> FactHandle 。这?/span> FactHandle 是一个代表在 Working Memory 中你?/span> asserted Object 的o(h)牌( token Q。当你希?/span> retract 或?/span> modify 一个对象的时候,q个令牌让你用来?/span> WorkingMemory q行交互?/span>

Cheese stilton  =   new  Cheese( " stilton " );
FactHandle stiltonHandle 
=  workingMemory.assertObject( stilton );

WorkingMeomry 有两U?/span> assertion 模式Q?/span> Equality ?/span> Identity Q默认是 Identity Q?/span>

Identity 模式?/span> WorkingMemory 使用一?/span> IdentityHashMap 来存储所有的 asserted Objects 。这个模式下Q当 asserted ?/span> Object 是同一个实例时Q它q回同一?/span> FactHandle ?/span>

Equality 模式?/span> WorkingMemory 使用一?/span> HashMap 来存储所有的 asserted Objects 。这个模式下Q当 asserted ?/span> Object 相等Ӟ它返回同一?/span> FactHandle ?/span>

Q?/span> WorkingMemory.assertObject(yourObjcet) 只是q行 assertion 的一U?/span> regular Ҏ(gu)Q还存在有一U称?/span> logical assertion 的动作)(j)?/span>

4.3 Retraction

基本上就?/span> assert 的逆操作。当?/span> retract 一?/span> fact Q?/span> WorkingMemory 不再跟t那?/span> fact 。Q何被 activated q依赖那?/span> fact 的规则将被取消。注意:(x)完全有可能存在某条规则是依赖于一?/span> fact 的“不存在”( non existence Q。在q种情况下, retract 一?/span> fact 导致一条规则被ȀzR对一?/span> Fact q行 Retraction Q必ȝ assert 时返回的那个 FactHandle 做ؓ(f)参数?/span>

Cheese stilton  =   new  Cheese( " stilton " );
FactHandle stiltonHandle 
=  workingMemory.assertObject( stilton );
.
workingMemory.retractObject( stiltonHandle );

4.4 Modification

当一?/span> Fact 被修改了Q会(x)通知规则引擎q行重新处理。在规则引擎内部实际上是Ҏ(gu)?/span> Fact q行 retract Q然后对新的 Object 再进?/span> assert 。要使用 modifyObject() Ҏ(gu)来通知 Working Memory Q被改变?/span> Object q不?x)自己通知规则引擎。注意:(x) modifyObject() Ҏ(gu)L要把被修改的 Object 做ؓ(f)W二参数Q这允怽把一个不可变对象替换为另一个新对象?/span>

Cheese stilton  =   new  Cheese( " stilton " );
FactHandle stiltonHandle 
=  workingMemory.assertObject( stilton );
.
stilton.setPrice( 
100  );
workingMemory.modifyObject( stiltonHandle, stilton );

4.5 Globals

Global 是一个能够被传进 WorkingMemory 但不需?/span> assert 的命名对象。大多数q些对象被用来作为静态信息或服务。这些服务被用在一条规则的 RHS Q或者可能是从规则引擎返回对象的一U方法?/span>

List list  =   new  ArrayListQ)(j);
workingMemory.setGlobal(
" list " , list);

setGlobal() Ҏ(gu)传进ȝ命名对象必须?/span> RuleBase 中所定义的具有相同的cdQ就是要同你的规则文件中?/span> Global 关键字所定义的类型相同)(j)Q否则会(x)抛出一?/span> RuntimeException 。如果一条规则在?/span> setGlobal 之前调用了定义的 Global Q会(x)抛出一?/span> NullPointerException ?/span>

4.6 Property Change Listener

如果你的 fact 对象?/span> JavaBean Q你可以为它们实C?/span> property change listener Q然后把它告诉规则引擎。这意味着Q当一?/span> fact 改变Ӟ规则引擎会(x)自动知道Qƈq行响应的动作(你不需要调?/span> modifyObject() Ҏ(gu)来通知 WorkingMemory Q?/span> Proxy libraries 会(x)帮助实现q一切。要?/span> Property Change Listener 生效Q还要将 fact 讄为动态( dynamic Q模式,通过?/span> true 做ؓ(f) assertObject() Ҏ(gu)的第二个参数来实玎ͼ(x)

Cheese stilton  =   new  Cheese( " stilton " );
FactHandle stiltonHandle 
=  workingMemory.assertObject( stilton,  true  );   // specifies t hat this is a dynamic fact

然后要在 JavaBean 中加入一?/span> PropertyChangeSupport 实例Q和两个Ҏ(gu)Q?/span> addPropertyChangeListener() ?/span> removePropertyChangeListener() 。最后要?/span> JavaBean ?/span> setter Ҏ(gu)中通知 PropertyChangeSupport 所发生的变化。示例代码如下:(x)

private   final  PropertyChangeSupport changes  =   new  PropertyChangeSupport(  this  );

public   void  addPropertyChangeListener( final  PropertyChangeListener l) {
    
this .changes.addPropertyChangeListener( l );
}

public   void  removePropertyChangeListener( final  PropertyChangeListener l) {
    
this .changes.removePropertyChangeListener( l );
}

public   void  setState( final  String newState) {
    String oldState 
=   this .state;
    
this .state  =  newState;
this .changes.firePropertyChange(  " state " , oldState, newState );


5. Agenda:


Figure 5.1 . Agenda

Agenda ?/span> RETE 的一个特炏V在一?/span> WorkingMemory Action 发生Ӟ可能?x)有多条规则发生完全匚w。当一条规则完全匹配的时候,一?/span> Activation p创徏Q引用了q条规则和与其匹配的 facts Q,然后放进 Agenda 中?/span> Agenda 通过使用冲突解决{略Q?/span> Conflict Resolution Strategy Q来安排q些 Activations 的执行?/span>

引擎工作在一个?/span> 2 阶段”模式下Q?/span>

<!--[if !supportLists]--> 1Q?span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">  <!--[endif]--> WorkingMemory Actions Q?/span>assert新的factsQ修改存在的facts?/span>retract facts都是WorkingMemory Actions。通过在应用程序中调用fireAllRules()Ҏ(gu)Q会(x)使引擎{换到Agenda Evaluatioin阶段?/span>

<!--[if !supportLists]--> 2Q?span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">  <!--[endif]--> Agenda Evaluation Q尝试选择一条规则进行激发(fireQ。如果规则没有找到就退出,否则它就试Ȁ发这条规则,然后转换?/span>WorkingMemory Actions阶段Q直?/span>Agenda中ؓ(f)I?/span>

q个q程一直重复,直到 Agenda 是空的,此时控制权就回到应用E序中。。当 WorkingMemory Actions 发生Ӟ没有规则正在被激发?/span>

下图说明了这个@环的q程Q?/span>


Figure  5.2 . Two Phase Execution

5 Q?/span> 1 Conflict Resultion

当有多条 rules ?/span> agenda 中,需要解军_H。当Ȁ发一条规则时Q会(x)?/span> WorkingMemory 产生副作用。规则引擎需要知道规则要以什么顺序来Ȁ发(例如Q激?/span> rule A 可能?x)引?/span> rule B 被从 agenda 中移除。)(j)

Drools 采取的冲H解决策略有 2 U,按照优先U排列如下:(x) Salience Q?/span> LIFO Q后q先出)(j)。最易懂的策略是?/span> Salience ”,即优先Q?/span> user 可以为某?/span> rule 指定一个高一点的优先U(通过附给它一个比较大的数字)(j)。高 Salience ?/span> rule 会(x)被优先激发?/span>

5 Q?/span> 2 Agenda Groups

Agenda Groups 是划?/span> Agenda ?/span> rules Q其实是?/span> activations ”)(j)的一U方法。在L一个时刻,只有一?/span> group 拥有?/span> focus ”,q意味着只有在那?/span> group 中的 activations 才是有效的?/span>

Agenda Groups 是在 grouped rules 之间创徏一个“流”( flow Q的便的Ҏ(gu)。你可以在规则引擎中Q或是用 API 来切换具有焦点的l。如果你的规则有很明的多“阶D”( phases Q或多“序列”( sequences Q的处理Q可以考虑?/span> Agenda Groups 来达到这个目的?/span>

每次调用 setFocus() Ҏ(gu)的时候,那个 Agenda Group ׃(x)被压入一个堆栈,当这个有焦点的组为空Ӟ它就?x)被弹出Q然后下一个组׃(x)被执行。一?/span> Agenda Group 可以出现在堆栈的多个位置。默认的 Agenda Group 是?/span> MAIN ”,所有没有被指定 Agenda Group ?/span> Activations 都被攑ֈ那个l中Q这个组L被放在堆栈的W一个组Qƈ默认l予焦点?/span>

5 Q?/span> 3  Agenda Filters


Figure 5.3. Agenda Filter

Filter 必须实现 AgendaFilter 接口Q用来允许或止一?/span> activation 能够被激发?/span> Drools 提供了下面几U方便的默认实现Q?/span>

<!--[if !supportLists]--> ·         <!--[endif]--> RuleNameEndWithAgendaFilter

<!--[if !supportLists]--> ·         <!--[endif]--> RuleNameEqualsAgendaFilter

<!--[if !supportLists]--> ·         <!--[endif]--> RuleNameStartsWithAgendaFilter

要用一?/span> filter p在调?/span> fireAllRules() Ҏ(gu)的时候指定它。下面的例子对所有名字以?/span> Test ”结规则q行qo(h)Q?/span>

workingMemory.fireAllRules(  new  RuleNameEndsWithAgendaFilter(  " Test "  ) );

6Q事件模型( Event Model Q?/span>

Event 包里提供了规则引擎的事g机制Q包括规则激发,对象?/span> asserted {等。你可以使用事g机制来进?/span> AOP ~程?/span>

有两U类型的 Event Listener Q?/span> WorkingMemoryEventListener ?/span> AgendaEventListener ?/span>


Figure 6.1. WorkingMemoryEventListener


Figure 6.2  AgendaEventListener

对两?/span> EventListener 接口都提供了默认实现Q但在方法中q没有做M事。你可以l承q两个默认实现来完成你自q实现Q?/span> DefaultAgendaEventListener ?/span> DefaultWorkingMemoryEventListener 。下面代码说明了如何扩展一?/span> DefaultAgendaEventListner q把它加?/span> WorkingMemory 中,例子中只完成?/span> afterActivationFired() Ҏ(gu)Q?/span>

workingMemory.addEventListener(  new  DefaultAgendaEventListener() {                            
   
public   void  afterActivationFired(AfterActivationFiredEvent event) {
       
super .afterActivationFired( event );
       System.out.println( event );
   }
   
});

Drools 也提供了 DebugWorkingMemoryEventListener ?/span> DebugAgendaEventListener 两个实现c,在这两个cȝҎ(gu)中实C debug 信息的输出:(x)

workingMemory.addEventListener(  new  DebugWorkingMemoryEventListener() );




BPM 2006-12-03 09:54 发表评论
]]>
Q二Q? RETE法 http://www.tkk7.com/clant/articles/85142.htmlBPM BPM Sun, 03 Dec 2006 01:53:00 GMThttp://www.tkk7.com/clant/articles/85142.htmlhttp://www.tkk7.com/clant/comments/85142.htmlhttp://www.tkk7.com/clant/articles/85142.html#Feedback0http://www.tkk7.com/clant/comments/commentRss/85142.htmlhttp://www.tkk7.com/clant/services/trackbacks/85142.html?/font> JBoss Rules 学习(fn)Q一Q?什么是Rule 中,我们介绍了JBoss Rules中对Rule的表C,其中提到了JBoss Rule中主要采用的RETE法来进行规则匹配。下面将详细的介l一下RETE法在JBoss Rule中的实现Q最后随便提一下JBoss Rules中也可以使用的另一U规则匹配算法Leaps?br />
1.Rete Q?br />

Rete 在拉丁语中是 ”net?/span> Q有|络的意思?/span> RETE 法可以分ؓ(f)两部分:(x)规则~译Q?/span> rule compilation Q和q行时执行( runtime execution Q?/span>

~译法描述了规则如何在 Production Memory 中生一个有效的辨别|络。用一个非技术性的词来_(d)一个L别网l就是用来过滤数据。方法是通过数据在网l中的传播来qo(h)数据。在端节点会(x)有很多匹配的数据。当我们着|络向下赎ͼ匚w的数据将?x)越来越。在|络的最底部是终端节点( terminal nodes Q。在 Dr Forgy ?/span> 1982 q的论文中,他描qC 4 U基本节点:(x) root , 1-input, 2-input and terminal 。下图是 Drools 中的 RETE 节点cdQ?/span>

 

Figure 1. Rete Nodes

根节点( RootNode Q是所有的对象q入|络的入口。然后,从根节点立即q入?/span> ObjectTypeNode ?/span> ObjectTypeNode 的作用是使引擎只做它需要做的事情。例如,我们有两个对象集Q?/span> Account ?/span> Order 。如果规则引擎需要对每个对象都进行一个周期的评估Q那?x)浪费很多的旉。ؓ(f)了提高效率,引擎只让匹?/span> object type 的对象通过到达节点。通过q种Ҏ(gu)Q如果一个应?/span> assert 一个新?/span> account Q它不会(x)?/span> Order 对象传递到节点中。很多现?/span> RETE 实现都有专门?/span> ObjectTypeNode 。在一些情况下Q?/span> ObjectTypeNode 被用散列法进一步优化?/span>

Figure 2 . ObjectTypeNodes

ObjectTypeNode 能够传播?/span> AlphaNodes, LeftInputAdapterNodes ?/span> BetaNodes ?/span>

1-input 节点通常被称?/span> AlphaNode ?/span> AlphaNodes 被用来评估字面条Ӟ literal conditions Q。虽?dng)?/span> 1982 q的论文只提C相等条gQ指的字面上相等Q,很多 RETE 实现支持其他的操作。例如, Account.name = = “Mr Trout? 是一个字面条件。当一条规则对于一U?/span> object type 有多条的字面条gQ这些字面条件将被链接在一赗这是说Q如果一个应?/span> assert 一?/span> account 对象Q在它能到达下一?/span> AlphaNode 之前Q它必须先满第一个字面条件。在 Dr. Forgy 的论文中Q他?/span> IntraElement conditions 来表q。下面的图说明了 Cheese ?/span> AlphaNode l合Q?/span> name = = “cheddar?/span> Q?/span> strength = = “strong?/span> Q:(x)


Figure 3. AlphaNodes

Drools 通过散列法优化了?/span> ObjectTypeNode ?/span> AlphaNode 的传播。每ơ一?/span> AlphaNode 被加C?/span> ObjectTypeNode 的时候,׃字面| literal value Q作?/span> key Q以 AlphaNode 作ؓ(f) value 加入 HashMap 。当一个新的实例进?/span> ObjectTypeNode 的时候,不用传递到每一?/span> AlphaNode Q它可以直接?/span> HashMap 中获得正的 AlphaNode Q避免了不必要的字面(g)查?/span>

<!--[if !supportEmptyParas]-->

2-input 节点通常被称?/span> BetaNode ?/span> Drools 中有两种 BetaNode Q?/span> JoinNode ?/span> NotNode ?/span> BetaNodes 被用来对 2 个对象进行对比。这两个对象可以是同U类型,也可以是不同cd?/span>

我们U定 BetaNodes ?/span> 2 个输入称为左边( left Q和双Q?/span> right Q。一?/span> BetaNode 的左边输入通常?/span> a list of objects 。在 Drools 中,q是一个数l。右边输入是 a single object 。两?/span> NotNode 可以完成?/span> exists ’检查?/span> Drools 通过烦(ch)引应用在 BetaNodes 上扩展了 RETE 法。下囑ֱCZ一?/span> JoinNode 的用:(x)

Figure 4 . JoinNode


注意到图中的左边输入用到了一?/span> LeftInputAdapterNode Q这个节点的作用是将一?/span> single Object 转化Z个单对象数组Q?/span> single Object Tuple Q,传播?/span> JoinNode 节点。因为我们上面提到过左边输入通常?/span> a list of objects ?/span>

<!--[if !supportEmptyParas]-->

Terminal nodes 被用来表明一条规则已l匹配了它的所有条Ӟ conditions Q?/span> 在这点,我们说这条规则有了一个完全匹配( full match Q。在一些情况下Q一条带有“或”条件的规则可以有超q一个的 terminal node ?/span>

Drools 通过节点的共享来提高规则引擎的性能。因为很多的规则可能存在部分相同的模式,节点的共享允许我们对内存中的节点数量q行压羃Q以提供遍历节点的过E。下面的两个规则共享了部分节点Q?/span>

rule
    when
        Cheese( $chedddar : name 
==   " cheddar "  )
        $person : Person( favouriteCheese 
==  $cheddar )
    then
        System.out.println( $person.getName() 
+   "  likes cheddar "  );
end


rule
    when
        Cheese( $chedddar : name 
==   " cheddar "  )
        $person : Person( favouriteCheese 
!=  $cheddar )
    then
        System.out.println( $person.getName() 
+   "  does likes cheddar "  );
end

q里我们先不探讨q两?/span> rule 到的是什么意思,单从一个直观的感觉Q这两条 rule 在它们的 LHS 中基本都是一L(fng)Q只是最后的 favouriteCheese Q一条规则是{于 $cheddar Q而另一条规则是不等?/span> $cheddar 。下面是q两条规则的节点图:(x)

Figure 5 . Node Sharing

从图上可以看刎ͼ~译后的 RETE |络中, AlphaNode 是共享的Q?/span> BetaNode 不是׃n的。上面说的相{和不相{就体现?/span> BetaNode 的不同。然后这两条规则有各自的 Terminal Node ?/span>

<!--[if !supportEmptyParas]-->

RETE 法的第二个部分是运行时Q?/span> runtime Q。当一个应?/span> assert 一个对象,引擎数据传递到 root node 。从那里Q它q入 ObjectTypeNode q沿着|络向下传播。当数据匚w一个节点的条gQ节点就它记录到相应的内存中。这样做的原因有以下几点Q主要的原因是可以带来更快的性能。虽然记住完全或部分匚w的对象需要内存,它提供了速度和可伸羃性的特点。当一条规则的所有条仉满Q这是完全匚w。而只有部分条件满I是部分匚w。(我觉得引擎在每个节点都有其对应的内存来储存满节点条g的对象,q就造成了如果一个对象是完全匚wQ那q个对象׃(x)在每个节点的对应内存中都存有其映象。)(j)

2. Leaps 法Q?/span>

Production systems ?/span> Leaps 法使用了一U?/span> lazy ”方法来评估条gQ?/span> conditions Q。一U?/span> Leaps 法的修改版本的实现Q作?/span> Drools v3 的一部分Q尝试结?/span> Leaps ?/span> RETE Ҏ(gu)的最好的特点来处?/span> Working Memory 中的 facts ?/span>

古典?/span> Leaps Ҏ(gu)所有的 asserted ?/span> facts Q按照其?/span> asserted ?/span> Working Memory 中的序Q?/span> FIFO Q,攑֜d栈中。它一个个的检?/span> facts Q通过q代匚w data type ?/span> facts 集合来找出每一个相兌则的匚w。当一个匹配的数据被发现时Q系l记住此时的q代位置以备待会(x)的lP代,q且Ȁ发规则结果( consequence Q。当l果Q?/span> consequence Q执行完成以后,pȝ׃(x)l箋处理处于d栈顶部的 fact 。如此反复?/span>



BPM 2006-12-03 09:53 发表评论
]]>
Q一Q? 什么是Rule http://www.tkk7.com/clant/articles/85141.htmlBPM BPM Sun, 03 Dec 2006 01:52:00 GMThttp://www.tkk7.com/clant/articles/85141.htmlhttp://www.tkk7.com/clant/comments/85141.htmlhttp://www.tkk7.com/clant/articles/85141.html#Feedback0http://www.tkk7.com/clant/comments/commentRss/85141.htmlhttp://www.tkk7.com/clant/services/trackbacks/85141.html          学习(fn)JBoss Rules有几天了Q因斚w的中文资料较?yu),所以这几天都在看官|上的manual。这是一份不错的教程Q我把我看的一些重要的东西译整理了一下,希望可以Ҏ(gu)学习(fn)JBoss Rules的同学们提供一点帮助?br />       在开始这份教E之前,我先要介l一下JBoss RulesQ?br />       JBoss Rules 的前w是Codehaus的一个开源项目叫Drools。最q被U_JBoss门下Q更名ؓ(f)JBoss RulesQ成ZJBoss应用服务器的规则引擎?br />       Drools是ؓ(f)Java量n定制的基于Charles  Forgy的RETE法的规则引擎的实现。具有了OO接口的RETE,使得商业规则有了更自然的表达?br /> 
       既然JBoss Rules是一个商业规则引擎,那我们就要先知道到底什么是RulesQ即规则。在JBoss Rules中,规则是如何被表示?br />

Rules

      一条规则是对商业知识的~码。一条规则有 attributes Q一?/span> Left Hand Side Q?/span> LHS Q和一?/span> Right Hand Side Q?/span> RHS Q?/span> Drools 允许下列几种 attributes Q?/span> salience Q?/span> agenda-group Q?/span> no-loop Q?/span> auto-focus Q?/span> duration Q?/font> activation-group ?/span>

rule ?/span> < name > ”   ?br />     < attribute >   < value >     
    when        
        
< LHS >     
    then        
        
< RHS >
end

      规则?/span> LHS ׃个或多个条gQ?/span> Conditions Q组成。当所有的条gQ?/span> Conditions Q都满qؓ(f)真时Q?/span> RHS 被执行?/span> RHS 被称为结果( Consequence Q?/span> LHS ?/span> RHS cM于:(x)
if  (  < LHS >  ) {
    
< RHS >
}

      规则可以通过 package 关键字同一个命名空_(d) namespace Q相兌Q其他的规则引擎可能U此则集Q?/span> Rule Set Q。一?/span> package 声明?/span> imports Q?/span> global 变量Q?/span> functions ?/span> rules ?/span>


package  com.sample

import  java.util.List
import  com.sample.Cheese

global List cheeses

function 
void  exampleFunction(Cheese cheese) {
    System.out.println( cheese );
}

rule “A Cheesy Rule?br />    when
        cheese : Cheese( type 
==   " stilton "  )
    then
        exampleFunction( cheese );
        cheeses.add( cheese );
end

      Ҏ(gu)的数据和被修改的数据q行规则的匹配称为模式匹配( Pattern Matching Q。进行匹配的引擎UCؓ(f)推理机( Inference Engine Q。被讉K的规则称?/span> ProductionMemory Q被推理行匹配的数据UCؓ(f) WorkingMemory ?/span> Agenda 理被匹配规则的执行。推理机所采用的模式匹配算法有下列几种Q?/span> Linear Q?/span> RETE Q?/span> Treat Q?/span> Leaps ?/span>

      Drools 采用?/span> RETE ?/span> Leaps 的实现?/span> Drools ?/span> RETE 实现被称?/span> ReteOO Q表C?/span> Drools ?/span> Rete 法q行了加强和优化的实现?/span>



      一条规则的 LHS ?/span> Conditional Element 和域U束Q?/span> Field Constraints Q。下面的例子昄了对一?/span> Cheese Fact 使用了字面域U束Q?/span> Literal Field Constraint Q?/span>

rule  " Cheddar Cheese "
    when
        Cheese( type 
==   " cheddar "  )
    then
        System.out.println( 
" cheddar "  );
end

上面的这个例子类gQ?/span>

public   void  cheddarCheese(Cheese cheese) {
    
if  ( cheese.getType().equals( " cheddar " ) {
        System.out.println( 
" cheddar "  );
    }
}
<!--[if !vml]--> <!--[endif]-->

      规则引擎实现了数据同逻辑的完全解耦。规则ƈ不能被直接调用,因ؓ(f)它们不是Ҏ(gu)或函敎ͼ规则的激发是?/span> WorkingMemory 中数据变化的响应。结果( Consequence Q即 RHS Q作?/span> LHS events 完全匚w?/span> Listener ?/span>

?/span> rules 被加?/span> Productioin Memory 后, rules 被规则引擎用 RETE 法分解成一个图Q?/span>



      ?/span> Facts ?/span> assert q入 WorkingMemory 中后Q规则引擎找到匹配的 ObjectTypeNode Q然后将?/span> Fact 传播C一个节炏V?/span> ObjectTypeNode 拥有一块内存来保存所有匹配的 facts 。在我们的例子中Q下一个节Ҏ(gu)一个域U束Q?/span> Field Constraint Q, type = = “cheddar?/span> 。如果某?/span> Cheese 对象的类型不是?/span> cheddar ”,q个 fact 不?x)被传播到网l的下一个节炏V如果是?/span> cheddar ”类型,它将被记录到 AlphaNode 的内存中Qƈ传播到网l的下一个节炏V?/span> AlphaNode 是古?/span> RETE 术语Q它是一个单输入 / 单输出的节点。最后通过 AlphaNode ?/span> fact 被传播到 Terminal Node ?/span> Terminal Node 是最l节点,到此我们说这条规则被完全匚wQƈ准备Ȁ发?/span>

      当一条规则被完全匚wQ它q没有立刻被Ȁ发(?/span> RETE 中是q样Q但?/span> Leaps 中它?x)立刻被Ȁ发)(j)。这条规则和与其匚w?/span> facts 激z被攑օ Agenda Q由 Agenda 来负责安排激?/span> Activations Q指的是 rule + the matched facts Q?/span>

下面的图很清楚的说明?/span> Drools 规则引擎的执行过E:(x)


   数据?/span> assert q?/span> WorkingMemory 后,?/span> RuleBase 中的 rule q行匚wQ确切的说应该是 rule ?/span> LHS Q,如果匚w成功q条 rule q同和它匚w的数据(此时叫?/span> Activation Q一赯攑օ Agenda Q等?/span> Agenda 来负责安排激?/span> Activation Q其实就是执?/span> rule ?/span> RHS Q,上图中的菱Ş部分是?/span> Agenda 中来执行的, Agenda ׃(x)Ҏ(gu)冲突解决{略来安?/span> Activation 的执行顺序?/span>



BPM 2006-12-03 09:52 发表评论
]]>
վ֩ģ壺 ëƬ߹ۿ| Ʒۺһ߹ۿ| AV12þ| ͬgayƬ| պƷרѲ| ѹۿһëƬa| ޾Ʒmv߹ۿ| ˳ƵƵ| ѿŮͰ| ޸Ƶַ| 99þ99ֻѵľƷ| ߹ۿƵ| ޹˾ƷӰ| ˳Ƶۿ| av߹ۿ| ޾ƷVĻ| ĻĴȫƵ| ɫվWWW| ˳ɵӰ߹ۿ| ѹ˦Ƭ| ݺۺɫ| һ234| ֻˬֳƵ| ޴Ƭ߹ۿ| Ļ߹ۿ| ۺ ŷ ˿| Ů߹ۿ| ɫһƵ| ĻƵ| þþӰԺ޾Ʒ| | ޵һҳպר| Ʒպһ| Ƶ| 18| ѻɫַ| ˳ۺ | ۺɫɫ| ޾Ʒ͵Ƶѹۿ| ޹˾þۺ| ޾ƷAVƬ|