如何对多个对象使用 drools traits

How to use drools traits for multiple objects

如果我向 drools 引擎添加一个事实,我有一组 Drools 规则可以正常工作,如果我添加两个事实,则规则仅适用于第一个事实。我怎样才能使规则集适用于多个事实?

我的特点:

@Traitable
public class Policy {

    private String postalCode;
    private String houseHold;
    private BigDecimal grossPremium;

    public Policy(String postalCode, String houseHold) {
        this.postalCode = postalCode;
        this.houseHold = houseHold;
    }
}

我的规则集:

import java.math.BigDecimal;

declare trait PolicyWithFactors
    policy : Policy
    postalCodeFactor : Double
    houseHoldFactor : Double
end

rule rule1
when
    $f : PolicyWithFactors(policy.postalCode == "1000", postalCodeFactor == null)
then
    System.out.println("Running rule1 for " + $f.getPolicy().getHouseHold() + " and " + $f.getPolicy().getPostalCode());
    modify($f) { setPostalCodeFactor(20.0); }
end

rule rule2
when
    $p : Policy()
    not PolicyWithFactors()
then
    System.out.println("Running rule2 for " + $p.getHouseHold() + " and " + $p.getPostalCode());
    PolicyWithFactors $pwf = don($p, PolicyWithFactors.class);
    modify ($pwf) { setPolicy($p); }
end

rule rule3
when
    $p : Policy(houseHold == "single")
    $f : PolicyWithFactors(houseHoldFactor == null)
then
    System.out.println("Running rule3 for " + $p.getHouseHold() + " and " + $p.getPostalCode());
    modify($f) { setHouseHoldFactor(10.0); }
end

rule rule4
when
    $p : Policy(grossPremium == null)
    $f : PolicyWithFactors(policy == $p, $pcf : postalCodeFactor != null, $hhf : houseHoldFactor != null)
then
    System.out.println("Running rule4 for " + $pcf + " and " + $hhf);
    BigDecimal $gp = new BigDecimal($pcf * $hhf);
    modify($p) { setGrossPremium($gp); }
end

rule rule5
when
    $p : Policy(houseHold == "family")
    $f : PolicyWithFactors(houseHoldFactor == null)
then
    System.out.println("Running rule5 for " + $p.getHouseHold() + " and " + $p.getPostalCode());
    modify($f) { setHouseHoldFactor(15.0); }
end

失败的测试用例:

public class RuleTest {

    @Test
    public void test() {
        KieServices kieServices = KieServices.Factory.get();
        KieContainer kieContainer = kieServices.getKieClasspathContainer();
        KieSession kieSession = kieContainer.newKieSession();
        Policy policy1 = new Policy("1000", "single");
        kieSession.insert(policy1);
        Policy policy2 = new Policy("1000", "family");
        kieSession.insert(policy2);
        kieSession.fireAllRules(50);
        assertThat(policy1.getGrossPremium(), is(new BigDecimal("200")));
        assertThat(policy2.getGrossPremium(), is(new BigDecimal("300")));
    }
}

罪魁祸首是规则 2。一旦工作内存中有 PolicyWithFactors,它就不会触发。

rule rule2
when
  $p : Policy()
  not PolicyWithFactors( policy == $p)
then ... end

我没有尝试理解其余所有内容,但请检查此约束是否应出现在所有后续规则中,即将匹配一个策略与一个 PolicyWithFactors。