21.7. 誠実な政治家の例のデシジョン (真理維持および顕著性)
誠実な政治家のデシジョンセットの例では、論理挿入を使用した真理維持の概念およびルールでの顕著性の使用方法を説明します。
以下は、誠実な政治家の例の概要です。
-
名前:
honestpolitician
-
Main クラス: (
src/main/java
内の)org.drools.examples.honestpolitician.HonestPoliticianExample
-
モジュール:
drools-examples
- タイプ: Java アプリケーション
-
ルールファイル: (
src/main/resources
内の)org.drools.examples.honestpolitician.HonestPolitician.drl
- 目的: ファクトの論理挿入をもとにした真理維持の概念およびルールでの顕著性の使用方法を紹介します。
誠実な政治家例の前提として基本的に、ステートメントが True の場合にのみ、オブジェクトが存在できます。insertLogical()
メソッドを使用して、ルールの結果により、オブジェクトを論理的に挿入します。つまり、論理的に挿入されたルールが True の状態であれば、オブジェクトは KIE セッションのワーキングメモリー内に留まります。ルールが True でなくなると、オブジェクトは自動的に取り消されます。
この例では、ルールを実行することで、企業による政治家の買収が原因で、政治家グループが誠実から不誠実に変わります。各政治家が評価されるにつれ、最初は honesty 属性を true
に設定して開始しますが、ルールが実行すると政治家は誠実ではなくなります。状態が誠実から不誠実に切り替わると、ワーキングメモリーから削除されます。ルールの顕著性により、顕著性が定義されているルールをどのように優先付けするかを、デシジョンエンジンに通知します。通知しないと、デフォルトの顕著性である 0
が使用されます。顕著性の値が高いルールは、アクティベーションキューの順番で、優先度が高くなります。
Politician クラスおよび Hope クラス
この例の Politician
クラス例は、誠実な政治家として設定されています。Politician
クラスは、文字列アイテム name
とブール値アイテム honest
で設定されています。
Politician クラス
public class Politician { private String name; private boolean honest; ... }
Hope
クラスは、Hope
オブジェクトが存在するかどうかを判断します。このクラスには意味を持つメンバーは存在しませんが、社会に希望がある限り、ワーキングメモリーに存在します。
Hope クラス
public class Hope { public Hope() { } }
政治家の誠実性に関するルール定義
誠実な政治家の例では、ワーキングメモリーに最低でも 1 名誠実な政治家が存在する場合は、"We have an honest Politician"
ルールで論理的に新しい Hope
オブジェクトを挿入します。すべての政治家が不誠実になると、Hope
オブジェクトは自動的に取り除かれます。このルールでは、salience
属性の値が 10
となっており、他のルールより先に実行されます。理由は、この時点では "Hope is Dead"
ルールが True となっているためです。
ルール "We have an honest politician"
rule "We have an honest Politician" salience 10 when exists( Politician( honest == true ) ) then insertLogical( new Hope() ); end
Hope
オブジェクトが存在すると、すぐに "Hope Lives"
ルールが一致して実行されます。"Corrupt the Honest"
ルールよりも優先されるように、このルールにも salience
値を 10
に指定しています。
ルール "Hope Lives"
rule "Hope Lives" salience 10 when exists( Hope() ) then System.out.println("Hurrah!!! Democracy Lives"); end
最初は、誠実な政治家が 4 人いるため、このルールには 4 つのアクティベーションが存在し、すべてが競合しています。各ルールが順番に実行し、政治家が誠実でなくなるように、企業により各政治家を買収させていきます。政治家 4 人が全員買収されたら、プロパティーが honest == true
の政治家はいなくなります。"We have an honest Politician"
のルールは True でなくなり、論理的に挿入されるオブジェクト (最後に実行された new Hope()
による) は自動的に取り除かれます。
ルール "Corrupt the Honest"
rule "Corrupt the Honest" when politician : Politician( honest == true ) exists( Hope() ) then System.out.println( "I'm an evil corporation and I have corrupted " + politician.getName() ); modify ( politician ) { honest = false }; end
真理維持システムにより Hope
オブジェクトが自動的に取り除かれると、Hope
に適用された条件付き要素 not
は True でなくなり、"Hope is Dead"
ルールが一致して実行されます。
ルール "Hope is Dead"
rule "Hope is Dead" when not( Hope() ) then System.out.println( "We are all Doomed!!! Democracy is Dead" ); end
実行と監査証跡
HonestPoliticianExample.java
クラスでは、honest の状態が true
に設定されている政治家 4 人が挿入され、定義したビジネスルールに対して評価されます。
HonestPoliticianExample.java クラスの実行
public static void execute( KieContainer kc ) { KieSession ksession = kc.newKieSession("HonestPoliticianKS"); final Politician p1 = new Politician( "President of Umpa Lumpa", true ); final Politician p2 = new Politician( "Prime Minster of Cheeseland", true ); final Politician p3 = new Politician( "Tsar of Pringapopaloo", true ); final Politician p4 = new Politician( "Omnipotence Om", true ); ksession.insert( p1 ); ksession.insert( p2 ); ksession.insert( p3 ); ksession.insert( p4 ); ksession.fireAllRules(); ksession.dispose(); }
この例を実行するには、IDE で Java アプリケーションとして org.drools.examples.honestpolitician.HonestPoliticianExample
クラスを実行します。
実行後に、以下の出力が IDE コンソールウィンドウに表示されます。
IDE コンソールでの実行出力
Hurrah!!! Democracy Lives I'm an evil corporation and I have corrupted President of Umpa Lumpa I'm an evil corporation and I have corrupted Prime Minster of Cheeseland I'm an evil corporation and I have corrupted Tsar of Pringapopaloo I'm an evil corporation and I have corrupted Omnipotence Om We are all Doomed!!! Democracy is Dead
この出力では、democracy lives に誠実な政治家が最低でも 1 人いることが分かります。ただし、各政治家は企業に買収されているため、全政治家が不誠実になり、民主性がなくなります。
この例の実行フローをさらに理解するために、HonestPoliticianExample.java
クラスを変更し、DebugRuleRuntimeEventListener
リスナーと監査ロガーを追加して実行の詳細を表示することができます。
監査ロガーを含む HonestPoliticianExample.java クラス
package org.drools.examples.honestpolitician; import org.kie.api.KieServices; import org.kie.api.event.rule.DebugAgendaEventListener; 1 import org.kie.api.event.rule.DebugRuleRuntimeEventListener; import org.kie.api.runtime.KieContainer; import org.kie.api.runtime.KieSession; public class HonestPoliticianExample { /** * @param args */ public static void main(final String[] args) { KieServices ks = KieServices.Factory.get(); 2 //ks = KieServices.Factory.get(); KieContainer kc = KieServices.Factory.get().getKieClasspathContainer(); System.out.println(kc.verify().getMessages().toString()); //execute( kc ); execute( ks, kc); 3 } public static void execute( KieServices ks, KieContainer kc ) { 4 KieSession ksession = kc.newKieSession("HonestPoliticianKS"); final Politician p1 = new Politician( "President of Umpa Lumpa", true ); final Politician p2 = new Politician( "Prime Minster of Cheeseland", true ); final Politician p3 = new Politician( "Tsar of Pringapopaloo", true ); final Politician p4 = new Politician( "Omnipotence Om", true ); ksession.insert( p1 ); ksession.insert( p2 ); ksession.insert( p3 ); ksession.insert( p4 ); // The application can also setup listeners 5 ksession.addEventListener( new DebugAgendaEventListener() ); ksession.addEventListener( new DebugRuleRuntimeEventListener() ); // Set up a file-based audit logger. ks.getLoggers().newFileLogger( ksession, "./target/honestpolitician" ); 6 ksession.fireAllRules(); ksession.dispose(); } }
- 1
DebugAgendaEventListener
とDebugRuleRuntimeEventListener
を処理するインポートにパッケージを追加します。- 2
- この監査ログは
KieContainer
レベルでは利用できないため、KieServices Factory
要素およびks
要素を作成してログを生成します。 - 3
execute
メソッドを変更してKieServices
とKieContainer
の両方を使用します。- 4
execute
メソッドを変更してKieContainer
に加えてKieServices
で渡します。- 5
- リスナーを作成します。
- 6
- ルールの実行後にデバッグビュー、監査ビュー、または IDE に渡すことが可能なログを構築します。
ログ機能を変更して誠実な政治家のサンプルを実行すると、target/honestpolitician.log
から IDE デバッグビュー、または利用可能な場合には 監査ビュー (IDE の一部では Window
この例では、監査ビュー では、クラスやルールのサンプルで定義されているように、実行、挿入、取り消しのフローが示されています。
図21.18 誠実な政治家の例での監査ビュー
最初の政治家が挿入されると、2 つのアクティベーションが発生します。"We have an honest Politician"
のルールは、exists
の条件付き要素を使用するため、最初に挿入された政治家に対してのみ一度だけアクティベートされます。この条件付き要素は、政治家が最低でも 1 人挿入されると一致します。Hope
オブジェクトがまだ挿入されていないため、ルール "Hope is Dead"
もこの時点でアクティベートになります。"We have an honest Politician"
ルールは、"Hope is Dead"
ルールより、salience
の値が高いため先に実行され、Hope
オブジェクト (緑にハイライト) を挿入します。Hope
オブジェクトを挿入すると、ルール "Hope Lives"
が有効になり、ルール "Hope is Dead"
が無効になります。この挿入により、挿入された誠実な各政治家に対して "Corrupt the Honest"
ルールがアクティベートになります。"Hope Lives"
のルールが実行して、"Hurrah!!!Democracy Lives"
が出力されます。
次に、政治家ごとに "Corrupt the Honest"
ルールを実行して "I'm an evil corporation and I have corrupted X"
と出力します。X
は政治家の名前で、その政治家の誠実値が false
に変更になります。最後の誠実な政治家が買収されると、真理維持システム (青でハイライト) により Hope
が自動的に取り消されます。緑でハイライトされたエリアは、現在選択されている青のハイライトエリアの出元です。Hope
ファクトが取り消されると、"Hope is dead"
ルールが実行して "We are all Doomed!!!Democracy is Dead"
が出力されます。