Clojure实现规则引擎

规则引擎

规则引擎由推理引擎发展而来,是一种嵌入在应用程序中的组件,实现了将业务决策从应用程序代码中分离出来,并使用预定义的语义模块编写业务决策。接受数据输入,解释业务规则,并根据业务规则做出业务决策。

1
2
3
4
when
<conditions>
then
<actions>;

最为著名的规则引擎是Drools,现由JBoss维护,分为Guvnor,Expert,Jbpm5,Jbpm5和Planner五个模块,应用在jBPM工作流中。
目前Java中开源规则引擎也非常多,Open Source Rule Engines in Java,Java也已经指定了rule engine规范

Clojure实现的规则引擎

现在比较著名的规则引擎有:
mimir,这个library不牵涉到复杂的数据结构,使用起来也比较简单。
clara,与Drools比较相似,其目标是解绑业务逻辑,同时利用的Clojure和Java生态系统的优势表达其作为组合的规则,以控制业务复杂性;使用起来比较简单,可以很好的在分布式系统上运行。
core.logic,严格意义上不能算是规则引擎Forward chaining范畴,实现了类似Prolog的逻辑编程(Backward chaining)。

mimir 使用

mimir是一个实验性的规则引擎,相对简单,截至现在已经2年多没有更新了,在这里也就不多介绍了。

1
2
3
4
5
6
7
8
9
(rule xyz
X < Y
Z > 5
Z = (+ X Y)
Z != Y
=>
(str X '+ Y '= Z))

(matches? "2+4=6"))

这段代码是先指定了规则(rule),然后判定一个fact是否满足该条件。

clara 使用

clara的基本使用在clara-example里面有很多示例。clara可以在Clojure,ClojureScript和Javay语言中使用。

1
2
3
4
5
(defrule free-lunch-with-gizmo
"Anyone who purchases a gizmo gets a free lunch."
[Purchase (= item :gizmo)]
=>
(insert! (->Promotion :free-lunch-with-gizmo :lunch)))

clara还提供了规则查询的功能

1
2
3
4
(defquery get-promotions
"Query to find promotions for the purchase."
[]
[?promotion <- Promotion])

core.logic使用

core.logic 严格来说是逻辑变成的范畴,过程是

1
事实 + 规则 =结果

是通过目前已经符合条件的事实 和现有规则来推导符合该规则的条件,相比与规则引擎是一种反向过程。
例如:

1
2
3
(run* [q]
(membero q [1 2 3])
(membero q [2 3 4]))

q满足了是[1 2 3]集合元素,又是 [2 3 4]的元素,计算q应该是什么。
core.logic主要采用一下方式:

1
2
(run* [logic-variable]
&logic-expressions)

支持fresh unify, ==等操作,默认条件是and操作,也可以通过conde支持OR操作。详细参见 core.logic Features

ruleengine

这是我为了练习Clojure而开的项目,结合了去年自己做优惠基础平台时的经验和想法的项目,目前还处于private状态。先写在这里,等到完成之后再公开项目。

References

Quora:How can Clojure be used for rules engines
The Rule Engine