Droolsを使って、ルールベース(BRMS)の動きを見るためにちょっと実験してみました。Droolsで、Projectをつくるとサンプルのプログラムをつくってくれますが、それをすこしばかり修正しての実験です。
(ルールベースの動きの基本は、プロダクションシステムとはとか、当ブログのルールベースプログラミングのカテゴリなどを参照ください)
まずは、ルール処理の対象となるファクトを準備します。
SampleFact.java
package com.sample;
public class SampleFact {
private int num;
private String name;
public SampleFact() {
super();
}
public SampleFact(int num, String name) {
super();
this.num = num;
this.name = name;
}
/**
* @return the num
*/
public int getNum() {
return num;
}
/**
* @param num the num to set
*/
public void setNum(int num) {
this.num = num;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "SampleFact [num=" + num
+ ", name=" + name + "]";
}
}
そして、mainプログラム
DroolsTest.java
package com.sample;
import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
/**
* This is a sample class to launch a rule.
*/
public class DroolsTest {
public static final void main(String[] args) {
try {
// load up the knowledge base
KieServices ks
= KieServices.Factory.get();
KieContainer kContainer
= ks.getKieClasspathContainer();
KieSession kSession
= kContainer.newKieSession("ksession-rules");
// go !
SampleFact sf1 = new SampleFact(1, "A");
SampleFact sf2 = new SampleFact(2, "B");
SampleFact sf3 = new SampleFact(3, "C");
SampleFact sf4 = new SampleFact(4, "D");
SampleFact sf5 = new SampleFact(5, "E");
kSession.insert(sf1);
kSession.insert(sf2);
kSession.insert(sf3);
kSession.insert(sf4);
kSession.insert(sf5);
kSession.fireAllRules();
} catch (Throwable t) {
t.printStackTrace();
}
}
上のように5つのファクトをワーキングメモリに追加して、以下のルール
Sample.drl
package com.sample
rule "サンプルルール1"
when
SampleFact($num: num, $name: name)
then
System.out.println("num=" + $num
+ ", name=" + $name);
end
を実行しました。
コンソールには、どのように表示されるでしょうか。
まあ、これはワーキングメモリに5つのファクトがあるので、単純に
条件節(when部分)のSampleFactにマッチして、5回ルールのサイクルが回ります。
num=5, name=E
num=4, name=D
num=3, name=C
num=2, name=B
num=1, name=A
つまり条件部にマッチしたファクトが
SampleFact(1, “A”);
SampleFact(2, “B”);
SampleFact(3, “C”);
SampleFact(4, “D”);
SampleFact(5, “E”);
の5つだったということ。
では、上記のサンプルルール1のかわりに次のルールがあった場合は
どうなるでしょうか
Sample.drl(改)
package com.sample
rule "サンプルルール1a"
when
SampleFact($num: num > 3, $name: name)
then
System.out.println("num=" + $num
+ ", name=" + $name);
end
このときは条件節に num > 3 という条件が加わったので
num=5, name=E
num=4, name=D
の2つのみが表示されます。
すなわち条件部にマッチしたファクトが
SampleFact(4, “D”);
SampleFact(5, “E”);
の2つということ。
さらに次はどうでしょう。
Sample.drl(改々)
package com.sample
rule "サンプルルール2"
when
SampleFact($num: num, $name: name)
SampleFact($num1: num, $name1: name)
then
System.out.println("num=" + $num
+ ", name=" + $name
+ ", num1=" + $num1
+ ", name1=" + $name1);
end
今度は、条件節のSampleFactのパターンが2つになりました。結果は、
num=1, name=A, num1=1, name1=A
num=1, name=A, num1=2, name1=B
num=1, name=A, num1=3, name1=C
・・・(中略)・・・
num=5, name=E, num1=4, name1=D
num=5, name=E, num1=5, name1=E
以上、25行表示されました。
これは、条件節の最初のパターン
SampleFact($num: num, $name: name)
に5つのファクトがマッチして、さらに2番目のパターンにも
SampleFact($num1: num, $name1: name)
5つのファクトがマッチして結局その組合せとして5×5=25(通り)の
組合せが表示されているということを表しています。つまり
条件部にマッチしたファクトの組を
[<最初のパターンにマッチしたファクト>,<2番目のパターンにマッチしたファクト>]
の形であらわすとすると、
[SampleFact(1, “A”), SampleFact(1, “A”)]
[SampleFact(1, “A”), SampleFact(2, “B”)]
[SampleFact(1, “A”), SampleFact(3, “C”)]
・・・(中略)・・・
[SampleFact(5, “E”), SampleFact(4, “D”)]
[SampleFact(5, “E”), SampleFact(5, “E”)]
の25個のファクトの組が条件部にマッチしたことになります。
では、こんなルールであったらどうでしょうか。
Sample.drl(もひとつ改)
package com.sample
rule "サンプルルール2a"
when
SampleFact($num: num, $name: name)
SampleFact($num1: num > $num, $name1: name)
then
System.out.println("num=" + $num
+ ", name=" + $name
+ ", num1=" + $num1
+ ", name1=" + $name1);
end
(この項続く)
コメント