﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-Java Votary-随笔分类-Rule Engine</title><link>http://www.blogjava.net/ericwang/category/8340.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 13:12:11 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 13:12:11 GMT</pubDate><ttl>60</ttl><item><title>[转]Drools in Action </title><link>http://www.blogjava.net/ericwang/archive/2006/03/11/34787.html</link><dc:creator>Dion</dc:creator><author>Dion</author><pubDate>Sat, 11 Mar 2006 02:02:00 GMT</pubDate><guid>http://www.blogjava.net/ericwang/archive/2006/03/11/34787.html</guid><wfw:comment>http://www.blogjava.net/ericwang/comments/34787.html</wfw:comment><comments>http://www.blogjava.net/ericwang/archive/2006/03/11/34787.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ericwang/comments/commentRss/34787.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ericwang/services/trackbacks/34787.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 题记世界是事实的总体，而不是事物的总体。世界为诸事实所规定，为它们既是全部事实所规定。——路德维希·维特根斯坦，《逻辑哲学论》The answer, please?"请回答我..."The stern voice startles you. 一个严厉的声音把你吓个半死.You were dozing in Mrs. Rosencrantz's high school math class agai...&nbsp;&nbsp;<a href='http://www.blogjava.net/ericwang/archive/2006/03/11/34787.html'>阅读全文</a><img src ="http://www.blogjava.net/ericwang/aggbug/34787.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ericwang/" target="_blank">Dion</a> 2006-03-11 10:02 <a href="http://www.blogjava.net/ericwang/archive/2006/03/11/34787.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]Drools项目简介</title><link>http://www.blogjava.net/ericwang/archive/2006/03/11/34784.html</link><dc:creator>Dion</dc:creator><author>Dion</author><pubDate>Sat, 11 Mar 2006 02:00:00 GMT</pubDate><guid>http://www.blogjava.net/ericwang/archive/2006/03/11/34784.html</guid><wfw:comment>http://www.blogjava.net/ericwang/comments/34784.html</wfw:comment><comments>http://www.blogjava.net/ericwang/archive/2006/03/11/34784.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ericwang/comments/commentRss/34784.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ericwang/services/trackbacks/34784.html</trackback:ping><description><![CDATA[<strong>内容提要</strong><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
在本文的第一部分，我将讨论规则引擎如何帮助你从软件的应用逻辑中分离出商业规则逻辑，以实现商业应用的灵活性。另外，我还将介绍JSR－94规则引擎
API，及其开源实现Drools项目，它是这一新技术的先驱。在第二部分，我们将介绍一个规则引擎例子，并深入地研究Drools引擎及其JSR－94
扩展的复杂性。
<div><br><strong>为什么使用规则引擎</strong><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
商业世界充满了关于变化的陈词滥调，如任何事物都会改变，唯一不变的是变化等等。而在技术领域里，情况正好相反。我们仍然在试图解决30年前软件业中同样
的一堆问题－－也许比30年前还要多的问题。在过去的十年，IT从业人员淹没在软件方法学的大量文献中，如快速软件开发，极限编程，敏捷软件开发等，它们
无一例外地强调灵活和变化的重要性。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 但商业通常比开发团队所依赖的软件过程和技术改变得更加迅速。当商业策划人员试图重整IT部门，以支持新的业务转型时，仍然觉得很费劲。</div>
<div><br><strong>Lost in Translation</strong><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
虽然IT团队反应迅速，但他们通常带来"电话效应"――IT给商业计划的执行带来的阻力和它带来的利益一样多。不幸的是，在开发团队完全理解商业决策规则
并实现之前，规则已经改变了。在软件进入市场前，它已经过时了，需要进行重构以满足新的业务需求。如果你是一个开发人员，你会知道我在说什么。再也没有比
在需求变动的情况下构造软件让开发人员更沮丧的事情了。作为软件开发人员，你必须比业务人员更了解业务，有时还要了解更多。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
试想一下你是一位商业决策者。假如公司的成功依赖于你对于市场趋势敏锐的洞察力，它常常帮助你领先于竞争者利用变化的市场环境获利。每天你都会得到更多更
好的市场信息，但并不要紧。完成新产品开发可能需要6－9个月，在此期间，对于市场大胆和敏锐的洞察和信息优势可能已经浪费了。而且，当产品发布时，有这
样几种可能：产品没有什么吸引人的特性，预算超支，过了产品的最佳发布期限，或三者兼而有之。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
情况可能还会更糟，在完成产品开发时，市场环境和规划产品开发时相比，已经发生了根本变化。现在你必须要遵守新的规则，你已经丧失了你的边际优势，而且设
计软件的五人中的三人已经离开了公司。你必须给接手的新人重新讲解复杂的业务。如果事情不顺利，你可能发现自己要对付一个缺少文档，并且你完全不了解的遗
留应用。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
你的战略在哪出现了问题？你在哪里应该可以做到更好？最近的轻量级软件过程，如极限编程，敏捷软件开发等都在强调自动单元测试和软件功能优先级的重要性。
除此之外，还有其他的原则，你的开发团队可能也很熟悉，这些原则可以帮助他们对需求的变动作出迅速反应并缩短项目的开发周期。这些原则的大多数，如系统分
解，多年前就已经出现，并得到了Java平台的支持（如JMX等），还有如面向对象和角色建模，已经内建在Java语言中。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
但Java仍然是一门相当年轻的语言，而且Java平台远远还没有完备。当前在Java社区，一个引人注目的新技术是，分离商业决策者的商业决策逻辑和应
用开发者的技术决策，并把这些商业决策放在中心数据库，让它们能在运行时（即商务时间）可以动态地管理和修改。这是一个你值得考虑的策略。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
为什么你的开发团队不得不象商业经理人一样，在代码中包含复杂微妙的商业决策逻辑呢？你怎样才能向他们解释决策推理的微妙之处呢？你这样做是否谨慎呢？可
能不是。象bottom
line一样，某些东西在解释的过程中丢失了。为什么要冒这样的风险，让应用代码或测试代码错误地表达你的商业决策逻辑呢？如果这样做的话，你怎样检查它
们的正确性呢――难道你自己想学习如何编程和编写测试代码，或者你的客户会为你测试软件？你一方面要应付市场，一方面要应付软件代码，这实在太困难了。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
如果能将这些商业决策规则集中地放在一个地方，以一种你可以理解的格式定义，让你可以直接管理，而不是散落在代码的各个角落，那该有多好。如果你能把商业
决策规则独立于你的软件代码，让开发团队作出技术决策，你将会获得更多好处。你的项目开发周期会更短，软件对于变动的需求更灵活。</div>
<div><br><strong>规则引擎标准Java API</strong><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
2003年11月，Java社区通过了Java Rule Engine
API规范（JSR－94）的最后草案。这个新的API让开发人员在运行时访问和执行规则有了统一的标准方式。随着新规范产品实现的成熟和推向市场，开发
团队将可以从应用代码中抽取出商业决策逻辑。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这就需要新一代的管理工具，帮助商务经理人可以定义和细化软件系统的行为。不必通过开发过程来修改应用，并假定可以得到正确的结果，经理人将可以随时根据需要修改决策规则，并进行测试。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 但这将需要开发人员在设计系统时作出某些改变，并可以得到合适的开发工具。</div>
<div><br><strong>分离商务和技术的关注点</strong><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这是一个非常简单的例子，从经理人的角度，说明如何分离商务和技术的关注点。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 你管理着一个反向投资基金。你公司计算机系统的一部分用于分析股票价格，收益和每股净资产，并在需要时向你提出预警。这个计算机系统的工作是，识别出PE比率比市场平均值低的股票，并标记出来以便进一步的检查。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 你的IT部门拥有一大堆数据，并开发了一系列你可以在规则中引用的简单数据对象。现在，为简单起见，假设你是一名受过良好教育的，了解技术的管理人，你了解XML的基本知识，可以让你编写和修改简单的XML规则文件。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 你的第一个规则是，给道琼斯所有的股票估值，并剔除P/E比率大于10的股票（这有点过分简化，但这里只作为一个例子）。保留下来的股票用来生产一系列报表。对于这个简单的例子，你的规则文件看起来如下（我们将会过头来讨论这个文件的结构）：</div>
<div><br>&lt;stock:overvalued&gt;<br>&nbsp;&nbsp;&nbsp; &lt;stock:index&gt; DJIA &lt;/stock:index&gt;<br>&nbsp;&nbsp;&nbsp; &lt;stock:pe&gt; over 10.0 &lt;/stock:pe&gt;<br>&lt;/stock:overvalued&gt;</div>
<div><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
一个月后，你接到一家巴西分析师公司的电话，雇佣你的公司生成一系列巴西股市的报表，但他们有更严格的标准。而目前在巴西，P/E比率市场平均值是个位
数，因此你用来评估被市场低股票的阈值需要改变。除了较低的P/E比率，你的新客户还要求以Price-to-Book比率作为参考标准。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 你启动规则编辑器，并修改规则以匹配新的评估条件。现在，规则引擎剔除巴西股市中P/E比率大于6.5，以及Price to Book 比率小于等于1的股票。完成规则文件修改后，看起来如下：</div>
<div><br>&lt;stock:overvalued&gt;<br>&nbsp;&nbsp;&nbsp; &lt;stock:index&gt; Brazil &lt;/stock:index&gt;<br>&nbsp;&nbsp;&nbsp; &lt;stock:pe&gt; over 6.5 &lt;/stock:pe&gt;<br>&nbsp;&nbsp;&nbsp; &lt;stock:pb&gt; over 1.0 &lt;/stock:pb&gt;<br>&lt;/stock:overvalued&gt;</div>
<div><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 你无需为此向开发团队作任何解释。你无需等待他们开发或测试程序。如果你的规则引擎的语义足够强大，让你描述工作数据，你可以随时按需修改商业规则。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果限制因素是规则的定义语言和数据模型，你可以确信这两者将会标准化，并出现先进的编辑器和工具，以简化规则的定义，保存和维护。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
现在，我希望你已经清楚以下的原则：在这个例子中，哪只股票是否被选择是一个商务决策，而不是技术决策。决定将哪只股票交给你的分析师是经理人的逻辑
――"logic of the bottom
line"。经理人作出这些决策，并可以按需定制应用。这些规则因此变成了一种控制界面，一种新的商业系统用户界面。</div>
<div><br><strong>使用Rule开发</strong><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果在这个应用场景中，你是一个开发人员，你的工作会稍微轻松一些。一旦你拥有了一种用于分析股票的规则语言，你可以取出数据对象并交给规则引擎执行。我们将会到规则语言的讨论，但现在我们继续刚才的例子。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
你的系统将一系列的stock
bean输入规则引擎。当规则执行后，你可以选出符合条件的股票并可以对它们作进一步处理。也许是把它们输入报表生成系统。分析师使用这些报表帮助他们分
析股市。同时，老板也可能让你使用新的技术分析工具，并用Dow理论预测股市的底部和顶部。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 规则引擎可以让你的系统变得更简单，因为你无需在代码中编写商务逻辑，如怎样选择股票，选择股票过程中奇怪的条件组合等。这些逻辑不再进入你的代码。你将可以专注于数据模型。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 现在可以这么认为，通过从应用代码中剥离出易变的商业逻辑，你的效率会更高。但凡是总有例外――简单应用可能并不能从规则系统中获益。但如果你开发一个大型系统，有很多易变的商业逻辑，你可以考虑在应用中集成规则引擎。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
除了从应用代码中剥离出商业决策逻辑外，规则引擎还有其他用处。有时候你需要应用成百上千的规则进行决策，并且有上千个对象和这些规则一起使用。很难想象
有什么先进的人工智能引擎可以处理这种情况。遇到这种情况，你需要一个极快的决策算法或是大型机。大型机并不便宜，但你可以非常便宜的得到效率和可伸缩性
最好的算法。</div>
<div><br><strong>Bob McWhirter的Drools项目</strong><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
现在，我要介绍Drools项目，Charles Forgy Rete算法的一个增强的Java语言实现。Drools是一个Bob
McWhirter开发的开源项目，放在The
Codehaus上。在我写这篇文章时，Drools发表了2.0-beata-14版。在CVS中，已完整地实现了JSR94 Rule
Engine API并提供了单元测试代码。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Rete算法是Charles
Forgy在1979年发明的，是目前用于生产系统的效率最高的算法（除了私有的Rete
II）。Rete是唯一的，效率与执行规则数目无关的决策支持算法。For the uninitiated, that means it can
scale to incorporate and execute hundreds of thousands of rules in a
manner which is an order of magnitude more efficient then the next best
algorithm。Rete应用于生产系统已经有很多年了，但在Java开源软件中并没有得到广泛应用（讨论Rete算法的文档参见<a href="http://herzberg.ca.sandia.gov/jess/docs/61/rete.html"><font color="#0d5d91">http://herzberg.ca.sandia.gov/jess/docs/61/rete.html</font></a>。）。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
除了应用了Rete核心算法，开源软件License和100％的Java实现之外，Drools还提供了很多有用的特性。其中包括实现了JSR94
API和创新的规则语义系统，这个语义系统可用来编写描述规则的语言。目前，Drools提供了三种语义模块――Python模块，Java模块和
Groovy模块。本文余下部分集中讨论JSR94 API，我将在第二篇文章中讨论语义系统。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 作为使用javax.rules
API的开发人员，你的目标是构造一个RuleExecutionSet对象，并在运行时通过它获得一个RuleSession对象。为了简化这个过程，
我编写了一个规则引擎API的fa?ade，可以用来解释代表Drools的DRL文件的InputStream，并构造一个
RuleExecutionSet对象。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在上面提到了Drools的三种语义模块，我接下来使用它们重新编写上面的例子XML规则文件。这个例子中我选择Java模块。使用Java模块重新编写的规则文件如下：</div>
<div><br>&lt;rule-set name="StockFlagger"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xmlns="<a href="http://drools.org/rules"><font color="#0d5d91">http://drools.org/rules</font></a>"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xmlns:java="<a href="http://drools.org/semantics/java"><font color="#0d5d91">http://drools.org/semantics/java</font></a>"&gt;</div>
<div>&nbsp; &lt;rule name="FlagAsUndervalued"&gt;<br>&nbsp;&nbsp;&nbsp; &lt;parameter identifier="stock"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;java:class&gt;org.codehaus.drools.example.Stock&lt;/java:class&gt;<br>&nbsp;&nbsp;&nbsp; &lt;/parameter&gt;<br>&nbsp;&nbsp;&nbsp; &lt;java:condition&gt;stock.getIndexName().equals("DJIA");&lt;/java:condition&gt;<br>&nbsp;&nbsp;&nbsp; &lt;java:condition&gt;stock.getPE() &gt; 10 &lt;/java:condition&gt;<br>&nbsp;&nbsp;&nbsp; &lt;java:consequence&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; removeObject(stock);&nbsp;&nbsp; ( 译注：应该是retractObject(stock) )<br>&nbsp;&nbsp;&nbsp; &lt;/java:consequence&gt;<br>&nbsp; &lt;/rule&gt;<br>&lt;/rule-set&gt;</div>
<div><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
现在的规则文件并没有上面的简洁明了。别担心，我们将在下一篇文章讨论语义模块。现在，请注意观察XML文件的结构。其中一个rule-set元素包含了
一个或多个rule元素，rule元素又包含了parameter，condition和consequence元素。Condition和
consequence元素包含的内容和Java很象。注意，在这些元素中，有些事你可以做，有些事你不能做。目前，Drools使用
BeanShell2.0b1作为它的Java解释器。我在这里并不想详细的讨论DRL文件和Java语义模块的语法。我们的目标是解释如何使用
Drools的JSR94 API。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
在Drools项目CVS的drools-jsr94模块中，单元测试代码包含了一个ExampleRuleEngineFacade对象，它基于
Brian Topping的Dentaku项目。这个fa?ade对象通过javax.rules
API，创建了供RuleExecutionSet和RuleSession使用的一系列对象。它并没有完全包括了Drools引擎API的所有特性和细
微差别，但可以作为新手使用API的一个简单例子。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 下面的代码片断显示如何使用规则引擎的facade构造一个RuleExecutionSet对象，并通过它获得一个RuleSession对象。</div>
<div>&nbsp;</div>
<div>import java.io.InputStream;<br>import javax.rules.*;<br>import org.drools.jsr94.rules.ExampleRuleEngineFacade;</div>
<div>public class Example {<br>&nbsp;&nbsp;&nbsp; private ExampleRuleEngineFacade engine;<br>&nbsp;&nbsp;&nbsp; private StatelessRuleSession statelessSession;</div>
<div>&nbsp;&nbsp;&nbsp; /* place the rule file in the same package as this class */<br>&nbsp;&nbsp;&nbsp; private String bindUri = "myRuleFile.drl"</div>
<div>&nbsp;&nbsp;&nbsp; public Example() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* get your engine facade */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; engine = new ExampleRuleEngineFacade();</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* get your input stream */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InputStream inputStream =<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Example.class.getResourceAsStream(bindUri);</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* build a RuleExecutionSet to the engine */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; engine.addRuleExecutionSet(bindUri, inputStream);</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* don't forget to close your InputStream! */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inputStream.close();</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* get your runtime session */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.statelessSession = engine.getStatelessRuleSession(bindUri);<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; ...<br>}</div>
<div><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
在以上的例子代码中，你需要处理InputStream的IOException例外，这里为了简单起见省略了。你要做的只是构建InputStream
对象，并把它输入ExampleRuleEngineFacade，用来创建一个RuleExecutionSet对象。然后，你可以得到一个
StatelessRuleSession，并用它来执行所有的规则。使用StatelessRuleSession相对简单。我们可以给上面的类添加一
个方法，用来对一个对象列表执行规则：</div>
<div><br>public List getUndervalued(List stocks) {<br>&nbsp;&nbsp;&nbsp; return statelessSession.executeRules(stocks);<br>}</div>
<div><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 该方法输入一个stock对象列表给规则引擎，然后使用规则评估输入的股票对象，并剔除那些不符合价值低估标准的股票。它是个简单的例子，但足以说明问题。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
在ExampleRuleEngineFacade类中，代码会稍微有些复杂。ExampleRuleEngineFacade类创建了一个
RuleServiceProvider对象，并用它创建RuleAdministrator，RuleExecutionSetProvider和
RuleRuntime对象。RuleExecutionSetProvider负责解释InputStream，并创建一个
RuleExecutionSet对象。RuleRuntime对象用来得到一个session，RuleAdministrator用来管理所有的对
象。在往下是Drools核心API，它的核心是Rete算法实现。我在这里不打算详细讨论，但你可以看看
ExampleRuleEngineFacade的代码。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
现在你已经看到了在商业和科研方面使用规则引擎的一些例子，并对Drools项目有了基本的了解。在下一篇文章里，我将讨论DRL文件的结构和Java语
义模块，让你可以编写自己的DRL文件。还将向你解释如何编写你自己的语义模块，讨论salience和working memory的概念。</div>
<div><br><strong>资源</strong><br>·&nbsp;<a href="http://www.drools.org/" target="_blank"><font color="#0d5d91">Drools Project</font></a> <br>·&nbsp;<a href="http://www.jcp.org/en/jsr/detail?id=94" target="_blank"><font color="#0d5d91">JSR-94 Specification</font></a></div>
<div>&nbsp;</div>
<div><strong>作者</strong></div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; N. Alex Rupp is a freelance software architect and developer
from Minneapolis, and the current JSR94 Lead for the Drools project.</div><img src ="http://www.blogjava.net/ericwang/aggbug/34784.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ericwang/" target="_blank">Dion</a> 2006-03-11 10:00 <a href="http://www.blogjava.net/ericwang/archive/2006/03/11/34784.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]Drools的配置文件</title><link>http://www.blogjava.net/ericwang/archive/2006/03/11/34785.html</link><dc:creator>Dion</dc:creator><author>Dion</author><pubDate>Sat, 11 Mar 2006 02:00:00 GMT</pubDate><guid>http://www.blogjava.net/ericwang/archive/2006/03/11/34785.html</guid><wfw:comment>http://www.blogjava.net/ericwang/comments/34785.html</wfw:comment><comments>http://www.blogjava.net/ericwang/archive/2006/03/11/34785.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ericwang/comments/commentRss/34785.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ericwang/services/trackbacks/34785.html</trackback:ping><description><![CDATA[<p>前几天跟着写了一个简单的例子.<br>觉得Drools的配置也没有什么.<br>今天在运行house的例子的时候, 无论怎么样, 总是异常: 没有定义的SMF.<br>显然没有找到我定义的drools.config文件.<br>官方网站上是这样写地:<br>String droolsConfigProp = System.getProperty( "drools.conf" );<br><br>if ( droolsConfigProp != null )<br>{<br>&nbsp;&nbsp;&nbsp; loadConfig( droolsConfigProp );<br>}<br><br>ClassLoader cl = Thread.currentThread( ).getContextClassLoader( ); if ( cl == null )<br>{<br>&nbsp;&nbsp;&nbsp; cl = getClass( ).getClassLoader( );<br>}<br><br>Enumeration configUrls = cl.getResources( "META-INF/drools.conf" );<br><br>if ( !configUrls.hasMoreElements( ) )<br>{<br>&nbsp;&nbsp;&nbsp; cl = getClass( ).getClassLoader( );<br>&nbsp;&nbsp;&nbsp; configUrls = cl.getResources( "META-INF/drools.conf" );<br>}<br><br>if ( !configUrls.hasMoreElements( ) )<br>{<br>&nbsp;&nbsp;&nbsp; cl = ClassLoader.getSystemClassLoader( );<br>&nbsp;&nbsp;&nbsp; configUrls = cl.getResources( "META-INF/drools.conf" );<br>}<br><br>this.classLoader = cl;<br>while ( configUrls.hasMoreElements( ) )<br>{<br>&nbsp;&nbsp;&nbsp; URL configUrl = (URL) configUrls.nextElement( );<br>&nbsp;&nbsp;&nbsp; loadConfig( configUrl );<br>}</p>
好像每一个旮旯里面都找了, 为什么没有找到我的呢?<br>System.getProperty指向的位置并不一定和loadFromUrl位置一样.呵呵.<img src ="http://www.blogjava.net/ericwang/aggbug/34785.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ericwang/" target="_blank">Dion</a> 2006-03-11 10:00 <a href="http://www.blogjava.net/ericwang/archive/2006/03/11/34785.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]使用Drools 的项目引用</title><link>http://www.blogjava.net/ericwang/archive/2006/03/11/34783.html</link><dc:creator>Dion</dc:creator><author>Dion</author><pubDate>Sat, 11 Mar 2006 01:59:00 GMT</pubDate><guid>http://www.blogjava.net/ericwang/archive/2006/03/11/34783.html</guid><wfw:comment>http://www.blogjava.net/ericwang/comments/34783.html</wfw:comment><comments>http://www.blogjava.net/ericwang/archive/2006/03/11/34783.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ericwang/comments/commentRss/34783.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ericwang/services/trackbacks/34783.html</trackback:ping><description><![CDATA[<p>一般情况下, 只显式引用:</p>
<ul><li>drools-all-2.0.jar</li><li>antlr-2.7.5.jar</li><li>xercesImpl-2.6.2.jar</li></ul>
<p>就可以了.当然ClassPath下也要用一些其他的jar.<br>下载位置: <a href="http://dist.codehaus.org/drools/distributions/drools-2.0-bin-withdeps.zip"><font color="#0d5d91">http://dist.codehaus.org/drools/distributions/drools-2.0-bin-withdeps.zip</font></a></p>
<p>如果, 在DRL文件中定义了Java Function, 这时候就要显式的引用:</p>
<ul><li>janino-2.3.2.jar</li></ul>
<p>这时候, 引擎是需要janino把DRL中的java function描述转换成可执行的二进制代码(?)的.</p><img src ="http://www.blogjava.net/ericwang/aggbug/34783.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ericwang/" target="_blank">Dion</a> 2006-03-11 09:59 <a href="http://www.blogjava.net/ericwang/archive/2006/03/11/34783.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]Open Source Rule Engines Written In Java</title><link>http://www.blogjava.net/ericwang/archive/2006/03/11/34780.html</link><dc:creator>Dion</dc:creator><author>Dion</author><pubDate>Sat, 11 Mar 2006 01:58:00 GMT</pubDate><guid>http://www.blogjava.net/ericwang/archive/2006/03/11/34780.html</guid><wfw:comment>http://www.blogjava.net/ericwang/comments/34780.html</wfw:comment><comments>http://www.blogjava.net/ericwang/archive/2006/03/11/34780.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ericwang/comments/commentRss/34780.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ericwang/services/trackbacks/34780.html</trackback:ping><description><![CDATA[<h2>Open Source Rule Engines Written In Java</h2>
                    <ul><li><a href="http://drools.org/"><font color="#666666"><u>Drools</u></font></a>
The drools engine uses a modified form of the Rete algorithm called the
Rete-OO algorithm. Internally it operates using the same concepts and
methods as Forgy's original but adds some node types required for
seemless integration with an object-oriented language. </li><li><a href="http://www.ofbiz.org/docs/rules.html"><font color="#666666"><u>OFBiz Rule Engine</u></font></a> Backward chaining is supported. Original code base from "Building Parsers in Java" by Steven John Metsker. 
</li><li><a href="http://www.mandarax.org/"><font color="#666666"><u>Mandarax</u></font></a>
Based on backward reasoning. The easy integration of all kinds of data
sources. E.g., database records can be easily integrated as sets of
facts and reflection is used in order to integrate functionality
available in the object model. </li><li><a href="http://smi.stanford.edu/people/hewett/research/ai/algernon/"><font color="#666666"><u>Algernon</u></font></a>
Efficient and concise KB traversal and retrieval. Straightforward
access to ontology classes and instances. Supports both forward and
backward chaining. </li><li><a href="http://tyruba.sourceforge.net/"><font color="#666666"><u>TyRuBa</u></font></a>
TyRuBa supports higher order logic programming: variables and compound
terms are allowed everywhere in queries and rules, also in the position
of a functor- or predicate-name. TyRuBa speeds up execution by making
specialized copies of the rule-base for each query in the program. It
does so incrementally while executing a logic program and builds an
index for fast access to rules and facts in the rule base, tuned to the
program that is running. The indexing techniques works also for
higher-order logic. TyRuBa does 'tabling' of query results. </li><li><a href="http://www.ksl.stanford.edu/software/JTP/"><font color="#666666"><u>JTP</u></font></a>
Java Theorem Prover is based on a very simple and general reasoning
architecture. The modular character of the architecture makes it easy
to extend the system by adding new reasoning modules (reasoners), or by
customizing or rearranging existing ones. </li><li><a href="http://www.di.ufpe.br/%7Ejeops/"><font color="#666666"><u>JEOPS</u></font></a>
JEOPS adds forward chaining, first-order production rules to Java
through a set of classes designed to provide this language with some
kind of declarative programming. </li><li><a href="http://info-sapient.sourceforge.net/"><font color="#666666"><u>InfoSapient</u></font></a> Semantics of business rules expressed using fuzzy logic. 
</li><li><a href="http://www.cs.umd.edu/projects/shop/description.html"><font color="#666666"><u>JShop</u></font></a> Simple Hierarchical Ordered Planner (SHOP) written in Java. 
</li><li><a href="http://public.research.mimesweeper.com/RDF/RDFExpert/Intro.html"><font color="#666666"><u>RDFExpert</u></font></a>
RDF-driven expert system shell. The RDFExpert software uses Brian
McBride's JENA API and parser. A simple expert system shell that uses
RDF for all of its input: knowledge base, inference rules and elements
of the resolution strategy employed. It supports forward and backward
chaining. </li><li><a href="http://www.hpl.hp.com/semweb/jena2.htm"><font color="#666666"><u>Jena 2</u></font></a>
- Jena is a Java framework for writing Semantic Web applications. Jena2
has a reasoner subsystem which includes a generic rule based inference
engine together with configured rule sets for RDFS and for the OWL/Lite
subset of OWL Full. These reasoners can be used to construct inference
models which show the RDF statements entailed by the data being
reasoned over. The subsystem is designed to be extensible so that it
should be possible to plug a range of external reasoners into Jena,
though worked examples of doing so are left to a future release. </li><li><a href="http://jlisa.sourceforge.net/"><font color="#666666"><u>JLisa</u></font></a>
- JLisa is a powerful framework for building business rules accessible
to Java and it is compatible with JSR-94. JLisa is more powerful than
Clips because it has the expanded benefit of having all the features
from common lisp available. These features are essential for
multi-paradigm software development </li><li><a href="http://www.agfa.com/w3c/euler/"><font color="#666666"><u>Euler</u></font></a>
- Euler is a backward-chaining reasoner enhanced with Euler path
detection and will tell you whether a given set of facts and rules
supports a given conclusion. Things are described in N3. </li><li><a href="http://jlogic.sourceforge.net/"><font color="#666666"><u>JLog</u></font></a>
- JLog is an implementation of a Prolog interpreter, written in Java.
It includes built-in source editor, query panels, online help,
animation primitives, and a GUI debugger. </li><li><a href="http://www.mindswap.org/2003/pellet/"><font color="#666666"><u>Pellet OWL Reasoner</u></font></a>
- Pellet is an open-source Java based OWL DL reasoner. It can be used
in conjunction with either Jena or OWL API libraries. Pellet API
provides functionalities to see the species validation, check
consistency of ontologies, classify the taxonomy, check entailments and
answer a subset of RDQL queries (known as ABox queries in DL
terminology). Pellet is an OWL DL reasoner based on the tableaux
algorithms developed for expressive Description Logics. </li><li><a href="http://comas.soi.city.ac.uk/prova/"><font color="#666666"><u>Prova</u></font></a>
- Prova is derived from Mandarax Java-based inference system developed
by Jens Dietrich. Prova extends Mandarax by providing a proper language
syntax, native syntax integration with Java, and agent messaging and
reaction rules. The development of this language was supported by the
grant provided within the EU project GeneStream. In the project, the
language is used as a rules-based backbone for distributed web
applications in biomedical data integration. </li></ul><img src ="http://www.blogjava.net/ericwang/aggbug/34780.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ericwang/" target="_blank">Dion</a> 2006-03-11 09:58 <a href="http://www.blogjava.net/ericwang/archive/2006/03/11/34780.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]Drools and Mandarax</title><link>http://www.blogjava.net/ericwang/archive/2006/03/11/34781.html</link><dc:creator>Dion</dc:creator><author>Dion</author><pubDate>Sat, 11 Mar 2006 01:58:00 GMT</pubDate><guid>http://www.blogjava.net/ericwang/archive/2006/03/11/34781.html</guid><wfw:comment>http://www.blogjava.net/ericwang/comments/34781.html</wfw:comment><comments>http://www.blogjava.net/ericwang/archive/2006/03/11/34781.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ericwang/comments/commentRss/34781.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ericwang/services/trackbacks/34781.html</trackback:ping><description><![CDATA[<h2>Drools and Mandarax</h2> 两个项目做了两件不同的事情: 一个是Forward Chaining,另一个是
backward chaining. Drools&nbsp;是forward chaining的,&nbsp;&nbsp;意味着 它对assert的对象反应,
事件驱动的. Mandarax&nbsp;是 backward chaining的,&nbsp;像 prologue一样, 你问它问题,
它试图给你它知道的答案.&nbsp;举例来说, 在使用Drools的时候, 你可能会先assert 给它今天的日期,
如果它发现有匹配的规则的手,它会用事件的方式通知你"今天是你的生日".&nbsp;在 backward chaining&nbsp;的系统,&nbsp;你可能先问
"今天是我的生日嘛?" 系统会搜索它知道的, 然后告诉你答案.<br>For an excellent explanation of forward and backward chaining read Charles Forgey's recent articles at <a href="http://rulespower.com/" target="_blank"><font color="#0d5d91">http://rulespower.com/</font></a> - Forward and Backward Chaining:<br>Parts 1, 2 and 3.<img src ="http://www.blogjava.net/ericwang/aggbug/34781.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ericwang/" target="_blank">Dion</a> 2006-03-11 09:58 <a href="http://www.blogjava.net/ericwang/archive/2006/03/11/34781.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>