Search code examples
droolsoptaplanner

Binding variables seemed to be recognized as methods incorrectly


drl:

rule "adjectFreePeriods"
    when
        $studentGroupAndEduClass : StudentGroupAndEduClass($eduClasses : eduClasses)
        not LectureOfEduClass(eduClass memberOf $eduClasses,
            $day : day, $timeslotIndex : timeslotIndex, period != null
        )
        not LectureOfEduClass(eduClass memberOf $eduClasses,
            $day == day, timeslotIndex == ($timeslotIndex + 1)
        )
    then
        scoreHolder.addSoftConstraintMatch(kcontext,- $studentGroupAndEduClass.getStudents().size());
end

java:

public class LectureOfEduClass{
    // ...
    //omitted others
    public Day getDay(){
        if(period == null){
            return null;
        }
        return period.getDay();
    }
    public int getTimeslotIndex() {
        if (period == null) {
            return Integer.MIN_VALUE;
        }
        return period.getTimeslot().getTimeslotIndex();
    }
}

Here are the exact error messages.

Unable to Analyse Expression $day == day:
[Error: unable to resolve method using strict-mode: domain.LectureOfEduClass.$day()]
[Near : {... $day == day ....}]
             ^
Unable to Analyse Expression timeslotIndex == ($timeslotIndex + 1):
[Error: unable to resolve method using strict-mode: domain.LectureOfEduClass.$timeslotIndex()]
[Near : {... timeslotIndex == ($timeslotIndex + 1) ....}]
                               ^ 

According to error messages shown, it seemed that the engine took those two binding variables as methods of POJOs incorrectly. What's wrong with those code snippets? How can I fix that?


Solution

  • The problem is that you are binding $day inside a not pattern. All the variables inside a not (or exists) patterns are local to the pattern for obvious reasons. I think that what you are trying to do is something like this:

    rule "adjectFreePeriods"
    when
      $studentGroupAndEduClass : StudentGroupAndEduClass($eduClasses : eduClasses)
      not (
        LectureOfEduClass(
          eduClass memberOf $eduClasses,
          $day : day, 
          $timeslotIndex : timeslotIndex, period != null
        ) and
        LectureOfEduClass(
          eduClass memberOf $eduClasses,
          $day == day, 
          timeslotIndex == ($timeslotIndex + 1)
        )
      )
    then
      scoreHolder.addSoftConstraintMatch(kcontext,- $studentGroupAndEduClass.getStudents().size());
    end
    

    Hope it helps,