|
@@ -6,6 +6,8 @@ import java.util.HashMap
|
|
|
import java.util.List
|
|
|
import java.util.Set
|
|
|
import org.eclipse.core.runtime.Assert
|
|
|
+import org.slf4j.Logger
|
|
|
+import org.slf4j.LoggerFactory
|
|
|
|
|
|
class CandidatesGenerator {
|
|
|
|
|
@@ -13,6 +15,8 @@ class CandidatesGenerator {
|
|
|
IVariantValidator variantValidator
|
|
|
IVariantProcessor processor
|
|
|
|
|
|
+ Logger logger = LoggerFactory.getLogger(typeof(CandidatesGenerator))
|
|
|
+
|
|
|
new (IConstraintChecker c, IVariantValidator v, IVariantProcessor p){
|
|
|
constraintChecker = c
|
|
|
variantValidator = v
|
|
@@ -31,7 +35,8 @@ class CandidatesGenerator {
|
|
|
// Assumes that there is a variant diagram created.
|
|
|
Assert.isTrue(cs.root !== null)
|
|
|
|
|
|
- recGenerateVariants(newLinkedList(cs.root), cs, new ConstraintsStack(), maxVariants)
|
|
|
+ val genVariants = recGenerateVariants(newLinkedList(cs.root), cs, new ConstraintsStack(), maxVariants)
|
|
|
+ return genVariants
|
|
|
}
|
|
|
|
|
|
def generateVariants(Candidates cs){
|
|
@@ -81,6 +86,7 @@ class CandidatesGenerator {
|
|
|
pbAdaptation.POut.valueTo.add(pbAdaptation.dual.PIn)
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
|
|
|
def createVariantTree(Candidates cs){
|
|
@@ -128,16 +134,20 @@ class CandidatesGenerator {
|
|
|
val n = ns.peek() // Head of the queue is the current element being visited.
|
|
|
|
|
|
try {
|
|
|
- switch n.alternative {
|
|
|
+ val alternative = n.alternative
|
|
|
+ switch alternative {
|
|
|
RootCandidateScenario: {
|
|
|
/*
|
|
|
* Recursively create I/O and DoStep constraints.
|
|
|
*/
|
|
|
- val scenario = (n.alternative as RootCandidateScenario)
|
|
|
+ val scenario = (alternative as RootCandidateScenario)
|
|
|
+ logger.debug("Processing Alternative RootCandidateScenario {}", scenario.identifier)
|
|
|
// Outports/HierarchicalPorts -> InPorts/HierarchicalPorts
|
|
|
for (outP : scenario.eAllContents.filter(OutputPortInstance).toIterable) {
|
|
|
for (inP : outP.valueTo) {
|
|
|
- addConstraint(outP, inP, constraints, n, cs)
|
|
|
+ logger.debug("Attempting to add constraint {}.{}->{}.{}.", outP.unit.identifier, outP.identifier, inP.unit.identifier, inP.identifier)
|
|
|
+ val success = addConstraint(outP, inP, constraints, n, cs)
|
|
|
+ logger.debug("Success: {}", success)
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -148,13 +158,17 @@ class CandidatesGenerator {
|
|
|
//Otherwise it is not an input port.
|
|
|
|
|
|
) {
|
|
|
- addConstraint(inP, inP.unit, constraints, n, cs)
|
|
|
+ logger.debug("Attempting to add constraint {}.{}->{}.", inP.unit.identifier, inP.identifier, inP.unit.identifier)
|
|
|
+ val success = addConstraint(inP, inP.unit, constraints, n, cs)
|
|
|
+ logger.debug("Success: {}", success)
|
|
|
}
|
|
|
|
|
|
// The DoStep of each unit can only happen after the doStep of the parent unit.
|
|
|
for (parentUnit : scenario.eAllContents.filter(HierarchicalCosimUnit).toIterable){
|
|
|
for (childUnit : parentUnit.cosimunits){
|
|
|
- addConstraint(parentUnit, childUnit, constraints, n, cs)
|
|
|
+ logger.debug("Attempting to add constraint {}->{}.", parentUnit.identifier, childUnit.identifier)
|
|
|
+ val success = addConstraint(parentUnit, childUnit, constraints, n, cs)
|
|
|
+ logger.debug("Success: {}", success)
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -162,8 +176,9 @@ class CandidatesGenerator {
|
|
|
ExtrapolationAdaptation: {
|
|
|
// Add precedence constraints to the ports that provide value to this port.
|
|
|
// and ensure the doStep ordering.
|
|
|
- val adaptation = n.alternative as ExtrapolationAdaptation
|
|
|
+ val adaptation = alternative as ExtrapolationAdaptation
|
|
|
val adapted = adaptation.adapted()
|
|
|
+ logger.debug("Processing Alternative ExtrapolationAdaptation of {}", adapted.identifier)
|
|
|
Assert.isNotNull(adapted)
|
|
|
Assert.isTrue(adapted instanceof InputPortInstance)
|
|
|
val adaptedPort = adapted as InputPortInstance
|
|
@@ -185,11 +200,14 @@ class CandidatesGenerator {
|
|
|
}
|
|
|
Assert.isTrue(siblingAdaptedPort !== null)
|
|
|
|
|
|
- addConstraint(siblingAdaptedPort, ancestorSrcUnit, constraints, n, cs)
|
|
|
+ logger.debug("Attempting to add constraint {}.{}->{}.", siblingAdaptedPort.unit.identifier, siblingAdaptedPort.identifier, ancestorSrcUnit.identifier)
|
|
|
+ val success = addConstraint(siblingAdaptedPort, ancestorSrcUnit, constraints, n, cs)
|
|
|
+ logger.debug("Success: {}", success)
|
|
|
}
|
|
|
InterpolationAdaptation: {
|
|
|
- val adaptation = n.alternative as InterpolationAdaptation
|
|
|
+ val adaptation = alternative as InterpolationAdaptation
|
|
|
val adapted = adaptation.adapted()
|
|
|
+ logger.debug("Processing Alternative InterpolationAdaptation of {}", adapted.identifier)
|
|
|
Assert.isNotNull(adapted)
|
|
|
Assert.isTrue(adapted instanceof InputPortInstance)
|
|
|
val adaptedPort = adapted as InputPortInstance
|
|
@@ -202,7 +220,11 @@ class CandidatesGenerator {
|
|
|
ancestorSrcPort = ancestorSrcUnit.ports.findFirst[p | adaptedPort.getsValueFrom(p)]
|
|
|
}
|
|
|
|
|
|
- addConstraint(ancestorSrcUnit, ancestorSrcPort, constraints, n, cs)
|
|
|
+
|
|
|
+
|
|
|
+ logger.debug("Attempting to add constraint {}->{}.{}.", ancestorSrcUnit.identifier, ancestorSrcPort.unit.identifier, ancestorSrcPort.identifier)
|
|
|
+ val success = addConstraint(ancestorSrcUnit, ancestorSrcPort, constraints, n, cs)
|
|
|
+ logger.debug("Success: {}", success)
|
|
|
|
|
|
// Redundant, as the srcPort is connected to the adaptedPort
|
|
|
// addConstraint(srcPort, adaptedPort, constraints, n, cs)
|
|
@@ -217,14 +239,23 @@ class CandidatesGenerator {
|
|
|
// Nothing to do.
|
|
|
}
|
|
|
PowerBondAdaptation: {
|
|
|
- // Nothing to do.
|
|
|
- // TODO: Add constraints to make sure the values of the power output port is compute after its dependencies have been set.
|
|
|
+ // TODO Clean up
|
|
|
+// val adaptation = alternative as PowerBondAdaptation
|
|
|
+// val adapted = adaptation.adapted()
|
|
|
+// logger.debug("Processing Alternative PowerBondAdaptation of {}", adapted.identifier)
|
|
|
+// Assert.isNotNull(adapted)
|
|
|
+// Assert.isTrue(adapted instanceof UnitInstance)
|
|
|
+// val unit = adapted as UnitInstance
|
|
|
+//
|
|
|
+// logger.debug("Attempting to add constraint {}->{}.{}.", unit.identifier, adaptation.POut.unit.identifier, adaptation.POut.identifier)
|
|
|
+// val success = addConstraint(unit, adaptation.POut, constraints, n, cs)
|
|
|
+// logger.debug("Success: {}", success)
|
|
|
}
|
|
|
MultiRateAdaptation: {
|
|
|
// Nothing to do
|
|
|
}
|
|
|
default:
|
|
|
- if (n.alternative !== null){
|
|
|
+ if (alternative !== null){
|
|
|
throw new UnsupportedOperationException()
|
|
|
}
|
|
|
}
|
|
@@ -256,8 +287,9 @@ class CandidatesGenerator {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- } catch (InterruptedException e) {
|
|
|
+ } catch (InfeasibleConstraintException e) {
|
|
|
// Do nothing.
|
|
|
+ logger.debug("The last added constraint is infeasible. Trying other alternatives.")
|
|
|
}
|
|
|
|
|
|
// Revert changes in model
|
|
@@ -292,7 +324,7 @@ class CandidatesGenerator {
|
|
|
src.precedes.add(trg)
|
|
|
return true
|
|
|
} else {
|
|
|
- throw new InterruptedException()
|
|
|
+ throw new InfeasibleConstraintException()
|
|
|
}
|
|
|
} else {
|
|
|
return false
|