在变量 window 之前还是之后?

before or after within variable window?

我正在尝试设计一个规则系统,其中可以使用规则配置对象对规则本身进行外部配置。具体来说,我想在 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 属性 作为秒数,在可配置的时间 window 中执行此操作?

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

before 关键字的行为是 described in the manual 作为:

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

The previous pattern will match if and only if the temporal distance between the time when $eventA finished and the time when $eventB started is between ( 3 minutes and 30 seconds ) and ( 4 minutes ). In other words:

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