具有嵌套成员的DROOLS局部变量赋值

时间:2015-09-30 17:08:50

标签: drools

我无法在DROOLS 6.2和Optaplanner中使用两个Java类为嵌套成员/对象分配局部变量。我试图确定两个事实/实例嵌套成员何时具有相同的值。下面的测试用例很简单,实际上我试图在规则中比较多个嵌套成员。

public class A {
  private B x;
  //public B getX(), public void setX(B b) follow ...
}

public class B {
  private int y;
  //public int getY(), public void setY(int y) follow ...
}

rule "testnestedmembers"
when  
    A(x.y : y, $x : x)
    A(x2.y == y, $x : x2) 
then 
    scoreHolder.addHardConstraintMatch(kcontext,-1000);

    Message [id=1, level=ERROR,      path=org/somebody/project/planner/solver/planScoreRules.drl, line=16, column=0
   text=[ERR 102] Line 16:49 mismatched input ':' in rule "testnestedmembers"]
    Message [id=2, level=ERROR, path=org/somebody/project/planner/solver/planScoreRules.drl, line=0, column=0 text=Parser returned a null Package]
    ---
    Warning Messages:
    ---
    Info Messages:

    at    org.optaplanner.core.config.score.director.ScoreDirectorFactoryConfig.buildKieBase(ScoreDirectorFactoryConfig.java:387)

我已经回顾了一些答案,例如: Drools Rule Expression : Access Nested class data member

Geoffrey De Smet的回答说明了有条件的,但不是本地的任务。 我尝试了不同的变化,但没有运气。谢谢你的任何建议。

编辑我应该说创建一个绑定而不是分配一个本地变量。

2 个答案:

答案 0 :(得分:0)

你的意思不是这样的:

when  
  $a1 : A($y1 : x.y)
  A(this != $a1, x.y == $y1) 
then
  ...

正如Geoffrey De Smet所说:

  

在DRL中,==表示等于,而不是相同。使用$varB : b,您可以执行B varB = a.getB();

之类的操作

答案 1 :(得分:0)

首先,我将指出导致编译器错误的原因。

rule "testnestedmembers"
when  
    A(x.y : y, $x : x)     // (1)
    A(x2.y == y, $x : x2)  // (2) (3)

(1)绑定的格式为<variable> : <field>,但x.y不是有效的变量名。 (2)与x2.y相同。此外,x2不是A中的字段。 (3)没有什么能阻止规则引擎将相同的事实与A类的两种模式相匹配。这意味着该规则将触发A类的每一个事实,因为(因为你的意图)Axy总是等于它自己。 / p>

正确

rule "testnestedmembers"
when
    $a1: A( $x1: x )
    A( this != $a1, $x2: x, $x1.getY() == $x2.getY() )
then
     ...

然而!此规则触发两次,一次绑定到$ a1的一个事实,一次绑定到$ a1的另一个(匹配)。一种可能性是测试这样一对(或群集)的存在

rule "testnestedmembers"
when
    $a1: A( $x1: x )
    exists A( this != $a1, $x2: x, $x1.getY() == $x2.getY() )
then
     ...

另一种选择是通过测试属性来确保排序:

rule "testnestedmembers"
when
    $a1: A( $x1: x, $id: id )
    exists A( id > $id, $x2: x, $x1.getY() == $x2.getY() )
then

现在这会激发每一对A,其中第二对有更大的(唯一!)id。