基於Rete算法的JAVA規則引擎

 

作者:張淵 夏清國( 西北工業大學計算機學院, 西安710072)
出自:《科學技術與工程》 第 6 卷第 11 期 2006 年 6 月

摘要

在軟件應用中若能抽取出規則, 可以使軟件實體更靈活, 規則引擎使得這成爲可能。其算法Rete 也逐漸發展成爲了一種最重要的主流算法。先着重敘述了規則引擎的原理及其JAVA API, 其次闡述了Rete 算法, 最後簡單介紹了Jess 與開源項目產品Drools。

關鍵詞

規則引擎 Rete算法 Java API Doorls J2EE
中圖法分類號 TP311.11; 文獻標識碼 B

JAVA 實現中, 基本分爲三層, 每層又對應優秀的框架用以使開發者集中開發最關鍵之處, 其中包括表現層框架( Struts, JSF 等) 、持久層框架( JDO 及Entity Beans 等) 以及結構化框架(例如 EJB)。在這些框架中, 卻沒有商業邏輯框架。圖1 顯示了目前這種狀態[1]。

圖1 用於Java 應用的框架

這裏需要規則引擎。本文着重闡述規則引擎原理及其所用Rete 算法, 並說明了兩種主流框架。

在企業級目前企業發展有一種趨勢, 那就是商業規則經常變動, 而且變動的原因多半來自非開發人員, 且對於即使是開發人員, 很多複雜的規則也很難推導出算法和抽象出數據模型。而且這些商業規則往往不能作爲穩定的需求, 也就是說可能在設計和編碼後還在變化。且業務規則往往嵌在系統各處代碼中, 給系統的維護、更新帶來極大困難, 更不可能讓非開發人員來管理。規則引擎正是解決了這個問題。

1 規則引擎

1.1 業務規則

一個業務規則包含一組條件和在此條件下執行的操作, 它們表示業務規則應用程序的一段業務邏輯。業務規則通常應該由業務分析人員和策略管理者開發和修改, 但有些複雜的業務規則也可以由技術人員使用面嚮對象的技術語言或腳本來定製。

業務規則的理論基礎是:設置一個或多個條件, 當滿足這些條件時會觸發一個或多個操作[3]。

1.2 規則引擎的架構

規則引擎的架構如 圖2所示:

圖2 業務規則引擎架構

規則引擎的推理步驟如下:

a. 將初始數據輸入至工作內存;
b. 使用模式匹配將規則庫中的規則和數據比較;
c. 如果執行規則存在衝突, 即同時激活了多個規則, 將衝突的規則放入衝突集合;
d. 解決衝突, 將激活的規則按順序放入議程中;
e. 執行其中的規則;

重複步驟b 至e, 直到執行完畢議程中的所有規則。任何一個規則引擎都需要很好地解決規則的推理機制和規則條件匹配的效率問題。當引擎執行時, 會根據規則執行隊列中的優先順序逐條執行規則執行實例, 由於規則的執行部分可能會改變工作區的數據對象, 從而會使隊列中的某些規則執行實例因爲條件改變而失效, 必須從隊列中撤銷;也可能會激活原來不滿足條件的規則, 生成新的規則執行實例進入隊列。於是就產生了一種“動態”的規則執行鏈, 形成規則的推理機制。這種規則的“鏈式”反應完全是由工作區中的數據驅動的。

2 Rete 算法

2.1 簡介

大部分規則引擎產品的算法, 基本上都來自於Charles Forgy 博士於1979 年提出Rete 算法及其變體, Rete 算法是目前效率最高的一個前向鍊形推理算法, 其核心思想是將分離的匹配項根據內容動態構造匹配樹, 以達到顯著降低計算量的效果。

2.2 算法描述

Rete 模式匹配算法是在模式匹配中利用推理機的時間冗餘性和規則結構的相似性, 通過保存中間去處來提高推理效率的一種模式匹配算法。

在模式匹配過程中, 規則的前提中可能會有很多相同的模塊, 因此在匹配規則前提時, 將進行大量的重複運算, 這樣就帶來時間冗餘性問題。例如:

RULE1:if (A>B) and D or C then E=100
RULE2:if (A>B) and (B<C) then E=200
RULE3:if (!(A>B) or (B<C)) then E=300

若要匹配這3 條規則時, 對於表達式A>B 要進行三次計算, 對B<C 需要兩次計算。Rete 採用的方法爲: 令M1=A>B, M2=B<C; 則規則可改爲:

RULE1:if (M1) and D or C then E=100
RULE2:if (M1) and (M2) then E=200
RULE3:if (!(M1) or (M2)) then E=300

這樣只有當A 或B 發生變化時, 才重新計算E1; 同樣當B 或C 發生變化時, 重新計算E2。這樣的推理避免了在每次進行模式匹配都重複計算相同的表達式, 而只要檢測相關參數是否變化來決定是否更新表達式, 這樣在推理過程中節省了大量時間和開銷, 從而提高了推理效率。

3 兩種主流規則引擎簡介

JSR94 規範定義了一組規則引擎的JAVA API,描述了一系列規則引擎的基本操作。這一系列操作的定義是基於一個假設, 即大多數客戶端需要執行一個多步規則引擎週期: 解析規則, 把對象放入引擎, 命中規則, 和從引擎中獲取結果對象。

規範定義的類和接口在javax.rules 和javax.rules.admin 包中。javax.rules 中包含用於規則引擎運行時客戶端的類和接口, 它們提供了從一個註冊的規則執行集獲取規則會話( rule session) , 並和規則會話交互的方法。而管理API 提供了從外部資源, 加載規則執行集的方法, 這些外部資源包括URI、輸入流、XML 文檔、二進制抽象語法樹和Reader。管理API 還包括註冊和註銷規則執行集的方法。只有註冊的規則執行集才能夠通過運行時客戶API 訪問。

比如: Sandia National 實驗室的Jess 規則引擎;開源軟件Drools 規則引擎等[5]。

3.1 Jess

在Jess 中, 規則的表達形式沿用了CLIPS 的語法結構, 通過對規則前件和後件的限定, 它可以支持內容豐富的模式匹配語言。另外, Jess 支持面向過程的編程方式, 它提供了一些語句來控制規則後件的操作流程, 如使用if...then...else 和while...do...語句, 這樣它就能很有效地利用面向過程編程的優勢。總之, Jess 的這些特性使系統擁有很強的知識表示能力。

例如:

( defrule library- rule- 1
                   ( book ( name ?X) ( status late) ( borrower ?Y) )
                   ( borrower ( name ?Y) ( address ?Z) )
=>
                   ( send- late- notice ?X ?Y ?Z) )

這套規則可以被翻譯作中文這樣理解: Thisrule might be
庫規則#1:
如果出現一本超期的名字爲X 的書, 它是名字爲Y 的人所借, 並且, Z 知道借者的地址, 則給Y 發送一條關於X 書的通知到Z 處[6]。

3.2 Drools

Drools 也是基於Charles Forgy' s 的Rete 算法的, 專爲Java 語言所設計的規則引擎。Rete 算法應用於面向對象的接口將使基於商業對象的商業規則的表達更爲自然。Drools 是用Java 寫的, 但能同時運行在Java 和.Net 上。

Drools 提供了聲明式程序設計(DeclarativeProgramming) , 並且使用域描述語言(Domain Specific Languages(DSL) ) 爲問題域定義了某種模式的Xml, 從而可以用來描述用戶問題域。DSLs 包含的Xml 元素( Element) 和屬性(Attribute) 代表了問題域中各種要素。例如:規則集是符合特定模式的Xml 文件( 詳見XmlSpy 的鏈接)。規則“語言”實際就是Portal 表達軟件包的使用, 可以擴充以滿足規則引擎的額外要求。
Drools規則集的擴展名爲.rls, 一般包括標籤〈cr:rule- set〉、規則〈cr:rule〉、每個規則中又定義有測試條件〈cr:condition〉與動作〈cr:actions〉。

例如:

<rule- set name="test rules"
                   <rule name="books">
                                     <parameter identifier="x">
                                                       <java:class>com.zhang.rules</java:class>
                                     </parameter>
                                     <java:condition>x.getStatus( ) .equals( "y:borrower")</java:condition>
                                     <java:consequence>vo.setMassage( z,"late book")</java:consequence>
                   </rule>
</rule- set>

4 結束語

基於Rete 算法的Java 規則引擎API (JSR- 94)允許客戶程序使用統一的方式和不同廠商的規則引擎產品交互, 一定程度上給規則引擎廠商提供了標準化規範。但其幾乎沒有定義什麼是規則引擎,當然也沒有深入到規則是如何構建和操縱的、規則調用的效用、規則與Java 語言的綁定等方面。並且JSR- 94 在對J2EE 的支持上也不足[1]。Jess 與Drools則各有千秋, 但規則語言的標準化, JSR- 94 的進一步的充實深化都有待研究。

致謝: 感謝李廣生、張河清、歐建深給予我的幫助。

參考文獻

1 Browne P. Using Drools in your enterprise java application. http://www.onjava.com/pub/a/onjava/2005/08/24/drools. html. 08/2005
2 Rupp N A. An introduction to the Drools project, http://www.theserverside.com/articles/content/Drools/article.html.05/2004
3 何仁杰, 樑冰. 用規則引擎替換代碼. http://blog.csdn.net/csdnloading/archive/2005/02/02/277276.aspx. 2004
4 李國樂. Java 規則引擎與其API . http:/ /www- 128. ibm. com/developerworks/cn/java/j- java- rules/#IDACCWOB. 07/2005
5 JSR94:Java Rule Engine APIhttp://jcp.org/en/jsr/detail?id=94.2005
6 Ernest J. Friedman- Hill .Jess, The Java Expert System Shell http://herzberg.ca.sandia.gov/jess. 1997

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章