在变量窗口之前或之后?

时间:2017-12-28 17:04:29

标签: drools drools-fusion

我正在尝试使用规则配置对象设计规则系统,其中规则本身可以在外部配置。具体来说,我想在DRL规则定义的外部配置特定类型规则的规则启动之间的最短时间。

到目前为止,我的方法是将规则配置作为事实ValueRuleSpec插入:

rule "Any value detected"
when
    $r : ValueRuleSpec(mode == ValueRuleSpecMode.ANY(), $devices: devices)
    $e : SensorEvent(deviceId memberOf $devices) from entry-point FMSensorEvents
    not Activation(ruleSpec == $r, cause == $e)
then
    insert(new Activation($r, $e));
end

$ r ValueRuleSpec对象具有属性 triggerEvery ,其中包含激活之间的最小秒数。我知道这可以通过在$ e之前使用以下内容测试是否缺少特定范围内的Activation对象来静态完成:

not Activation(this before[60s, 0s] $e)

如何使用$ r.triggerEvery属性作为秒数,在可配置的时间窗口中执行此操作?

1 个答案:

答案 0 :(得分:0)

根据laune的建议回答我自己的问题。

before关键字的行为为described in the manual

$eventA : EventA( this before[ 3m30s, 4m ] $eventB ) 
     

当且仅当时间距离时,先前的模式将匹配   在$ eventA完成的时间和$ eventB的时间之间   开始时间在(3分钟到30秒)和(4分钟)之间。在   换句话说:

3m30s <= $eventB.startTimestamp - $eventA.endTimeStamp <= 4m

查看source code for the before evaluator我们可以看到相同的内容。

 @Override
 protected boolean evaluate(long rightTS, long leftTS) {
     long dist = leftTS - rightTS;
     return this.getOperator().isNegated() ^ (dist >= this.initRange && dist <= this.finalRange);
 }

基于此,我相应地修改了我的代码,现在它似乎正常工作:

rule "Any value detected"
when
    $r : ValueRuleSpec(mode == ValueRuleSpecMode.ANY(), $devices: devices)
    $e : SensorEvent(deviceId memberOf $devices) from entry-point FMSensorEvents
    not Activation(ruleSpec == $r, cause == $e)
    // no activation within past triggerEvery seconds for same device
    not Activation(
        ruleSpec == $r, 
        deviceId == $e.deviceId, 
        start.time > ($e.start.time - ($r.triggerEvery * 1000))
    )
then
    insert(new Activation($r, $e));
end