Monitor and troubleshoot Java applications and services with Datadog: 

>> Try it free!

1. Overview

In this article, we’ll see how what Backward Chaining is and how we can use it with Drools.

This article is a part of a series showcasing the Drools Business Rules Engine.

2. Maven Dependencies

Let’s start by importing the drools-core dependency:

<dependency>
    <groupId>org.drools</groupId>
    <artifactId>drools-core</artifactId>
    <version>7.4.1.Final</version>
</dependency>

3. Forward Chaining

First of all, with forward chaining, we start by analyzing data and make our way towards a particular conclusion.

An example of applying forward chaining would be a system that discovers new routes by inspecting already known connections between nodes.

4. Backward Chaining

As opposed to forward chaining, backward chaining starts directly with the conclusion (hypothesis) and validates it by backtracking through a sequence of facts.

When comparing forward chaining and backward chaining, 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).

An example of applying backward chaining would be to validate if there’s a route connecting two nodes.

5. Drools Backward Chaining

The Drools project was created primarily as a forward chaining system. But, starting with version 5.2.0, it supports backward chaining as well.

Let’s create a simple application and try to validate a simple hypothesis – if the Great Wall of China is on Planet Earth.

5.1. The Data

Let’s create a simple fact base describing things and its location:

  1. Planet Earth
  2. Asia, Planet Earth
  3. China, Asia
  4. Great Wall of China, China

5.2. Defining Rules

Now, let’s create a “.drl” file called BackwardChaining.drl which we’ll place in /resources/com/baeldung/drools/rules/. This will contain all necessary queries and rules to be used in the example.

The main belongsTo query, that will utilize backward chaining, can be written as:

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

Additionally, let’s add two rules that will make it possible to review our results easily:

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. Creating the Application

Now, we’ll need a Java class for representing facts:

public class Fact {
 
    @Position(0)
    private String element;

    @Position(1)
    private String place;

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

Here we use the @Position annotation to tell the application in which order Drools will supply values for those attributes.

Also, we’ll create the POJO representing results:

public class Result {
    private String value;
    private List<String> facts = new ArrayList<>();
 
    //... getters, setters, constructors, and other methods
}

And now, we can run the example:

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");
    }
}

When the test cases are executed, they add the given facts (“Asia belongs to Planet Earth“, “China belongs to Asia”, “Great Wall of China belongs to China”).

After that, the facts are processed with the rules described in BackwardChaining.drl, which provides a recursive query belongsTo(String x, String y).

This query is invoked by the rules which use backward chaining to find if the hypothesis (“Great Wall of China BELONGS TO Planet Earth”), is true or false.

6. Conclusion

We’ve shown an overview of Backward Chaining, a feature of Drools used to retrieve a list of facts to validate if a decision is true.

As always, the full example can be found in our GitHub repository.

Monitor and troubleshoot Java applications and services with Datadog: 

>> Try it free!