最近在学习规则推理引擎,主要是在看JBoss Drools,有了一点点入门,自己写个例子练习一下,同时也和初学的同学们分享交流。
规则定义的代码如下:Hanoi.drl
package com.sample.hanoi
/*
*/
#list any import classes here.
#declare any global variables here
rule "apply for the n=1"
when
#conditions
h : Hanoi( sequence == 1 )
then
#actions
System.out.println( h.getOne() + " -> " + h.getThree() );
end
rule "apply for the n>1."
#include attributes such as "salience" here...
when
#conditions
h : Hanoi( sequence > 1 )
then
#actions
insert( new Hanoi( h.getSequence() - 1,h.getTwo(),h.getOne(),h.getThree() ) );
insert( new Hanoi( 1, h.getOne(), h.getTwo(), h.getThree()) );
insert( new Hanoi( h.getSequence() - 1,h.getOne(),h.getThree(),h.getTwo() ) );
end
以上是Hanoi算法的规则表示,是比较简单的,主要注意两个问题:
首先,我采用的是Drools官方示例中的Fibonacci的例子的解决办法,引入了一个sequence的变量,这个变量是来记录有多少层塔的。
其次,大家在看代码的时候,可能注意到了,在"apply for the n>1."规则的后件中的顺序与我们平常写得Hanoi程序正好相反,这是为什么呢?原来这是Drools冲突解决策略的一种方案。
Drools的冲突解决的方案主要两种:
第一种:Salience,即优先级策略。用户可以为某个 rule 指定一个高一点的优先级(通过附给它一个比较大的数字)。高 Salience 的 rule 将会被优先激发。
第二种:LIFO,当规则的salience相同,又出现执行顺序冲突时,按照LIFO(后进先出)策略
我这里是利用了第二种策略,所以顺序正好相反。
下面是Hanoi的Bean类和程序的主类:
public class Hanoi {
private String one;
private String two;
private String three;
private int sequence;
public Hanoi() {
super();
}
public Hanoi(int sequence) {
super();
this.sequence = sequence;
}
public Hanoi(int sequence, String one, String two, String three ) {
super();
this.one = one;
this.two = two;
this.three = three;
this.sequence = sequence;
}
/**
* @return the sequence
*/
public int getSequence() {
return sequence;
}
/**
* @param sequence the sequence to set
*/
public void setSequence(int sequence) {
this.sequence = sequence;
}
/**
* @return the one
*/
public String getOne() {
return one;
}
/**
* @param one the one to set
*/
public void setOne(String one) {
this.one = one;
}
/**
* @return the two
*/
public String getTwo() {
return two;
}
/**
* @param two the two to set
*/
public void setTwo(String two) {
this.two = two;
}
/**
* @return the three
*/
public String getThree() {
return three;
}
/**
* @param three the three to set
*/
public void setThree(String three) {
this.three = three;
}
}
public class HanoiExample {
/**
* @param args
*/
public static void main(String[] args) throws Exception {
final PackageBuilder builder = new PackageBuilder();
builder.addPackageFromDrl( new InputStreamReader( FibonacciExample.class.getResourceAsStream( "/Hanoi.drl" ) ) );
final RuleBase ruleBase = RuleBaseFactory.newRuleBase();
ruleBase.addPackage( builder.getPackage() );
final StatefulSession session = ruleBase.newStatefulSession();
session.insert( new Hanoi( 4, "A", "B", "C" ) );
session.fireAllRules();
session.dispose(); // Stateful rule session must always be disposed when finished
}
这是我自己尝试的第一个例子,在写规则的时候,我觉还是有很多问题的,最主要的就是:如何更好的里利用drools提供的功能,写出精炼的规则?还有很多的隐藏的规则如何发现?这些都是需要多多经验的,希望能够和大家讨论,共同进步。