89.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
DebugAgendaEventListenerDebugRuleRuntimeEventListener を処理するインポートにパッケージを追加します。
2
この監査ログは KieContainer レベルでは利用できないため、KieServices Factory 要素および ks 要素を作成してログを生成します。
3
execute メソッドを変更して KieServicesKieContainer の両方を使用します。
4
execute メソッドを変更して KieContainer に加えて KieServices で渡します。
5
リスナーを作成します。
6
ルールの実行後にデバッグビュー、監査ビュー、または IDE に渡すことが可能なログを構築します。

ログ機能を変更して誠実な政治家のサンプルを実行すると、target/honestpolitician.log から IDE デバッグビュー、または利用可能な場合には 監査ビュー (IDE の一部では WindowShow View) に、監査ログファイルを読み込むことができます。

この例では、監査ビュー では、クラスやルールのサンプルで定義されているように、実行、挿入、取り消しのフローが示されています。

図89.18 誠実な政治家の例での監査ビュー

honest politician audit

最初の政治家が挿入されると、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" が出力されます。