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>9.44.0.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:
- Planet Earth
- Asia, Planet Earth
- China, Asia
- 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.