89.3. 状態の例のデシジョン (前向き連鎖および競合解決)
状態の例のディジョンセットでは、デシジョンエンジンが前向き連鎖と、ワーキングメモリー内のファクトへの変更をどのように使用してルールの実行競合を順番に解決していくのかを例示します。この例では、ルールで定義可能な顕著性の値またはアジェンダグループを使用して競合を解決することにフォーカスします。
以下は、状態の例の概要です。
- 
							名前: state
- 
							Main クラス: (src/main/java内の)org.drools.examples.state.StateExampleUsingSalience、org.drools.examples.state.StateExampleUsingAgendaGroup
- 
							モジュール: drools-examples
- タイプ: Java アプリケーション
- 
							ルールファイル: (src/main/resources内の)org.drools.examples.state.*.drl
- 目的: ルールの顕著性やアジェンダグループを使用した前向き連鎖や競合解決を例示します。
前向き連鎖のルールシステムは、ディジョンエンジンのワーキングメモリーにあるファクトで開始して、そのファクトへの変更に反応するデータ駆動型のシステムです。オブジェクトがワーキングメモリーに挿入されると、その変更の結果として True となるルールの条件はすべて、アジェンダによって実行されるようにスケジュールされます。
反対に、後向き連鎖のルールシステムは、しばしば再帰を使用して、デシジョンエンジンが満たそうとする結論から開始する目的駆動型のシステムです。システムが結論または目的に到達できない場合は、サブとなる目的、つまり、現在の目的の一部を完了する結論を検索します。システムは、最初の結論が満たされるか、すべてのサブとなる目的が満たされるまでこのプロセスを続行します。
Red Hat Process Automation Manager のデシジョンエンジンは、前向き連鎖と後向き連鎖の両方を使用してルールを評価します。
以下の図は、デシジョンエンジンが、ロジックフローで後向き連鎖のセグメントと、前向き連鎖全体を使用してルールを評価する方法を例示します。
図89.4 前向き連鎖と後向き連鎖を使用したルール評価のロジック
					状態の例では、State クラスごとに、名前や現在の状態のフィールドが含まれます (org.drools.examples.state.State のクラス参照)。以下の状態は、各プロジェクトで考えられる 2 つの状態です。
				
- 
							NOTRUN
- 
							FINISHED
State クラス
状態の例には、同じ例が 2 つのバージョンとして提供されており、それぞれルール実行の競合を解決します。
- 
							ルールの顕著性を使用して競合を解決する StateExampleUsingSalienceバージョン
- 
							ルールアジェンダグループを使用して競合を解決する StateExampleUsingAgendaGroupsバージョン
					状態の例のバージョンはいずれも、A、B、C、および D の 4 つの State オブジェクトを使用します。最初に、それぞれの状態は、NOTRUN に設定されます。NOTRUN は、例が使用するコンストラクターのデフォルト値です。
				
顕著性を使用した状態の例
					状態の例の StateExampleUsingSalience バージョンでは、ルールで顕著性の値を使用し、ルール実行の競合を解決します。顕著性の値が高いルールは、アクティベーションキューの順番で、優先度が高くなります。
				
					この例では、各 State インスタンスを KIE セッションに挿入して、fireAllRules() を呼び出します。
				
顕著性の状態例の実行
					この例を実行するには、IDE で Java アプリケーションとして org.drools.examples.state.StateExampleUsingSalience クラスを実行します。
				
実行後に、以下の出力が IDE コンソールウィンドウに表示されます。
IDE コンソールでの顕著性の状態例の出力
A finished B finished C finished D finished
A finished
B finished
C finished
D finished4 つのルールが存在します。
					まず、"Bootstrap" ルールが実行され、A の状態が FINISHED に設定されます。次に、B の状態が FINISHED に変更されます。オブジェクト C と D はいずれも B に依存するため競合が発生しますが、顕著性の値で解決されます。
				
					この例の実行フローをさらに理解するには、target/state.log の監査ログファイルを IDE デバッグビュー (または Audit View が利用できる場合は Audit View (例: IDE の Window 
					この例では、Audit View は、状態が NOTRUN のオブジェクト A のアサーションが "Bootstrap" ルールをアクティベートしますが、他のオブジェクトのアサーションはすぐに有効になりません。
				
図89.5 顕著性の状態例の監査ビュー
顕著性の状態例の "Bootstrap" ルール
					"Bootstrap" ルールを実行すると、A の状態が FINISHED に変わり、ルール "A to B" をアクティベートします。
				
顕著性の状態例の "A to B" ルール
					"A to B" ルールを実行すると、B の状態を FINISHED に変更し、"B to C" と "B to D" の両方のルールをアクティベートして、これらのアクティベーションをデシジョンエンジンアジェンダに配置します。
				
顕著性の状態例の "B to C" および "B to D" ルール
					この時点から、両方のルールが実行される可能性があるため、これらのルールは競合しています。競合解決ストラテジーを使用すると、デシジョンエンジンアジェンダがどのルールを実行するかを決定できます。"B to C" は、顕著性の値が高いため (デフォルトの顕著性の値 0 に対して 10) 先に実行し、オブジェクト C の状態が FINISHED に変更されます。
				
					IDE の Audit View では、ルール "A to B" の State オブジェクトが変更され、2 つのアクティベーションが競合する結果になることが分かります。
				
					IDE で Agenda View を使用して、デシジョンエンジンアジェンダの状態を調査できます。この例では Agenda View で、ルール "A to B" のブレークポイントと、2 つの競合するルールを持つアジェンダの状態が分かります。最後にルール "B to D" が実行され、オブジェクト D の状態が FINISHED に変更されます。
				
図89.6 顕著性の状態例のアジェンダビュー
アジェンダグループを使用した状態の例
					状態の例の StateExampleUsingAgendaGroups バージョンでは、ルールでアジェンダグループを使用し、ルール実行における競合を解決します。アジェンダグループを使用すると、デシジョンエンジンアジェンダが分割され、ルールのグループの実行に対してこれまで以上に制御ができるようになります。デフォルトでは、ルールはすべてアジェンダグループ MAIN に含まれています。agenda-group 属性を使用して、ルールに異なるアジェンダグループを指定できます。
				
					最初は、ワーキングメモリーは、アジェンダグループ MAIN にフォーカスを当てます。アジェンダグループのルールは、グループがこのフォーカスを受けた場合のみ実行されます。setFocus() メソッドか、auto-focus ルール属性を使用してフォーカスを設定できます。auto-focus 属性を使用すると、ルールが一致してアクティベートされた場合のみ、ルールにアジェンダグループのフォーカスが自動的に当てられます。
				
					この例では、auto-focus 属性を使用すると "B to D" の前に "B to C" ルールを実行できます。
				
アジェンダグループの状態例のルール "B to C"
					ルール "B to C" は、アジェンダグループ "B to D" の setFocus() を呼び出し、アクティブなルールを実行できるようにします。その後にルール "B to D" が実行できるようになります。
				
アジェンダグループの状態例のルール "B to D"
					この例を実行するには、IDE で Java アプリケーションとして org.drools.examples.state.StateExampleUsingAgendaGroups クラスを実行します。
				
実行後に、以下の出力が IDE コンソールウィンドウに表示されます (状態の例の顕著性バージョンと同じ)。
IDE コンソールでのアジェンダグループの状態例の出力
A finished B finished C finished D finished
A finished
B finished
C finished
D finished状態の例の含まれる動的なファクト
					状態の例に含まれる主なコンセプトとしては、他にも PropertyChangeListener オブジェクトを実装するオブジェクトに基づいて 動的ファクト を使用するというものがあります。デシジョンエンジンがファクトプロパティーへの変更を確認し、対応するためには、アプリケーションがデシジョンエンジンに対して、変更があったことを通知する必要があります。modify ステートメントを使用して、このコミュニケーションをルールで明示的に設定するか、JavaBeans 仕様で定義されているようにファクトが PropertyChangeSupport インターフェイスを実装するように指定することで暗黙的に設定できます。
				
					この例は、ルールで modify ステートメントを明示的に指定しなくても良いように PropertyChangeSupport インターフェイスを使用する方法が示されています。このインターフェイスを使用するには、org.drools.example.State クラスと同じ方法で、ファクトに PropertyChangeSupport が実装されていることを確認し、DRL ルールファイルで以下のコードを使用して、これらのファクトでプロパティー変更がないかをリッスンするようにデシジョンエンジンを設定してください。
				
動的ファクトの宣言
declare type State @propertyChangeSupport end
declare type State
  @propertyChangeSupport
end
					PropertyChangeListener オブジェクトを使用する場合に、各セッターは通知用に追加のコードを実装する必要があります。たとえば、state の以下のセッターは org.drools.examples のクラスに含まれます。
				
PropertyChangeSupport のセッター例
 
     
    