/**
  * Check assignments of the given exams
  *
  * @param first assignment of the first exam
  * @param second assignment of the second exam
  * @return true, if the constraint is satisfied
  */
 public boolean check(ExamPlacement first, ExamPlacement second) {
   switch (getType()) {
     case sDistPrecedence:
       return first.getPeriod().getIndex() < second.getPeriod().getIndex();
     case sDistPrecedenceRev:
       return first.getPeriod().getIndex() > second.getPeriod().getIndex();
     case sDistSamePeriod:
       return first.getPeriod().getIndex() == second.getPeriod().getIndex();
     case sDistDifferentPeriod:
       return first.getPeriod().getIndex() != second.getPeriod().getIndex();
     case sDistSameRoom:
       return first.getRoomPlacements().containsAll(second.getRoomPlacements())
           || second.getRoomPlacements().containsAll(first.getRoomPlacements());
     case sDistDifferentRoom:
       for (Iterator<ExamRoomPlacement> i = first.getRoomPlacements().iterator(); i.hasNext(); )
         if (second.getRoomPlacements().contains(i.next())) return false;
       return true;
     default:
       return false;
   }
 }
 /**
  * Return true if this is hard constraint or this is a soft constraint without any violation
  *
  * @param p exam assignment to be made
  */
 public boolean isSatisfied(ExamPlacement p) {
   if (isHard()) return true;
   switch (getType()) {
     case sDistPrecedence:
       ExamPeriod last = null;
       for (Exam exam : variables()) {
         ExamPlacement placement =
             (p != null && exam.equals(p.variable()) ? p : exam.getAssignment());
         if (placement == null) continue;
         if (last == null || last.getIndex() < placement.getPeriod().getIndex())
           last = placement.getPeriod();
         else return false;
       }
       return true;
     case sDistPrecedenceRev:
       last = null;
       for (Exam exam : variables()) {
         ExamPlacement placement =
             (p != null && exam.equals(p.variable()) ? p : exam.getAssignment());
         if (placement == null) continue;
         if (last == null || last.getIndex() > placement.getPeriod().getIndex())
           last = placement.getPeriod();
         else return false;
       }
       return true;
     case sDistSamePeriod:
       ExamPeriod period = null;
       for (Exam exam : variables()) {
         ExamPlacement placement =
             (p != null && exam.equals(p.variable()) ? p : exam.getAssignment());
         if (placement == null) continue;
         if (period == null) period = placement.getPeriod();
         else if (period.getIndex() != placement.getPeriod().getIndex()) return false;
       }
       return true;
     case sDistDifferentPeriod:
       HashSet<ExamPeriod> periods = new HashSet<ExamPeriod>();
       for (Exam exam : variables()) {
         ExamPlacement placement =
             (p != null && exam.equals(p.variable()) ? p : exam.getAssignment());
         if (placement == null) continue;
         if (!periods.add(placement.getPeriod())) return false;
       }
       return true;
     case sDistSameRoom:
       Set<ExamRoomPlacement> rooms = null;
       for (Exam exam : variables()) {
         ExamPlacement placement =
             (p != null && exam.equals(p.variable()) ? p : exam.getAssignment());
         if (placement == null) continue;
         if (rooms == null) rooms = placement.getRoomPlacements();
         else if (!rooms.containsAll(placement.getRoomPlacements())
             || !placement.getRoomPlacements().containsAll(rooms)) return false;
       }
       return true;
     case sDistDifferentRoom:
       HashSet<ExamRoomPlacement> allRooms = new HashSet<ExamRoomPlacement>();
       for (Exam exam : variables()) {
         ExamPlacement placement =
             (p != null && exam.equals(p.variable()) ? p : exam.getAssignment());
         if (placement == null) continue;
         for (ExamRoomPlacement room : placement.getRoomPlacements()) {
           if (!allRooms.add(room)) return false;
         }
       }
       return true;
     default:
       return false;
   }
 }