Reputation: 23088
I am trying to detect conflicting periods in a timetable: if a teacher teaches in a Period (timeStart=1400,timeEnd=1500,dayOfWeek="Monday",class="c1")
, he cannot teach Period(1305,1405,dayOfWeek="Monday",class="c2")
, because he will have to be at two classes at once for a time interval (yes, it's constrived).
An example of one period and whether other periods conflict:
--------- 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
So I tried detecting such periods based on timeStart
and timeEnd
values and asserting such conflicts as 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
However, not even a single conflict is ever detected and Drools is silent on this matter. What is wrong with my rule?
Upvotes: 0
Views: 250
Reputation: 634
Discover the joy of the Fusion temporal operators. Your case is a perfect example for their use.
First, you need to define a duration
member on your Period
class. Your constructor can calculate the duration from the start and end time, e.g.
private final int duration;
// ... other fields
public Period(int id, DayOfWeek dayOfWeek, Date timeStart, Date timeEnd) {
// ... set other fields
duration = timeEnd.getTime() - timeStart.getTime();
}
Now declare Period
as an event in your DRL:
declare Period
@role(event)
@timestamp(startTime)
@duration(duration)
end
Then your rule can easily determine whether two periods overlap:
rule "detect-overlap"
when
$left_period : Period( )
$right_period : Period( this overlappedby $left_period )
then
...
end
Upvotes: 1