为了账号安全,请及时绑定邮箱和手机立即绑定

一文带你了解如何使用 Drools 规则引擎进行反向推理

标签:
Java

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 仓库 中找到。


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消