Droolsでの後方連鎖の例

Droolsでの逆方向チェーンの例

1. 概要

この記事では、後向き連鎖とは何か、そしてそれをDroolsでどのように使用できるかを見ていきます。

この記事は、Drools Business Rules Engineを紹介するシリーズの一部です。

2. Mavenの依存関係

drools-coredependencyをインポートすることから始めましょう:


    org.drools
    drools-core
    7.4.1.Final

3. フォワードチェーン

まず、フォワードチェーンでは、データの分析から始め、特定の結論に向かって進みます。

フォワードチェーンを適用する例としては、ノード間の既知の接続を検査して新しいルートを検出するシステムがあります。

4. 後方連鎖

前向き連鎖とは対照的に、backward chaining starts directly with the conclusion (hypothesis) and validates it by backtracking through a sequence of facts.

前向き連鎖と後向き連鎖を比較する場合、the first one can be described as “data-driven” (data as input), while the latter one can be described as “event(or goal)-driven” (goals as inputs).

後向き連鎖を適用する例は、2つのノードを接続するルートがあるかどうかを検証することです。

5. Drools後向き連鎖

Droolsプロジェクトは、主にフォワードチェーンシステムとして作成されました。 ただし、バージョン5.2.0以降では、後方チェーンもサポートしています。

簡単なアプリケーションを作成して、簡単な仮説–if the Great Wall of China is on Planet Earthを検証してみましょう。

5.1. データ

物事とその場所を説明する簡単なファクトベースを作成しましょう。

  1. 地球

  2. アジア、惑星地球

  3. 中国、アジア

  4. 万里の長城、中国

5.2. ルールの定義

それでは、/resources/com/example/drools/rules/に配置するBackwardChaining.drlという名前の「.drl」ファイルを作成しましょう。 これには、例で使用される必要なすべてのクエリとルールが含まれます。

後向き連鎖を利用するメインのbelongsToクエリは、次のように記述できます。

query belongsTo(String x, String y)
    Fact(x, y;)
    or
    (Fact(z, y;) and belongsTo(x, z;))
end

さらに、結果を簡単に確認できるようにする2つのルールを追加しましょう。

rule "Great Wall of China BELONGS TO Planet Earth"
when
    belongsTo("Great Wall of China", "Planet Earth";)
then
    result.setValue("Decision one taken: Great Wall of China BELONGS TO Planet Earth");
end

rule "print all facts"
when
    belongsTo(element, place;)
then
    result.addFact(element + " IS ELEMENT OF " + place);
end

5.3. アプリケーションの作成

次に、ファクトを表すためのJavaクラスが必要です。

public class Fact {

    @Position(0)
    private String element;

    @Position(1)
    private String place;

    // getters, setters, constructors, and other methods ...
}

ここでは、@Positionアノテーションを使用して、Droolsがこれらの属性の値を提供する順序をアプリケーションに通知します。

また、結果を表すPOJOを作成します。

public class Result {
    private String value;
    private List facts = new ArrayList<>();

    //... getters, setters, constructors, and other methods
}

そして今、例を実行することができます:

public class BackwardChainingTest {

    @Before
    public void before() {
        result = new Result();
        ksession = new DroolsBeanFactory().getKieSession();
    }

    @Test
    public void whenWallOfChinaIsGiven_ThenItBelongsToPlanetEarth() {

        ksession.setGlobal("result", result);
        ksession.insert(new Fact("Asia", "Planet Earth"));
        ksession.insert(new Fact("China", "Asia"));
        ksession.insert(new Fact("Great Wall of China", "China"));

        ksession.fireAllRules();

        assertEquals(
          result.getValue(),
          "Decision one taken: Great Wall of China BELONGS TO Planet Earth");
    }
}

テストケースが実行されると、与えられた事実(「Asia belongs to Planet Earth」、「中国belongs toアジア」、「万里の長城は中国に属する」)が追加されます。

その後、ファクトはBackwardChaining.drlで記述されたルールで処理され、再帰クエリbelongsTo(String x, String y).が提供されます。

このクエリは、後向き連鎖を使用して仮説(“Great Wall of China BELONGS TO Planet Earth”)が真か偽かを見つけるルールによって呼び出されます。

6. 結論

決定が正しいかどうかを検証するために事実のリストを取得するために使用されるDroolsの機能である後向き連鎖の概要を示しました。

いつものように、完全な例はGitHub repositoryにあります。