根据另一条规则的条件,根据和否则流口水

时间:2018-02-22 19:01:27

标签: drools

我想运行一个调用Java方法的规则,并从另一个规则中传递事实(或者更确切地说,它的逻辑值),尽管我不知道java方法是否对这个问题非常重要。这不容易描述,所以我会尝试根据一个例子来展示它:

rule "Some rule determining fact"

    when
        ... //some conditions
    then
        insert(new SomeCondition(callSomeJavaMethodReturningBoolean()))
    end

rule "Some rule using SomeCondition"

    when
        SomeCondition($value: value)
        ... //some other conditions
    then
        insert(callJavaMethodUsingSomeCondition($value))
    end

这里的问题是第一条规则并不总是触发,因此SomeCondition并不总是被定义,第二条规则也不会被评估。

我的第二次尝试是创建两个单独的规则:

rule "Some rule determining fact"

    when
        ... //some conditions
    then
        insert(new SomeCondition(callSomeJavaMethodReturningBoolean()))
    end

rule "SomeConditionTrueRule"

    when
        SomeCondition(value == true)
        ... //some other conditions
    then
        insert(callJavaMethodUsingSomeCondition(true))
    end

rule "SomeConditionFalseRule"

    when
        not SomeCondition() or SomeCondition(value == false)
        ... //some other conditions
    then
        insert(callJavaMethodUsingSomeCondition(false))
    end

这也没有按预期工作,因为它甚至在评估我的第一条规则之前首先评估SomeConditionFalseRule。我会对如何解决这个问题提出任何建议。如果重要的话,使用的Drools版本是6.5.0。此外,我希望尽可能避免使用salience,因为我已经读过它是一种不好的做法(如果我错了,请纠正我)。

1 个答案:

答案 0 :(得分:1)

在这种情况下,您需要分离两组规则(插入SomeCondition个对象和执行java代码的规则)。

最简单的方法是在第二组使用较低的显着性:

rule "Some rule determining fact"
when
    ... //some conditions
then
    insert(new SomeCondition(callSomeJavaMethodReturningBoolean()))
end

rule "SomeConditionTrueRule"
salience -1
when
    SomeCondition(value == true)
    ... //some other conditions
then
    insert(callJavaMethodUsingSomeCondition(true))
end

rule "SomeConditionFalseRule"
salience -1
when
    not SomeCondition() or SomeCondition(value == false)
    ... //some other conditions
then
    insert(callJavaMethodUsingSomeCondition(false))
end

更强大的方法是使用2 agenda-groups并一个接一个地激活它们。

但我们的想法是,执行java代码的规则为规则确定了时间,以确定需要执行哪些操作才能做出最终决定。

如果我已经在上面提到过,只要您创建会话,就会激活(A1SomeConditionFalseRule,但在您致电之前不会执行激活fireAllRules()。如果您随后插入必要的事实以使SomeConditionTrueRule成立,那么您现在将获得激活(A2)。

此时,议程将如下所示:| A1 | A2 |

调用fireAllRules()时,Drools会选择具有更高显着性的议程中的激活(默认情况下,规则的salience为0)。在这种情况下,将挑选并执行A2

A2的执行会插入新的事实,使A1无效,并为A3创建新的激活(SomeConditionTrueRule)。 Drools将继续从议程中删除A1,因此不会执行规则SomeConditionFalseRule

A2执行后的议程将如下所示:| A3 |

希望它有所帮助,