83.5. デシジョンエンジンにおけるファクトの伝播モード

デシジョンエンジンは、以下のファクト伝播モードをサポートします。このモードは、ルール実行の準備としてエンジンネットワークを介して挿入されたファクトを、デシジョンエンジンが進める方法を決定します。

  • Lazy: (デフォルト) ファクトはルール実行時にバッチコレクションで伝播されますが、ユーザーまたはアプリケーションによってファクトは個別に挿入されるため、リアルタイムでは実行されません。その結果、ファクトが最終的にデシジョンエンジンを介して伝播される順序は、ファクトが個別に挿入された順序とは異なる可能性があります。
  • Immediate: ファクトは、ユーザーまたはアプリケーションが挿入する順序で即座に伝播されます。
  • Eager: ファクトは (バッチコレクション内に) 遅延して伝播されますが、ルールの実行前には伝播されます。デシジョンエンジンは、no-loop または lock-on-active の属性を持つルールに対してこの伝播動作を使用します。

デフォルトでは、デシジョンエンジンの Phreak ルールアルゴリズムは、改善されたルール評価全体に対して Lazy (遅延) ファクト伝播を使用します。ただし、場合によっては、この Lazy 伝播動作は、Immediate または Eager 伝播を必要とする特定のルール実行の想定される結果を変更する可能性があります。

たとえば、以下のルールは接頭辞に ? を指定したクエリーを使用して、プルオンリーまたはパッシブ方式でクエリーを呼び出します。

パッシブクエリーを使用したルールの例

query Q (Integer i)
    String( this == i.toString() )
end

rule "Rule"
  when
    $i : Integer()
    ?Q( $i; )
  then
    System.out.println( $i );
end

この例では、クエリーを満たす StringInteger の前に挿入される場合にのみ、ルールを実行する必要があります。たとえば、以下のコマンド例のようになります。

ルールの実行をトリガーするコマンドの例

KieSession ksession = ...
ksession.insert("1");
ksession.insert(1);
ksession.fireAllRules();

ただし、Phreak におけるデフォルトの Lazy (遅延) 伝播動作が原因で、デシジョンエンジンはこの場合における 2 つのファクトの挿入シーケンスを検出しません。そのため、String および Integer の挿入順序に関係なく、このルールは実行されます。この例では、想定されるルール評価には Immediate 伝播が必要です。

デシジョンエンジンの伝播モードを変更して、この場合に想定されるルール評価を達成するには、ルールに @Propagation(<type>) タグを追加し、<type>LAZYIMMEDIATE、または EAGER に設定します。

同じルールの例では、想定どおりに、Immediate 伝播アノテーションによって、クエリーを満たす StringInteger の前に挿入される場合にのみ、ルールが評価されます。

パッシブクエリーと指定された伝播モードを使用したルールの例

query Q (Integer i)
    String( this == i.toString() )
end

rule "Rule" @Propagation(IMMEDIATE)
  when
    $i : Integer()
    ?Q( $i; )
  then
    System.out.println( $i );
end