八字命理应用drools规则引擎

调研规则引擎用于八字命理中介绍了easyrules,easyrules比较轻量,但实际使用规则引擎,还是drools更能胜任复杂的业务。因为决策表可以让这个逻辑更加优雅
为什么一定要研究规则引擎,因为边缘计算中规则引擎是一个技术趋势,但是drools在边缘中运行就有些重了。当你看了很多命理书的时候,感觉还是用规则引擎来做,比使用java设计模式要强的多。
我的目的是八字命理,并不想把kie-spring再来一遍,于是就使用到fast-drools-spring-boot-starter这个插件

<properties>
        <version.fast-drools>8.0.7</version.fast-drools>
        <version.lombok>1.16.14</version.lombok>
        <version.spring-cloud>2.0.1.RELEASE</version.spring-cloud>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>

        <dependency>
            <groupId>com.github.hongwen1993</groupId>
            <artifactId>fast-drools-spring-boot-starter</artifactId>
            <version>${version.fast-drools}</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${version.lombok}</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-context</artifactId>
            <version>${version.spring-cloud}</version>
        </dependency>
    </dependencies>

1 决策表
1

出现下面的错误是因为dto这个对象没有解析到,这里主要dto的位置要填写那个格,按照上图说明

2021-02-27 16:53:56.160 ERROR 1824 --- [pool-1-thread-1] com.drools.core.KieTemplate              : file not fount.
2021-02-27 16:53:56.478  WARN 1824 --- [           main] o.d.c.kie.builder.impl.KieBuilderImpl    : File 'file0.drl' is in folder '' but declares package 'com.dzmsoft.qingqiu'. It is advised to have a correspondance between package and folder names.
2021-02-27 16:53:57.269 ERROR 1824 --- [           main] o.d.c.kie.builder.impl.KieProject        : Unable to build KieBaseModel:defaultKieBase
Predicate 'dto.setResult("旺")' must be a Boolean expression

编译出了错误,这个时候就可以参照Drools决策表的使用将决策表转化为drl查看发生了什么

import org.drools.decisiontable.InputType;
import org.drools.decisiontable.SpreadsheetCompiler;

@Test
    public void test02() throws FileNotFoundException {
        File file = new File("F:\\bazi_rules\\shy.xlsx");
        InputStream is = new FileInputStream(file);
        SpreadsheetCompiler compiler = new SpreadsheetCompiler();
        String drl = compiler.compile(is, InputType.XLS);
        System.out.println(drl);
    }

下面有两个地方有异常,
dto.setResult(旺)说明ACTION应该写成dto.setResult("$1");,加上引号
② when条件不正确,故提示then这个错误。第二个condition没有解析,解决方案是引用同一个对象的condition合并为一个单位格,赋值dto:ShyGenYinDto

package com.dzmsoft.qingqiu.rule;
//generated from Decision Table
import com.dzmsoft.qingqiu.rule.dto.ShyGenYinDto;
import java.lang.Integer;
import java.lang.String;
// rule values at B8, header at B3
rule "根根在年支、月支"
	when
		dto:ShyGenYinDto(yz == "助")
		mz
	then
		dto.setResult();
end

// rule values at B9, header at B3
rule "根印在年支、月支"
	when
		dto:ShyGenYinDto(yz == "助")
		mz
	then
		dto.setResult();

2021-02-27 17:10:09.325 ERROR 8744 --- [pool-1-thread-1] com.drools.core.KieTemplate              : file not fount.
2021-02-27 17:10:09.634  WARN 8744 --- [           main] o.d.c.kie.builder.impl.KieBuilderImpl    : File 'file0.drl' is in folder '' but declares package 'com.dzmsoft.qingqiu'. It is advised to have a correspondance between package and folder names.
2021-02-27 17:10:09.729 ERROR 8744 --- [           main] o.d.c.kie.builder.impl.KieProject        : Unable to build KieBaseModel:defaultKieBase
[11,1]: [ERR 102] Line 11:1 mismatched input 'then' in rule "根根在年支、月支"

正确的决策表生成规则是这样的了

rule "根根在年支、月支"
	when
		dto:ShyGenYinDto(yz == "助", mz == "助")
	then
		dto.setResult("旺");
end

可以看到决策表中如果出现tgbqcn>=Integer.valueOf($1) and tgbqcn<=Integer.valueOf($2),生成drl的时候就出现问题了,解决方案也比较简单,采用tgbqcn>=Integer.valueOf($1) , tgbqcn<=Integer.valueOf($2),用逗号代替and就可以了

rule "月支根,年支、日支克月支,根本气透干2个以上"
	when
		dto:ShyGenYinDto(yz == "克", mz == "助", dz == "克", bqtg == "是", tgbqcn>=Integer.valueOf(2) and tgbqcn<=Integer.valueOf(3))
	then
		dto.setResult("弱");
end

这里再思考一个问题,决策表的规则那么多,它们之间怎么样保证互斥关系的呢?就好比我的实验,发现实施效果并不理想。
1
为防止冲突,增加了两个配置ACTIVATION-GROUP对规则进行分组和Sequential设置为顺序执行,设置好后,发现还是不行
将决策表生成的规则,写入到drl文件中,进行调试。
原则上根根在年支、时支,天干不是印比一片(包括合化)的salience要高于年支根,月支泄根一次,本气透干为什么,匹配到后者呢?
activation-group设置的一组规则,只需要一个执行,其他的就不执行了,相当于组内的规则是互斥的。那么只要年支根,月支泄根一次,本气透干activation-group为2,同一个规则,就可以匹配到正确的了。
但是不同activation-group之间的呢?并不影响。
agenda-group是同一组的规则都会执行。

package com.dzmsoft.qingqiu.rules;
//generated from Decision Table
import com.dzmsoft.qingqiu.rules.dto.ShyGenYinDto;
import java.lang.Integer;
// rules values at B90, header at B4
rule "根根在年支、时支,天干印比一片"
	salience 65454
	activation-group "2"
	when
		dto:ShyGenYinDto(yz == "助", hz == "助", tgybyp == "1")
	then
		dto.setResult("旺");
		dto.setDesc("根根在年支、时支,天干印比一片");
end

// rules values at B91, header at B4
rule "根根在年支、时支,天干合化印比一片"
	salience 65453
	activation-group "2"
	when
		dto:ShyGenYinDto(yz == "助", hz == "助", tghhybyp == "1")
	then
		dto.setResult("旺");
		dto.setDesc("根根在年支、时支,天干合化印比一片");
end

// rules values at B92, header at B4
rule "根根在年支、时支,天干不是印比一片(包括合化)"
	salience 65452
	activation-group "2"
	when
		dto:ShyGenYinDto(yz == "助", hz == "助", tghhybyp == "0", tgybyp == "0")
	then
		dto.setResult("弱");
		dto.setDesc("根根在年支、时支,天干不是印比一片(包括合化)");
end

rule "年支根,月支泄根一次,本气透干"
	salience 65439
	activation-group "4"
	when
		dto:ShyGenYinDto(yz == "助", mz == "泄", bqtg == "1")
	then
		dto.setResult("弱");
		dto.setDesc("年支根,月支泄根一次,本气透干");
end

// rule values at B106, header at B4
rule "年支根,月支泄根一次,合化本气透干"
	salience 65438
	activation-group "4"
	when
		dto:ShyGenYinDto(yz == "助", mz == "泄", hhbqtg == "1")
	then
		dto.setResult("弱");
		dto.setDesc("年支根,月支泄根一次,合化本气透干");
end

解决规则冲突,另外的办法,就是就规则设置更加清晰,问题也就能解决。比如把某些规则的值设置的更加清晰一些
1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

warrah

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值