/////////////////////////////////   HYPERGRAPH NODE
 // /////////////////////////////////////////////////
 private ISkolemPart generateHyperGraphSkolemFunction(
     SkolemFunctionGenerator generator, MappingTask mappingTask) {
   // initialize data structures
   Map<SetAlias, List<GeneratorWithPath>> generatorsByAlias =
       new HashMap<SetAlias, List<GeneratorWithPath>>();
   Map<SetAlias, ISkolemPart> partsByAlias = new HashMap<SetAlias, ISkolemPart>();
   Map<VariableJoinCondition, ISkolemPart> partsForJoins =
       new HashMap<VariableJoinCondition, ISkolemPart>();
   initializeDataStructures(
       generator, generatorsByAlias, partsByAlias, partsForJoins, mappingTask);
   // generate tuple strings
   ISkolemPart partForTuples = generatePartForTuples(partsByAlias, mappingTask);
   ISkolemPart partForJoins = generatePartForJoins(generator, partsForJoins, mappingTask);
   ISkolemPart partForVariable = generatePartForVariable(generator, partsForJoins, mappingTask);
   ISkolemPart result = new AppendSkolemPart();
   result.addChild(new StringSkolemPart("SK("));
   result.addChild(new StringSkolemPart("Tuples="));
   result.addChild(partForTuples);
   result.addChild(new StringSkolemPart("**Joins="));
   result.addChild(partForJoins);
   if (generator.getTgd().getTargetView().getAllJoinConditions().size() > 1) {
     result.addChild(new StringSkolemPart("**Var="));
     result.addChild(partForVariable);
   }
   if (generator.getPosition() != null) {
     result.addChild(new StringSkolemPart("**Pos=" + generator.getPosition()));
   }
   result.addChild(new StringSkolemPart(")"));
   return result;
 }
 /////////////////////////////////   LOCAL NODE   /////////////////////////////////////////////////
 private ISkolemPart generateLocalSkolemFunction(
     SkolemFunctionGenerator generator, MappingTask mappingTask) {
   StringBuilder functionName = new StringBuilder();
   functionName.append("SK_");
   functionName.append("TGD").append(compactHashCode(generator.getTgd().hashCode())).append("_");
   functionName
       .append("N")
       .append(compactHashCode(generator.getJoinConditions().toString().hashCode()));
   if (generator.getPosition() != null) {
     functionName.append("_Pos=").append(generator.getPosition());
   }
   return generateAppendWithFunctionName(functionName.toString(), generator, mappingTask);
 }
 private String findGeneratorForPath(
     VariablePathExpression setPath, FORule rule, MappingTask mappingTask) {
   List<FormulaVariable> universalVariables = rule.getUniversalFormulaVariables(mappingTask);
   TGDGeneratorsMap generatorsMap = rule.getGenerators(mappingTask);
   IValueGenerator generator = generatorsMap.getGeneratorForSetPath(setPath);
   if (generator == null) {
     return "SK_" + setPath.toString() + "()";
   }
   if (generator instanceof NullValueGenerator) {
     return NullValueGenerator.getInstance().toString();
   }
   SkolemFunctionGenerator skolemGenerator = (SkolemFunctionGenerator) generator;
   return skolemGenerator.toStringWithVariableArguments(universalVariables);
 }
 /////////////////////////////////   KEY NODE   /////////////////////////////////////////////////
 private ISkolemPart generateSkolemFunctionForKey(
     SkolemFunctionGenerator generator, MappingTask mappingTask) {
   StringBuilder functionName = new StringBuilder();
   functionName.append("SK_");
   //
   // functionName.append("TGD_").append(compactHashCode(generator.getTgd().hashCode())).append("_");
   functionName
       .append("KEY_")
       .append(compactHashCode(generator.getFunctionalDependencies().get(0).hashCode()));
   if (generator.getPosition() != null) {
     functionName.append("_Pos=").append(generator.getPosition());
   }
   return generateAppendWithFunctionName(functionName.toString(), generator, mappingTask);
 }
 //////////////////////////// third part: variable part
 private ISkolemPart generatePartForVariable(
     SkolemFunctionGenerator generator,
     Map<VariableJoinCondition, ISkolemPart> partsForJoins,
     MappingTask mappingTask) {
   if (generator.getJoinConditions().isEmpty()) {
     return NullSkolemPart.getInstance();
   }
   ISkolemPart append =
       new AppendSkolemPart(mappingTask.getConfig().useSortInSkolems(), "", "", ", ");
   for (VariableJoinCondition variableJoinCondition : generator.getJoinConditions()) {
     append.addChild(partsForJoins.get(variableJoinCondition));
   }
   return append;
 }
 /////////////////////////////////   INTERMEDIATE NODE
 // /////////////////////////////////////////////////
 private ISkolemPart generateSkolemFunctionForIntermediateNode(
     SkolemFunctionGenerator generator, MappingTask mappingTask) {
   StringBuilder functionName = new StringBuilder();
   functionName.append("SK_");
   functionName.append(SpicyEngineUtility.removeRootLabel(generator.getName()));
   return generateAppendWithFunctionName(functionName.toString(), generator, mappingTask);
 }
 private String findGeneratorForVariable(
     FormulaVariable variable, FORule rule, MappingTask mappingTask) {
   List<FormulaVariable> universalVariables =
       rule.getUniversalFormulaVariablesInTarget(mappingTask);
   TGDGeneratorsMap generatorsMap = rule.getGenerators(mappingTask);
   for (VariablePathExpression targetPath : variable.getTargetOccurrencePaths()) {
     IValueGenerator generator =
         generatorsMap.getGeneratorForLeaf(
             targetPath, mappingTask.getTargetProxy().getIntermediateSchema());
     if (generator != null && generator instanceof SkolemFunctionGenerator) {
       SkolemFunctionGenerator skolemGenerator = (SkolemFunctionGenerator) generator;
       return skolemGenerator.toStringWithVariableArguments(universalVariables);
     }
   }
   return NullValueGenerator.getInstance().toString();
   // throw new IllegalArgumentException("Unable to find generator for variable: " +
   // variable.toLongString() + "\nin rule: " + rule + "\n" +
   // SpicyEngineUtility.printVariableList(rule.getExistentialFormulaVariables(mappingTask)) +
   // "\nGenerators: " + generatorsMap);
 }
 public ISkolemPart generateSkolemFunction(
     SkolemFunctionGenerator generator, MappingTask mappingTask) {
   if (generator.isLeafGenerator()) {
     if (generator.getType() == SkolemFunctionGenerator.STANDARD) {
       if (mappingTask.getConfig().useLocalSkolem()) {
         return generateLocalSkolemFunction(generator, mappingTask);
       } else {
         return generateHyperGraphSkolemFunction(generator, mappingTask);
       }
     } else if (generator.getType() == SkolemFunctionGenerator.KEY) {
       return generateSkolemFunctionForKey(generator, mappingTask);
     } else if (generator.getType() == SkolemFunctionGenerator.EGD_BASED) {
       return generateEGDSkolemFunction(generator, mappingTask);
     }
     throw new IllegalArgumentException(
         "Incorrect type for leaf generator: " + generator + " - Type: " + generator.getType());
   } else {
     return generateSkolemFunctionForIntermediateNode(generator, mappingTask);
   }
 }
 private String generateEGDFunctionName(
     SkolemFunctionGenerator generator, MappingTask mappingTask) {
   StringBuilder result = new StringBuilder();
   List<String> fds = new ArrayList<String>();
   for (VariableFunctionalDependency functionalDependency :
       generator.getFunctionalDependencies()) {
     fds.add("-" + generateId(functionalDependency));
   }
   Collections.sort(fds);
   for (int i = 0; i < fds.size(); i++) {
     result.append(fds.get(i));
   }
   return "SK_EGDs" + compactHashCode(result.toString().hashCode());
 }
 private Map<SetAlias, List<GeneratorWithPath>> groupGeneratorsByAlias(
     SkolemFunctionGenerator skolemFunction) {
   Map<SetAlias, List<GeneratorWithPath>> groups =
       new HashMap<SetAlias, List<GeneratorWithPath>>();
   for (GeneratorWithPath subGenerator : skolemFunction.getSubGenerators()) {
     SetAlias generatorVariable = subGenerator.getTargetPath().getStartingVariable();
     List<GeneratorWithPath> variableGroup = groups.get(generatorVariable);
     if (variableGroup == null) {
       variableGroup = new ArrayList<GeneratorWithPath>();
       groups.put(generatorVariable, variableGroup);
     }
     variableGroup.add(subGenerator);
   }
   return groups;
 }
 //////////////////////////// step 1.a: initialize data structures
 private void initializeDataStructures(
     SkolemFunctionGenerator generator,
     Map<SetAlias, List<GeneratorWithPath>> generatorsByAlias,
     Map<SetAlias, ISkolemPart> partsByAlias,
     Map<VariableJoinCondition, ISkolemPart> partsForJoin,
     MappingTask mappingTask) {
   generatorsByAlias = groupGeneratorsByAlias(generator);
   for (SetAlias variable : generatorsByAlias.keySet()) {
     List<GeneratorWithPath> generatorGroup = generatorsByAlias.get(variable);
     partsByAlias.put(variable, generatePartForAlias(variable, generatorGroup, mappingTask));
   }
   generatePartsForJoins(
       generator.getTgd().getTargetView().getAllJoinConditions(),
       partsForJoin,
       partsByAlias,
       mappingTask);
 }
 private ISkolemPart generateAppendsForSubGenerator(
     SkolemFunctionGenerator generator, MappingTask mappingTask) {
   ISkolemPart append =
       new AppendSkolemPart(mappingTask.getConfig().useSortInSkolems(), "(", ")", ", ");
   for (GeneratorWithPath subGeneratorWithPath : generator.getSubGenerators()) {
     VariablePathExpression subGeneratorPath = subGeneratorWithPath.getTargetPath();
     IValueGenerator subGenerator = subGeneratorWithPath.getGenerator();
     ISkolemPart appendForGenerator = new AppendSkolemPart(false, "", "", ": ");
     StringSkolemPart stringPart =
         new StringSkolemPart(
             SpicyEngineUtility.removeRootLabel(subGeneratorPath.getAbsolutePath()));
     SubGeneratorSkolemPart generatorPart = new SubGeneratorSkolemPart(subGenerator);
     appendForGenerator.addChild(stringPart);
     appendForGenerator.addChild(generatorPart);
     append.addChild(appendForGenerator);
   }
   return append;
 }
 //////////////////////////// second part: joins part
 private ISkolemPart generatePartForJoins(
     SkolemFunctionGenerator generator,
     Map<VariableJoinCondition, ISkolemPart> partsForJoins,
     MappingTask mappingTask) {
   List<VariableJoinCondition> joinConditions =
       generator.getTgd().getTargetView().getAllJoinConditions();
   if (joinConditions.isEmpty()) {
     return NullSkolemPart.getInstance();
   }
   List<VariableJoinCondition> sortedConditions =
       new ArrayList<VariableJoinCondition>(joinConditions);
   Collections.sort(sortedConditions);
   ISkolemPart append =
       new AppendSkolemPart(mappingTask.getConfig().useSortInSkolems(), "", "", ", ");
   for (VariableJoinCondition variableJoinCondition : sortedConditions) {
     ISkolemPart joinPart = partsForJoins.get(variableJoinCondition);
     append.addChild(joinPart);
   }
   return append;
 }