1. 概述
规则引擎在我们进行业务开发过程中使用非常广泛,比如常见的营销活动的策略定义、金融业务里面的风险评估、征信验证都会使用到规则引擎的能力。在本文里面我们将介绍如何使用 Java 里面最常用的 Drools 规则引擎进行反向推理。
2. 正向推理
正向推理是指我们从数据输入开始,得出一个特定的结论。比如使用正向推理可以根据节点之间已知的连接,发现新的路由。
3. 反向推理
与正向推理相反,反向推理是直接从结论(假设)开始,通过回溯一系列事实来验证结论是否正确。
在比较正向推理和反向推理时,正向推理可以理解成 数据驱动
(数据作为输入),而反向推理可以理解成 事件(或目标)驱动
(目标作为输入)。
比如使用反向推理可以验证是否存在连接两个节点的路由。
4. Drools Maven 依赖
首先要导入 drools-core Maven 依赖 :
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>7.4.1.Final</version>
</dependency>
5. 使用 Drools 进行反向推理示例
Drools 项目一开始是作为正向推理系统创建的。但是,从 5.2.0 版本开始,它也开始支持反向推理。
我们创建一个简单的应用程序并尝试验证一个简单的假设:如果中国的长城是在地球上。
5.1 事实数据准备
首先需要创建一个简单的事实列表来描述事物及其位置:
1. Planet Earth
2. Asia, Planet Earth
3. China, Asia
4. Great Wall of China, China
5.2 定义规则
我们首先创建一个名为 BackwardChaining.drl 的 .drl
文件,利用反向推理的 belongsTo 查询可以写成如下形式:
query belongsTo(String x, String y)
Fact(x, y;)
or
(Fact(z, y;) and belongsTo(x, z;))
end
此外,我们需要添加两条规则,以便可以查看我们的结果:
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;
// ...
}
在这里,我们使用 @Position 注解告诉 Drools 这些属性提供值的顺序。
此外,我们还将创建表示结果的类:
public class Result {
private String value;
private List<String> facts = new ArrayList<>();
...
}
最后我们就可以运行示例:
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
, China belongs to Asia
, Great Wall of China belongs to China
).
然后会使用 BackwardChaining.drl 中描述的规则处理事实,提供递归查询 belongsTo(String x, String y).
该查询使用反向推理进行规则调用,从而判断假设(Great Wall of China BELONGS TO Planet Earth
)是真还是假。
6. 小结
本文展示了一个使用 Drools 进行反向推理的示例,通过检索事实列表验证结论/假设是否正确。完整的代码示例可以在我的 GitHub 仓库 中找到。
共同学习,写下你的评论
评论加载中...
作者其他优质文章