在规则LHS

时间:2016-11-17 05:41:01

标签: drools

如何将变量绑定到规则LHS中or组中匹配的不同类型的事实?

例如,如果我有以下规则文件:

package com.sample

rule "Rule1"
    when
         object1: ObjectType1( id == 1) or
         object2: ObjectType2( id == 2)
    then
        System.out.println(object1.getId());
        System.out.println(object2.getId());
end

我使用此驱动程序代码:

package com.sample;

import org.kie.api.runtime.KieSession;

public class DroolsTest {

  public static final void main(String[] args) {
    try {
      String ruleFilePath = "src/main/resources/rules/ruleFile.drl";
      KieSession kSession = KSessionUtil.buildKSession(ruleFilePath);

      ObjectType1 o1 = new ObjectType1(1);
      ObjectType2 o2 = new ObjectType2(2);

      kSession.insert(o1);
      kSession.insert(o2);

      kSession.fireAllRules();

      System.out.println("Bye");
    } catch (Throwable t) {
      t.printStackTrace();
    }
  }
}

ObjectType1.java

package com.sample;

public class ObjectType1 {
  public ObjectType1(int i) {
    super();
    this.id = i;
  }

  public int getId() {
    return id;
  }

  public void setId(int id) {
    this.id = id;
  }

  public int id;
}

ObjectType2.java

package com.sample;

public class ObjectType12 {
  public ObjectType2(int i) {
    super();
    this.id = i;
  }

  public int getId() {
    return id;
  }

  public void setId(int id) {
    this.id = id;
  }

  public int id;
}

我从Drools Eclipse插件中得到语法错误:

object1 cannot be resolved.
object2 cannot be resolved.

如果我将规则LHS中的or更改为and,则错误就会消失。

我正在使用Drools 6.2.0。

2 个答案:

答案 0 :(得分:3)

棘手的部分是Drools如何处理模式之间的or操作数。在您的示例中,Drools会将您的规则分解为两个独立的规则:

rule "Rule1_A"
when
     object1: ObjectType1( id == 1)
then
    System.out.println(object1.getId());
    System.out.println(object2.getId());
end


rule "Rule1_B"
when
     object2: ObjectType2( id == 2)
then
    System.out.println(object1.getId());
    System.out.println(object2.getId());
end

如您所见,错误现在变得更加明显。

Drools处理or的方式的副作用还在于此操作中没有短路:如果会话中存在两个对象,则规则将执行两次。

希望它有所帮助,

答案 1 :(得分:1)

this answer by Esteban中所述,不可能以这种方式绑定变量。

相反,我们可以做的是创建一个包装类,它将包含一个对象,每个不同的数据类型需要匹配:

ObjectType1

现在,如果我们想在知识会话中插入ObjectType1 object1 = new ObjectType1(); kSession.insert(object1); 的对象:

ObjectType.ob1

我们可以将object1设置为引用ObjectType,然后将新的ObjectType1 object1 = new ObjectType1(); ObjectType object = new ObjectType(); object.setOb1(object1); kSession.insert(object); 对象插入到会话中:

ObjectType1

现在在规则文件中,我们需要将ObjectType(getOb1() != null)类型的对象与ObjectType1()匹配,而不是rule "Rule1" when object: ( ObjectType( ob1 != null && ob1.getId() == 1 ) or ObjectType( ob2 != null && ob2.getId() == 2 ) ) then if ( object.getOb1() != null ) { System.out.println(object.getOb1().getId()); } else { System.out.println(object.getOb2().getId()); } end

.price__tooltip {
    transition: all 0.2s ease-in;
    opacity: 0;
    [...]
}
.price__text:hover {
      &+.price__tooltip{
        opacity: 1;
      }
}