private EquivalenceClassForSymmetricEGD createEquivalenceClass(Dependency egd) {
   FormulaVariable v1 =
       ((ComparisonAtom) egd.getConclusion().getAtoms().get(0)).getVariables().get(0);
   AttributeRef variableOccurrence = v1.getPremiseRelationalOccurrences().get(0).getAttributeRef();
   AttributeRef conclusionAttribute =
       EquivalenceClassUtility.correctAttributeForSymmetricEGDs(variableOccurrence, egd);
   List<BackwardAttribute> attributesForBackwardChasing = findAttributesForBackwardChasing(egd);
   return new EquivalenceClassForSymmetricEGD(
       egd, conclusionAttribute, attributesForBackwardChasing);
 }
 private List<BackwardAttribute> findAttributesForBackwardChasing(Dependency egd) {
   List<BackwardAttribute> attributesForBackwardChasing = new ArrayList<BackwardAttribute>();
   for (FormulaVariableOccurrence backwardAttributeOccurrence : egd.getBackwardAttributes()) {
     AttributeRef occurrenceAttribute =
         EquivalenceClassUtility.correctAttributeForSymmetricEGDs(
             backwardAttributeOccurrence.getAttributeRef(), egd);
     FormulaVariable variable =
         LunaticUtility.findPremiseVariableInDepedency(backwardAttributeOccurrence, egd);
     BackwardAttribute backwardAttribute = new BackwardAttribute(occurrenceAttribute, variable);
     if (attributesForBackwardChasing.contains(backwardAttribute)) {
       continue;
     }
     attributesForBackwardChasing.add(backwardAttribute);
   }
   return attributesForBackwardChasing;
 }
 private EquivalenceClassForSymmetricEGD readNextEquivalenceClass(
     ITupleIterator it,
     Dependency egd,
     IDatabase deltaDB,
     String stepId,
     IChaseState chaseState,
     Scenario scenario) {
   if (!it.hasNext() && (this.lastTupleHandled || this.lastTuple == null)) {
     return null;
   }
   EquivalenceClassForSymmetricEGD equivalenceClass = createEquivalenceClass(egd);
   if (lastTuple != null && !this.lastTupleHandled) {
     if (logger.isDebugEnabled())
       logger.debug("Reading tuple : " + this.lastTuple.toStringWithOIDAndAlias());
     addTuple(
         this.lastTuple,
         equivalenceClass,
         scenario.getCostManagerConfiguration(),
         deltaDB,
         stepId,
         scenario);
     this.lastTupleHandled = true;
   }
   if (logger.isDebugEnabled()) logger.debug("Reading next equivalence class...");
   while (it.hasNext()) {
     if (chaseState.isCancelled())
       ChaseUtility.stopChase(
           chaseState); // throw new ChaseException("Chase interrupted by user");
     Tuple tuple = it.next();
     if (logger.isDebugEnabled())
       logger.debug("Reading tuple : " + tuple.toStringWithOIDAndAlias());
     if (lastTuple == null
         || equivalenceClass.isEmpty()
         || EquivalenceClassUtility.sameEquivalenceClass(tuple, this.lastTuple, egd)) {
       addTuple(
           tuple,
           equivalenceClass,
           scenario.getCostManagerConfiguration(),
           deltaDB,
           stepId,
           scenario);
       this.lastTuple = tuple;
       this.lastTupleHandled = true;
     } else {
       if (logger.isDebugEnabled()) logger.debug("Equivalence class is finished...");
       if (equivalenceClass.isEmpty()) {
         throw new IllegalArgumentException(
             "Unable to create equivalence class for egd:\n"
                 + egd
                 + "\nLast tuple: \n"
                 + lastTuple
                 + "\nCurrent tuple: \n"
                 + tuple);
       }
       this.lastTuple = tuple;
       this.lastTupleHandled = false;
       break;
     }
   }
   if (logger.isDebugEnabled()) logger.debug("Equivalence class loaded");
   if (logger.isDebugEnabled())
     logger.debug("-------- Equivalence class:\n" + equivalenceClass + "\n---------------");
   return equivalenceClass;
 }