Claudio Gomes преди 5 години
родител
ревизия
b1e7135d17
променени са 1 файла, в които са добавени 51 реда и са изтрити 50 реда
  1. 51 50
      HintCOEngine/src/ua/ansymo/hintco/CandidatesGenerator.xtend

+ 51 - 50
HintCOEngine/src/ua/ansymo/hintco/CandidatesGenerator.xtend

@@ -121,8 +121,6 @@ class CandidatesGenerator {
 		println()
 	}
 	
-	// TODO: Break this method into multiple methods: generation of constraints, propagation of constraints, etc...
-	// Leave the recursive calls here!
 	def private int recGenerateVariants(Deque<VariantDiagram> ns, 
 										HintConfiguration cs, 
 										ConstraintsStack constraints, int maxVariants, boolean optimizeAlgebraicLoops) {
@@ -138,8 +136,57 @@ class CandidatesGenerator {
 		val n = ns.peek() // Head of the queue is the current element being visited.
 		
 		try {
-			val alternative = n.alternative
-			switch alternative {
+			addConstraintsBasedOnAlternative(n.alternative, constraints, n, cs)
+			
+			// Check invariant on localConstraints
+			localConstraints.forEach[k, v|
+				Assert.isTrue(k.precedes.containsAll(v))
+			]
+			
+			if (n.children.empty){
+				// Base case
+				if (numGenVariants < maxVariants){
+					// Propagate precedence constraints from inner scenarios to their parents.
+					// If two nodes are indirectly (via a path in the children nodes) connected, then they should be connected directly.
+					// This will ensure that the topological sort can safely ignore child nodes.
+					propagateConstraints(n, ns, constraints, cs)
+					
+					val variantID = ns.map[n1 | n1.identifier].reduce[n1, n2| n2 + "_" + n1]
+					// mark alternatives as selected, so the processor knows which alternatives have been selected.
+					// Exclude root because it has no alternative
+					markSelected(ns, true)
+					processor.process(ns, variantID, constraints, cs)
+					markSelected(ns, false)
+					numGenVariants++				
+				}
+			} else {
+				// Recurse
+				for (c : n.children) {
+					if (numGenVariants < maxVariants && variantValidator.validVariant(c, n.children.filter[a | a!==c], ns)){
+						ns.push(c)
+						val childGenVariants = recGenerateVariants(ns, cs, constraints, maxVariants-numGenVariants, optimizeAlgebraicLoops)
+						numGenVariants = numGenVariants + childGenVariants
+						ns.pop()	
+					}
+				}
+			}
+		} catch (InfeasibleConstraintException e) {
+			// Do nothing.
+			logger.debug("The last added constraint is infeasible. Trying other alternatives.")
+		}
+		
+		// Revert changes in model
+		localConstraints.forEach[k, v| 
+			Assert.isTrue(k.precedes.removeAll(v))
+		]
+		constraints.pop()
+		
+		Assert.isTrue(callDepth == constraints.size)
+		return numGenVariants
+	}
+	
+	def addConstraintsBasedOnAlternative(Alternative alternative, ConstraintsStack constraints, VariantDiagram n, HintConfiguration cs) {
+		switch alternative {
 				RootCandidateScenario: {
 					/*
 					 * Recursively create I/O and DoStep constraints.
@@ -264,52 +311,6 @@ class CandidatesGenerator {
 						throw new UnsupportedOperationException()
 					}
 			}
-			
-			// Check invariant on localConstraints
-			localConstraints.forEach[k, v|
-				Assert.isTrue(k.precedes.containsAll(v))
-			]
-			
-			if (n.children.empty){
-				// Base case
-				if (numGenVariants < maxVariants){
-					// Propagate precedence constraints from inner scenarios to their parents.
-					// If two nodes are indirectly (via a path in the children nodes) connected, then they should be connected directly.
-					// This will ensure that the topological sort can safely ignore child nodes.
-					propagateConstraints(n, ns, constraints, cs)
-					
-					val variantID = ns.map[n1 | n1.identifier].reduce[n1, n2| n2 + "_" + n1]
-					// mark alternatives as selected, so the processor knows which alternatives have been selected.
-					// Exclude root because it has no alternative
-					markSelected(ns, true)
-					processor.process(ns, variantID, constraints, cs)
-					markSelected(ns, false)
-					numGenVariants++				
-				}
-			} else {
-				// Recurse
-				for (c : n.children) {
-					if (numGenVariants < maxVariants && variantValidator.validVariant(c, n.children.filter[a | a!==c], ns)){
-						ns.push(c)
-						val childGenVariants = recGenerateVariants(ns, cs, constraints, maxVariants-numGenVariants, optimizeAlgebraicLoops)
-						numGenVariants = numGenVariants + childGenVariants
-						ns.pop()	
-					}
-				}
-			}
-		} catch (InfeasibleConstraintException e) {
-			// Do nothing.
-			logger.debug("The last added constraint is infeasible. Trying other alternatives.")
-		}
-		
-		// Revert changes in model
-		localConstraints.forEach[k, v| 
-			Assert.isTrue(k.precedes.removeAll(v))
-		]
-		constraints.pop()
-		
-		Assert.isTrue(callDepth == constraints.size)
-		return numGenVariants
 	}
 	
 	def propagateConstraints(VariantDiagram n, Deque<VariantDiagram> ns, ConstraintsStack constraints, HintConfiguration cs) {