до или после в окне переменной?

Я пытаюсь разработать систему правил, в которой сами правила могут быть настроены извне, используя объект конфигурации правил. В частности, я хочу внешне настроить определение правила 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, используя что-то вроде:

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

Как я могу сделать это с настраиваемым временным окном, используя свойство $r.triggerEvery в качестве количества секунд?


person Joeri Sebrechts    schedule 28.12.2017    source источник
comment
Временные операторы, т. е. before, after и т. д., являются просто синтаксическим сахаром для определенных условий, включающих метки времени событий, на которые ссылается временное выражение. (Определения операторов вы найдете в руководстве по Drools.) Написание функции DRL статического метода, которая вычисляет то же самое отношение, но включает параметры, поступающие из третьего факта, не должно быть слишком сложным. Возможно, вам потребуется указать временную метку в качестве поля события, установленного кодом Java при вставке события.   -  person laune    schedule 28.12.2017


Ответы (1)


Отвечая на мой собственный вопрос, основанный на совете laune.

Поведение ключевого слова before описано в руководстве как:

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

Предыдущий шаблон будет совпадать тогда и только тогда, когда временное расстояние между временем завершения $eventA и временем начала $eventB составляет от (3 минуты и 30 секунд) до (4 минуты). Другими словами:

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

Поиск исходный код оценщика перед мы можем видеть то же самое.

 @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
person Joeri Sebrechts    schedule 29.12.2017