在 Drools 中为一个组执行单个规则

Execution of a single rule for a group in Drools

我正在研究基于立法的专家系统,我有很多这样的规则:

规则 1: 如果扣押金额大于3000,扣押金额,理据法100

规则二:如果查封是家庭式的,查封金额,正当法则200

问题是动作"Seize"只能应用一次,但我需要保存满足规则的历史记录,我在下面举个例子

rule "law 100"

when 
  $seizure: Seizure(amount>3000)
then
  $seizure.getRules().add("Justification: law 100 of the civil that says bla bla");
  $seizure.applyPunishment();

rule "law 200"

when 
  $seizure: Seizure(type == TYPES.Family)
then
  $seizure.getRules().add("Justification: law 200 of the family code that says bla bla");
  $seizure.applyPunishment();

如上所示,我需要 "then" 部分保存描述规则“$seizure.getRules().add("Justification: law of the civil code");”。我还需要如果“$seizure.applyPunishment();”已在规则 1 中应用,将不会在规则 2 中重新应用。

感谢指教

这里有多种选择。

  1. applyPunishment为幂等。

    您没有显示 applyPunishment 的代码,但它可能看起来像

    private boolean alreadySeized = false;
    
    public void applyPunishment() {
        if (alreadySeized) {
            return;
        }
    
        alreadySeized = true;
    

    您也可以将其基于其他一些已经存在的变量。例如。 if (seizedAmount > 0) return;。但很难说如果没有代码,它会如何工作。

  2. 您可以将 applyPunishment 更改为类似 markForPunishment 的内容,这可能看起来像

    private boolean markedForPunishment;
    
    public void markForPunishment() {
        markedForPunishment = true;
    }
    

    然后添加一条规则,例如

    rule "Punish"
    
    when
      $seizure: Seizure(markedForPunishment  == true)
    then
      $seizure.applyPunishment();
    

    搭配得当getter。

    您的其他规则将调用 markForPunishment 而不是 applyPunishment

  3. 您可以使用 ruleflow 将理由与惩罚分开。

  4. 您可以 set a variable 在您的规则中使用的 then 子句中。

可能还有其他选择。要做出的重大决定是您想要 MVEL 解决方案还是 Java 解决方案。有几个选项需要更改两者。