Drools手册译.docx
《Drools手册译.docx》由会员分享,可在线阅读,更多相关《Drools手册译.docx(19页珍藏版)》请在冰豆网上搜索。
Drools手册译
Chapter 1. TheRuleEngine
1.1. WhatisaRuleEngine
1.1.1IntroductionandBackground
A.I.(ArtificialIntelligence)是一个关注于“使计算机像人类一样思考“的广泛的研究领域,包括NeuralNetworks(神经网络),GeneticAlgorithms(遗传算法),DecisionTrees(决策树),FrameSystems(框架系统)andExpertSystems(专家系统)。
Knowledgerepresentation(知识表示)是A.I.的一部分,关心怎样表示和操作知识。
专家系统使用知识表示把知识编码简化成一个可用于推理的知识库──比如,我们可以用知识库处理数据以推出结论。
专家系统又叫基于知识的系统、基于知识的专家系统,并被认为是A.I.的一个应用。
TheprocessofdevelopingwithanExpertSystemisKnowledgeEngineering。
EMYCIN是最早的专家系统Shell(外壳)之一,它从医学诊断专家系统MYCIN发展而来。
早期的专家系统有自己的logichardcoded"shells"(逻辑硬件编码外壳),把逻辑与系统相分离,为用户输入提供一个简单的使用环境。
Drools是一个使用基于规则的方法实现的专家系统的规则引擎,更准确的说属于产生式规则系统。
规则引擎这个术语是非常不明确的,因为任何以任意形式使用能够应用于数据生成结果的规则的系统都可以称为规则引擎。
规则引擎包括像formvalidationanddynamicexpressionengines这样的简单系统。
"HowtoBuildaBusinessRulesEngine(2004)"byMalcolmChisholm例证了这种不明确性。
……ProductionRuleSystem(产生式规则系统)是一种规则引擎,也是专家系统,thevalidationandexpressionevaluationRuleEnginesmentionpreviouslyarenotExpertSystems。
一个ProductionRuleSystem完全关注于精确表达propositional(命题)和firstorderlogic(一阶逻辑)的知识表示,nonambigiousanddeclarativemanner。
ProductionRuleSystem的核心是一个能够scaleto大量规则和事实的InferenceEngine(推理引擎)。
InferenceEngine将事实、数据与产生式规则(也可以叫做产生式,或干脆叫规则)进行匹配,以推出结论。
一个产生式规则分为两部分,用一阶逻辑表示知识。
when
then
将新的或已存在的事实与产生式规则进行匹配的过程被称为模式匹配,这个过程由推理机完成。
推理机使用的用于模式匹配的算法有很多,包括:
Linear,Rete,Treat,Leaps。
Drools即使用Rete也使用Leaps。
Leaps是实验性的,因为它是个新算法。
Drools中的Rete算法被称为ReteOO,表示Drools为面向对象系统(ObjectOrientedsystems)增强并优化了Rete算法。
其它基于Rete算法的引擎也有他们对Rete算法进行独有增强后的市场术语,比如RetePlus,ReteIII。
要知道象ReteIII这样的名字纯粹是市场性的,不像原始版本的Rete算法,它们没有公布实现细节,这一点很重要;因此,问类似于“Drools是用ReteIII实现的吗?
”的问题是没有任何意义的。
最寻常的对Rete算法的增强在下面这篇文章中有论述"ProductionMatchingforLargeLearningSystems(Rete/UL)"(1995)byRobertB.Doorenbos
规则存在ProductionMemory(规则库)中,推理机要匹配的facts(事实)存在WorkingMemory(工作内存)中。
事实被插入到工作内存中后,可能被修改或删除。
一个有大量规则和事实的系统可能会很多规则被满足,这些规则被称为beinconflict。
Agenda(议程)通过ConflictResolutionstrategy(冲突决策策略)管理这些conflictingrules的执行顺序。
一个产生式规则系统的推理机是stateful(有状态的)并且能够TruthMaintence(真值维护)。
……
一个产生式规则系统有两个执行方法──ForwardChainingandBackwardChaining,两种方法都用的系统叫做混合(hybrid)产生式规则系统。
理解这两种操作方法是理解产生式规则系统之所以不同和怎样从中选择最好系统的关键。
Forwardchaing是'data-driven'……Drools是Forwardchaing引擎。
Backwardchaining是'goal-driven'……Prolog是一个Backwardchaining引擎。
Drools在其下一个主要版本将加入对Backwardchaining的支持。
1.2. WhyuseaRuleEngine
1.2.1Summaryofadvantagesofaruleengine
逻辑与数据分离
1.2.2Whenshouldyouusearuleengine(译的不完整)
对这个问题最简短的回答就是“当没有令人满意的传统的程序设计方法能够解决这个问题时”。
如果你曾注意到在你的代码中有很多刚刚觉得不对的”if””else””switch”和其它凌乱的逻辑,你总是要回过头去修改它们(可能是由于提供给你的逻辑是错误的,或是由于逻辑或者你的理解变化了),那么可以考虑使用规则。
如果你所面对的问题没有算法能够解决,考虑使用规则
1.2.3Whennottousearuleengine
这里引用Drools邮件发送清单中的话(DaveHamu):
“在我看来,在使用规则引擎的兴奋中,人们忘记了规则引擎只是一个复杂的应用或方法中的一部分。
实际上,规则引擎不是用于规则的工作流引擎或进程管理工具。
对特定的工作要使用恰当的工具。
当然,必要时一对老虎钳可以当作锤子用,但那并不是发明老虎钳的本意。
”
1.4ReteAlgorithm
正如所看到的,编译后的Rete网表明,Alpha结点是共享的。
但是Beta结点不共享,每一个都有自己的终结点;如果第二个模式相同,也将被共享。
1.3. KnowledgeRepresentation
1.3.1. ProductionRules
Drools中的产生式规则(或者说规则)结构分为两部分:
LeftHandSide(LHS)和RightHandSide(RHS),此外,规则可能有如下的属性:
salience,agenda-group,auto-focus,activation-group,no-loop,duration。
rule“”
when
then
end
规则的LHS包括ConditionalElements(CE)和Columns,以简化propositionalandfirstorderlogic(命题和一阶逻辑)的编码。
Colunm表示对一个fact(事实)的FieldConstraints(域约束)。
目前Drools支持下面的CEs:
And,or,not,exitsts,很快还会加上forall和accumulate。
允许下面的FieldConstraints:
LiteralConstraint,BoundVariableConstraint,ReturnValue,Predicate。
第三章提供了关于这些内容的深入的学习。
规则通过package关键字与一个namespace(命名空间)相关联,其他规则引擎可能称此为RuleSet(规则集)。
一个Package声明imports,globalvariables,functions和rules。
规则引擎实现了数据和逻辑的完全解耦。
1.3.2. FirstOrderLogic
规则用FirstOrderLogic(一阶逻辑)或predicatelogic(谓词逻辑)──扩展了PropositionalLogic(命题逻辑)──书写。
命题是一个可以判断真假的陈述。
在Java中,一个简单的命题包括'variable''operator''value',这里我们经常把value作为literalvalue(字面值)。
一个命题可以被认为是一个fieldconstraint。
命题间可用'&&'and'||'连接。
1.6. TheDroolsRuleEngine
……
Chapter 2. InstallationandSetup
2.1Installingandusing
Drools提供了一个基于Eclipse的IDE,但其核心只要求Java1.4(J2SE)。
一个简单的开始Drools的方法是下载并安装Eclipse插件。
这样将为你提供你需要的所有的东西:
可以简单的创建一个新的规则工程并且所的工作都已经做好了。
2.1.3InstallingIDE(RuleWorkbench)
EclipseIDE要求Eclipse3.2或更高版本。
既可以通过下载插件来安装,也可以通过Updatesite安装。
2.1.3.1Installingfromzipfile
要从Zip文件安装,需要下载并解压Zip文件。
在压缩包里有一个Plugin目录,和Pluginjar。
将这个Pluginjar放到Eclipse程序的Plugin目录下,并启动Eclipse。
2.1.3.2Installingfromtheupdatesite
使用Updatesite安装是一个很方便的方法,并能保持最新版本(Eclipse会应需求检查更新)。
一些防火墙可能会使在Eclipse中使用Updatesites有麻烦,如果遇到这样的问题,请从插件手动安装。
同时,如果是手动安装插件,那么也将需要手动从Plugin目录中删除它。
Step1.使用Eclipse的Help菜单找到SoftwareUpdates/FindandInstall
Step2.选择Searchfornewfeaturestoinstall选项
Step3.选择NewRemoteSite
Step4.在弹出的NewUpdateSite对话框中
Name栏可以填JBossRules
URL栏填URL:
Step5.选择刚刚添加的新的Updatesite,单击Finish按钮。
Step6.几秒钟后你将看到从Updatesite得到的DroolsIDE,选中其前面的复选框。
注意,这时可能会出现出错提示:
DroolsRuleWorkbench(3.0.5)requiresfeature"org.eclipse.gef(3.2.1)",orequivalent.解决办法是下载EclipseGEF-ALL-3.2.1.zip压缩包作为Eclipse的插件
Step7.接受协议。
开始从Updatesite下载,需要等待一段时间。
Step8.确定下载来的正是你想要的DroolsIED
Step9.按下Accept按钮,继续安装
Step10.重启Eclipse,安装即将生效。
Chapter3.TheRuleLanguage
3.1.Overview
Drools3有"native"(自己的)rulelanguage(DRL),它是非XML文本格式的。
这种格式就标点而言非常轻便(light),并且通过expander机制支持自然的领域描述语言DSL(这种语言允许问题域形态的描述)。
本章主要讲述(nativeruleformat)。
……如果你使用RuleWorkbench,内容帮助已经为你提供了很多规则结构,比如,输入“ru”然后按“ctrl+space”,内容帮助就会为你创建规则结构。
3.1.1Arulefile
一般的,一个规则文件就是一个以.drl为扩展名的文件。
在一个drl文件里可以有多条规则,函数等等。
也可以将规则展开成多个规则文件(这种情况下,建议使用扩展名.rule,但不是必需的),通过多个文件展开规则对处理大量规则有帮助。
简单的说,一个DRL文件就是一个文本文件。
3.1.2.Whatmakesarule
规则有下面的大略格式:
rule "name"
ATTRIBUTES
when
LHS
then
RHS
end
确实就是这么简单。
基本上不需要标点,即使是name的双引号也是可选的(只有当规则名中有空格时才需要引号)。
Attributes(也是可选的)提示规则应该怎样运行。
LHS是规则的条件部分,遵守下面讲的特定的语法。
RHS基本上是一个允许执行的Java语义代码块(不久的将来也将支持其它语义语言,比如groovy,C#)。
这里唯一的特定关键词是关于插入,回收,修改事实的。
任何在LHS中使用的变量都可以在RHS中使用。
注意,空白(whitespace)并不重要,除非是在领域描述语言(DSL)中,在DSL中,每一行都在下一行前执行。
3.1.3.DomainSpecificLanguage
DSL是增强nativerulelanguage的工具,它使用expander机制。
Expander机制是一个扩展的API,但是默认的,它能够以.dsl文件工作,dsl文件包含从领域或自然语言到规则语言和领域对象的映射。
也可以将这些.dsl文件想像成提供一些隔离的领域模型的映射。
DSLs/expanders在被编译时通过执行规则源文件中的一行来工作(这是唯一的newlines是重要的时刻)。
这样作是为了有助于可读性和避免需要标点。
期望一段时间以后,expanders和DSLs将对不同的领域都有效,并能提供其它形式的自然语言分析。
3.1.4.Reservedwords
在规则语言中有一些保留字。
当给你自己的领域对象、属性、方法、函数等在规则文本中使用的对象命名时与这些保留字避免冲突是明智的。
下表是应该在规则内容中尽量避免的关键字(一般情况下,能够正常工作,但有时规则可能会被不正确的编译。
当然,可能使关键字作为方法名的一部分,如notSomething()。
when
then
rule
end
contains
matches
and
or
modify
retract
assert
salience
function
query
exists
eval
agenda-group
no-loop
duration
->
not
auto-focus
3.2.Comments
注释是被规则引擎忽略的文本部分。
3.2.1.Singlelinecomment
以#或//开头
3.2.2.Multilinecomment
以/*开头,以*/结束
3.3.Package
一个Package是一个规则和其它相关结构(如imports,globals)的集合。
通常,Package成员互相关联(如HR规则)。
一个Package代表一个命名空间(namespace),标志一个特定的规则群。
Packagename自身只是命名空间,与文件或文件夹没有任何关系。
可以将多个规则源文件汇编,那样就会有一个顶级Packageconfiguration,所有的规则都在这个顶级Package下面。
然而,通常的结构是,像Package声明一样,一个Package中的所有规则在同一个文件里,这样Package就完全是自限制的。
下面的铁路图表示了组成一个Package的所有内容。
注意,一个Package必须有一个命名空间,并使用标准Java公约(如不允许有空格,不像规则名是允许空格的)声明Packagename。
就元素的顺序而言,除了package和expander声明必须在文件顶端、在任何规则出现之前外,其它的在规则文件中可以任何顺序出现。
Inallcases,半角冒号是可选的。
Figure3.3.package
3.3.1.import
3.3.2.expander
3.3.3.global
3.4.Fuction
Functions是一种在你的规则文件中插入语义代码的方法,与一般的Java类相对。
Functionscan'tdoanythingmorethanwhatyoucandowithhelperclasses(事实上,编译器在后台生成helperclass,isn’tthathelpful。
在规则文件中使用functions的最主要的好处是可以使所有逻辑在同一个地方,并且当需要时可以改变functions(这可能是优点也可能是缺点)。
Functions对invoke规则的Consequence(then)部分的行为最有帮助,尤其是当某条特定的行为(在不同的规则中)被反复执行时,只需对每条规则区别function的参数。
Atypicalfunctiondeclarationlookslike:
functionStringcalcSomething(Stringarg){
return"hola!
";
}
Function的参数和返回类型就像一般的方法(method)一样(如果需要的话,也可以没有参数)。
function在规则里调用(call)(就像调用方法一样,使用function名和参数调用)。
Function中可以使用helper类中的一个静态方法:
Foo.doSomething(),或者……
3.5.Rule
Rule结构是最重要的结构。
Rule使用了形如“IF”something“THEN”action(当然,我们的关键字是“when”和“then”)的形式。
一个规则在一个package中必须要有唯一的名字。
如果一个名字中含有空格,那就需要将名字放在双引号中(最好总是使用双引号)。
Attribute是可选的(最好是每行只有一个Attribute)。
规则的LHS跟在“when”关键字的后面(最好是另起一行),同样RHS要跟在“then”关键字后面(最好也另起一行)。
规则以关键字“end”结束。
规则不能嵌套。
3.5.1.LeftHandSide
LeftHandSide其实就是规则的条件部分。
3.5.2.RightHandSide
RightHandSide(RHS)就是规则的结果(consequence)或者动作(action)部分。
RHS的目的是retract或addfacts到WorkingMemory中,还有invoke针对你的application的动作。
实际上,RHS是当规则激发(fire)时执行的代码块。
在RHS中,你可以使用几个方便的method来改变WorkingMemory:
“modify(obj)”:
告诉引擎一个对象已经发生变化,规则必须重新匹配(obj对象必须是出现在LHS中的对象);
“assert(newSomething())”:
将一个新的Something对象加入WorkingMemory;
“assertLogical(newSomething())”:
与assert方法类似。
但是,当没有fact支持当前激发规则的真实性的时候,这个新对象会自动被retract,
“retract(obj)”:
从WorkingMemory中移除一个对象。
这些方法都是宏指令,提供了到KnowledgeHelper实例的快捷方式(参考KnowledgeHelper接口)。
KnowledgeHelper接口可以在RHS代码块中调用,通过变量“drools”。
如果你在assert进引擎的JavaBean中加入“PropertyChangeListener”,在对象发生变化的时候,你就不用调用“modify”方法。
3.5.3.RuleAttriutes
3.5.3.1. no-loop
defaultvalue:
false
type:
Boolean
当某个规则结果修改一个事实时,可能引起这个规则的再次被激活,引起递归。
设置no-loop为真表示忽略这种试图激活的行为。
3.5.3.2. salience
defaultvalue:
0
type:
integer
每个规则都有一个能够被分配一个整数的salience属性,默认值为0,这个整数可正可负。
Salience是一种优先级形式,在规则激活序列中,高Salience的规则被给以高优先级。
3.5.3.3. agenda-group
defaultvalue:
MAIN
type:
String
Agendagroup允许用户给Agenda分组以提供更多的执行控制。
只有当前组的规则才能被fire。
3.5.3.4. auto-focus
defaultvaluefalse
type:
Boolean
当一个auto-focus值为真的规则被激活,并且它所属的RuleAgendaGroup当前没有焦点,那么它将被自动聚焦,允许规则potentiallyfire。
3.5.3.5. activation-group
defaultvalueN/A
type:
String
属于同一命名activation-group的规则相互间有排它性。
换句话说,fire一个activation-group中的第一个规则将取消其它规则的激活。
Activation-group属性是任何一个字符串,只要这个字符串有别于同一组中的所有规则。
注意:
activation-group过去被称为Xor-group,但技术上它不完全是Xor(异或),你可能会听到人们提到Xor-group,那就在你的头脑中用activation-group替换它。
3.5.3.6. duration
defaultvalue:
nodefaultvalue
type:
long
3.5.4. Column
Cheese()
Cheese(type=="stilton",price<10)
一个规则包含一个FieldConstraints(域限制)或几个Objec