Почему это сложное состояние не работает?

Я пытаюсь обнаружить противоречивые периоды в расписании: если учитель преподает в Period (timeStart=1400,timeEnd=1500,dayOfWeek="Monday",class="c1")он не может учить Period(1305,1405,dayOfWeek="Monday",class="c2")потому что он должен быть в двух классах одновременно в течение некоторого промежутка времени (да, это исправлено).

Пример одного периода и конфликтуют ли другие периоды:

          ---------                left_period (timeStart=1400,timeEnd=1500)

 ---------                        right_period (1300,1400) NO conflict
  ---------                       right_period (1305,1405) conflict
                   ---------      right_period (1500,1600) NO conflict
                 ---------        right_period (1555,1555) NO conflict

Поэтому я попытался обнаружить такие периоды на основе timeStart а также timeEnd ценности и утверждение таких конфликтов, как PeriodTimeConflict(left_period,right_period),

rule "insertPeriodTimeConflict"
    when
    $day_of_week : DayOfWeek()
    $left_period : Period(  $lp_id : id,
                dayOfWeek==$day_of_week,
                $lp_time_start : timeStart,
                $lp_time_end : timeEnd
                )
    $right_period : Period( id > $lp_id,
                dayOfWeek==$day_of_week,
                (   (timeStart>=$lp_time_start && timeStart<$lp_time_end)||
                    (timeEnd>$lp_time_start && timeEnd<=$lp_time_end)
                    )
                )
    then
    insertLogical(new PeriodTimeConflict($left_period,$right_period));
end

Тем не менее, ни один конфликт не обнаружен, и Drools об этом молчит. Что не так с моим правилом?

1 ответ

Откройте для себя радость временных операторов Fusion. Ваш случай - прекрасный пример для их использования.

Во-первых, вам нужно определить duration член на вашем Period учебный класс. Ваш конструктор может рассчитать продолжительность от времени начала и окончания, например,

private final int duration;
// ... other fields

public Period(int id, DayOfWeek dayOfWeek, Date timeStart, Date timeEnd) {
  // ... set other fields
  duration = timeEnd.getTime() - timeStart.getTime();
}

Теперь объявляю Period как событие в вашем ДХО:

declare Period
  @role(event)
  @timestamp(startTime)
  @duration(duration)
end

Тогда ваше правило может легко определить, перекрываются ли два периода:

rule "detect-overlap"
  when
    $left_period : Period( )
    $right_period : Period( this overlappedby $left_period )
  then
    ...
end
Другие вопросы по тегам