aboutsummaryrefslogtreecommitdiffstats
path: root/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse
diff options
context:
space:
mode:
Diffstat (limited to 'Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse')
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ActivationSelector.xtend24
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BalancedActivationSelector.xtend51
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BasicScopeGlobalConstraint.xtend103
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BestFirstStrategyForModelGeneration.java207
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/DiversityChecker.xtend184
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/DseUtils.xtend66
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/EvenActivationSelector.xtend20
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/HillClimbingOnRealisticMetricStrategyForModelGeneration.java1000
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/InconsistentScopeGlobalConstraint.xtend25
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/LoggerSolutionFoundHandler.xtend24
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ModelGenerationCompositeObjective.xtend130
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/NumericSolver.xtend192
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/PartialModelAsLogicInterpretation.xtend67
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/PunishSizeObjective.xtend52
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ScopeObjective.xtend6
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionCopier.xtend82
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithCopy.xtend9
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithDiversityDescriptor.xtend120
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SurelyViolatedObjectiveGlobalConstraint.xtend27
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedMultiplicityObjective.xtend18
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedWFObjective.xtend54
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ViatraReasonerSolutionSaver.xtend250
-rw-r--r--Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/WF2ObjectiveConverter.xtend43
23 files changed, 1974 insertions, 780 deletions
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ActivationSelector.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ActivationSelector.xtend
new file mode 100644
index 00000000..65f9814c
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ActivationSelector.xtend
@@ -0,0 +1,24 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import java.util.ArrayList
4import java.util.Collection
5import java.util.Random
6
7abstract class ActivationSelector {
8 long runtime = 0
9 protected val Random r
10 new(Random r) {
11 this.r = r
12 }
13
14 def randomizeActivationIDs(Collection<Object> activationIDs) {
15 val startTime = System.nanoTime
16 val res = internalRandomizationOfActivationIDs(activationIDs)
17 runtime+= System.nanoTime-startTime
18 return res
19 }
20 def protected ArrayList<Object> internalRandomizationOfActivationIDs(Collection<Object> activationIDs);
21 def getRuntime(){
22 return runtime
23 }
24} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BalancedActivationSelector.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BalancedActivationSelector.xtend
new file mode 100644
index 00000000..2df9957b
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BalancedActivationSelector.xtend
@@ -0,0 +1,51 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import java.util.Collection
4import java.util.HashMap
5import java.util.Map
6import java.util.List
7import java.util.Random
8import java.util.ArrayList
9import java.util.LinkedList
10import java.util.Collections
11
12class BalancedActivationSelector extends ActivationSelector{
13 val Random r = new Random
14
15 new(Random r) {
16 super(r)
17 }
18
19 override protected internalRandomizationOfActivationIDs(Collection<Object> activationIDs) {
20 val Map<String,List<Object>> urns = new HashMap
21 val res = new ArrayList(activationIDs.size)
22 for(activationID : activationIDs) {
23 val pair = activationID as Pair<String,? extends Object>
24 val name = pair.key
25 val selectedUrn = urns.get(name)
26 if(selectedUrn!==null) {
27 selectedUrn.add(activationID)
28 } else {
29 val collection = new LinkedList
30 collection.add(activationID)
31 urns.put(name,collection)
32 }
33 }
34
35 for(list:urns.values) {
36 Collections.shuffle(list,r)
37 }
38
39 while(!urns.empty) {
40 val randomEntry = urns.entrySet.get(r.nextInt(urns.size))
41 val list = randomEntry.value
42 val removedLast = list.remove(list.size-1)
43 res.add(removedLast)
44 if(list.empty) {
45 urns.remove(randomEntry.key)
46 }
47 }
48 return res
49 }
50
51} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BasicScopeGlobalConstraint.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BasicScopeGlobalConstraint.xtend
new file mode 100644
index 00000000..67f447ed
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BasicScopeGlobalConstraint.xtend
@@ -0,0 +1,103 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import com.google.common.collect.ImmutableList
4import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
5import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialTypeInterpratation
6import java.util.Comparator
7import java.util.List
8import org.eclipse.viatra.dse.base.ThreadContext
9import org.eclipse.viatra.dse.objectives.Comparators
10import org.eclipse.viatra.dse.objectives.IGlobalConstraint
11import org.eclipse.viatra.dse.objectives.IObjective
12import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
13
14class BasicScopeGlobalConstraint implements IGlobalConstraint, IObjective {
15 val PartialInterpretation p
16 val List<ScopeAssertion> assertions
17
18 new(PartialInterpretation p) {
19 this.p = p
20 assertions = ImmutableList.copyOf(p.scopes.map [
21 val currentSize = targetTypeInterpretation.elements.size
22 val minElements = minNewElements + currentSize
23 val maxElements = if (maxNewElements < 0) {
24 -1
25 } else {
26 maxNewElements + currentSize
27 }
28 new ScopeAssertion(minElements, maxElements, targetTypeInterpretation)
29 ])
30 }
31
32 override init(ThreadContext context) {
33 if (context.model != p) {
34 throw new IllegalArgumentException(
35 "Partial model must be passed to the constructor of BasicScopeGlobalConstraint")
36 }
37 }
38
39 override checkGlobalConstraint(ThreadContext context) {
40 assertions.forall[upperBoundSatisfied]
41 }
42
43 override getFitness(ThreadContext context) {
44 var double fitness = p.minNewElements
45 for (assertion : assertions) {
46 if (!assertion.lowerBoundSatisfied) {
47 fitness += 1
48 }
49 }
50 fitness
51 }
52
53 override satisifiesHardObjective(Double fitness) {
54 fitness <= 0.01
55 }
56
57 override BasicScopeGlobalConstraint createNew() {
58 this
59 }
60
61 override getName() {
62 class.name
63 }
64
65 override getComparator() {
66 Comparators.LOWER_IS_BETTER
67 }
68
69 override getLevel() {
70 2
71 }
72
73 override isHardObjective() {
74 true
75 }
76
77 override setComparator(Comparator<Double> comparator) {
78 throw new UnsupportedOperationException
79 }
80
81 override setLevel(int level) {
82 throw new UnsupportedOperationException
83 }
84
85 @FinalFieldsConstructor
86 private static class ScopeAssertion {
87 val int lowerBound
88 val int upperBound
89 val PartialTypeInterpratation typeDefinitions
90
91 private def getCount() {
92 typeDefinitions.elements.size
93 }
94
95 private def isLowerBoundSatisfied() {
96 count >= lowerBound
97 }
98
99 private def isUpperBoundSatisfied() {
100 upperBound < 0 || count <= upperBound
101 }
102 }
103}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BestFirstStrategyForModelGeneration.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BestFirstStrategyForModelGeneration.java
index d9a1e54c..2940d12d 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BestFirstStrategyForModelGeneration.java
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/BestFirstStrategyForModelGeneration.java
@@ -9,9 +9,7 @@
9 *******************************************************************************/ 9 *******************************************************************************/
10package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse; 10package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse;
11 11
12import java.util.ArrayList;
13import java.util.Arrays; 12import java.util.Arrays;
14import java.util.Collection;
15import java.util.Collections; 13import java.util.Collections;
16import java.util.Comparator; 14import java.util.Comparator;
17import java.util.Iterator; 15import java.util.Iterator;
@@ -22,17 +20,16 @@ import java.util.Random;
22 20
23import org.apache.log4j.Level; 21import org.apache.log4j.Level;
24import org.apache.log4j.Logger; 22import org.apache.log4j.Logger;
23import org.eclipse.emf.ecore.EObject;
25import org.eclipse.emf.ecore.util.EcoreUtil; 24import org.eclipse.emf.ecore.util.EcoreUtil;
25import org.eclipse.viatra.dse.api.SolutionTrajectory;
26import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy; 26import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
27import org.eclipse.viatra.dse.base.ThreadContext; 27import org.eclipse.viatra.dse.base.ThreadContext;
28import org.eclipse.viatra.dse.objectives.Fitness; 28import org.eclipse.viatra.dse.objectives.Fitness;
29import org.eclipse.viatra.dse.objectives.IObjective; 29import org.eclipse.viatra.dse.objectives.IObjective;
30import org.eclipse.viatra.dse.objectives.ObjectiveComparatorHelper; 30import org.eclipse.viatra.dse.objectives.ObjectiveComparatorHelper;
31import org.eclipse.viatra.dse.solutionstore.ISolutionFoundHandler;
31import org.eclipse.viatra.dse.solutionstore.SolutionStore; 32import org.eclipse.viatra.dse.solutionstore.SolutionStore;
32import org.eclipse.viatra.query.runtime.api.IPatternMatch;
33import org.eclipse.viatra.query.runtime.api.IQuerySpecification;
34import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine;
35import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher;
36 33
37import hu.bme.mit.inf.dslreasoner.logic.model.builder.DocumentationLevel; 34import hu.bme.mit.inf.dslreasoner.logic.model.builder.DocumentationLevel;
38import hu.bme.mit.inf.dslreasoner.logic.model.builder.LogicReasoner; 35import hu.bme.mit.inf.dslreasoner.logic.model.builder.LogicReasoner;
@@ -40,11 +37,11 @@ import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem;
40import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.InconsistencyResult; 37import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.InconsistencyResult;
41import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.LogicResult; 38import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.LogicResult;
42import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.ModelResult; 39import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.ModelResult;
43import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationMethod;
44import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretation2logic.PartialInterpretation2Logic; 40import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretation2logic.PartialInterpretation2Logic;
45import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation; 41import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation;
46import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualisation; 42import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualisation;
47import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualiser; 43import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualiser;
44import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ModelGenerationMethod;
48import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasonerConfiguration; 45import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasonerConfiguration;
49import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace; 46import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace;
50 47
@@ -77,54 +74,72 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
77 // Running 74 // Running
78 private PriorityQueue<TrajectoryWithFitness> trajectoiresToExplore; 75 private PriorityQueue<TrajectoryWithFitness> trajectoiresToExplore;
79 private SolutionStore solutionStore; 76 private SolutionStore solutionStore;
80 private SolutionStoreWithCopy solutionStoreWithCopy;
81 private SolutionStoreWithDiversityDescriptor solutionStoreWithDiversityDescriptor;
82 private volatile boolean isInterrupted = false; 77 private volatile boolean isInterrupted = false;
83 private ModelResult modelResultByInternalSolver = null; 78 private ModelResult modelResultByInternalSolver = null;
84 private Random random = new Random(); 79 private Random random = new Random();
85 private Collection<ViatraQueryMatcher<? extends IPatternMatch>> matchers; 80// private Collection<ViatraQueryMatcher<? extends IPatternMatch>> matchers;
86 81 public ActivationSelector activationSelector = new EvenActivationSelector(random);
82 public ViatraReasonerSolutionSaver solutionSaver;
83 public NumericSolver numericSolver;
87 // Statistics 84 // Statistics
88 private int numberOfStatecoderFail = 0; 85 private int numberOfStatecoderFail = 0;
89 private int numberOfPrintedModel = 0; 86 private int numberOfPrintedModel = 0;
90 private int numberOfSolverCalls = 0; 87 private int numberOfSolverCalls = 0;
88 public long globalConstraintEvaluationTime = 0;
89 public long fitnessCalculationTime = 0;
90
91 public long explorationStarted = 0;
91 92
92 public BestFirstStrategyForModelGeneration( 93 public BestFirstStrategyForModelGeneration(
93 ReasonerWorkspace workspace, 94 ReasonerWorkspace workspace,
94 ViatraReasonerConfiguration configuration, 95 ViatraReasonerConfiguration configuration,
95 ModelGenerationMethod method) 96 ModelGenerationMethod method,
96 { 97 ViatraReasonerSolutionSaver solutionSaver,
98 NumericSolver numericSolver) {
97 this.workspace = workspace; 99 this.workspace = workspace;
98 this.configuration = configuration; 100 this.configuration = configuration;
99 this.method = method; 101 this.method = method;
102 this.solutionSaver = solutionSaver;
103 this.numericSolver = numericSolver;
104// logger.setLevel(Level.DEBUG);
100 } 105 }
101 106
102 public SolutionStoreWithCopy getSolutionStoreWithCopy() {
103 return solutionStoreWithCopy;
104 }
105 public SolutionStoreWithDiversityDescriptor getSolutionStoreWithDiversityDescriptor() {
106 return solutionStoreWithDiversityDescriptor;
107 }
108 public int getNumberOfStatecoderFail() { 107 public int getNumberOfStatecoderFail() {
109 return numberOfStatecoderFail; 108 return numberOfStatecoderFail;
110 } 109 }
110 public long getForwardTime() {
111 return context.getDesignSpaceManager().getForwardTime();
112 }
113 public long getBacktrackingTime() {
114 return context.getDesignSpaceManager().getBacktrackingTime();
115 }
111 116
112 @Override 117 @Override
113 public void initStrategy(ThreadContext context) { 118 public void initStrategy(ThreadContext context) {
114 this.context = context; 119 this.context = context;
115 this.solutionStore = context.getGlobalContext().getSolutionStore(); 120 this.solutionStore = context.getGlobalContext().getSolutionStore();
116 ViatraQueryEngine engine = context.getQueryEngine(); 121 solutionStore.registerSolutionFoundHandler(new ISolutionFoundHandler() {
117// // TODO: visualisation 122
118 matchers = new LinkedList<ViatraQueryMatcher<? extends IPatternMatch>>(); 123 @Override
119 for(IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> p : this.method.getAllPatterns()) { 124 public void solutionTriedToSave(ThreadContext context, SolutionTrajectory trajectory) {
120 //System.out.println(p.getSimpleName()); 125 // Ignore.
121 ViatraQueryMatcher<? extends IPatternMatch> matcher = p.getMatcher(engine); 126 }
122 matchers.add(matcher); 127
123 } 128 @Override
129 public void solutionFound(ThreadContext context, SolutionTrajectory trajectory) {
130 configuration.progressMonitor.workedModelFound(configuration.solutionScope.numberOfRequiredSolutions);
131 saveTimes();
132 logger.debug("Found a solution.");
133 }
134 });
135 numericSolver.init(context);
124 136
125 this.solutionStoreWithCopy = new SolutionStoreWithCopy(); 137// ViatraQueryEngine engine = context.getQueryEngine();
126 this.solutionStoreWithDiversityDescriptor = new SolutionStoreWithDiversityDescriptor(configuration.diversityRequirement); 138// matchers = new LinkedList<ViatraQueryMatcher<? extends IPatternMatch>>();
127 139// for(IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>> p : this.method.getAllPatterns()) {
140// ViatraQueryMatcher<? extends IPatternMatch> matcher = p.getMatcher(engine);
141// }
142//
128 final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper(); 143 final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper();
129 this.comparator = new Comparator<TrajectoryWithFitness>() { 144 this.comparator = new Comparator<TrajectoryWithFitness>() {
130 @Override 145 @Override
@@ -138,23 +153,26 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
138 153
139 @Override 154 @Override
140 public void explore() { 155 public void explore() {
141 if (!context.checkGlobalConstraints()) { 156 this.explorationStarted=System.nanoTime();
157 if (!checkGlobalConstraints()) {
142 logger.info("Global contraint is not satisifed in the first state. Terminate."); 158 logger.info("Global contraint is not satisifed in the first state. Terminate.");
143 return; 159 return;
160 } else if(!numericSolver.maySatisfiable()) {
161 logger.info("Numeric contraints are not satisifed in the first state. Terminate.");
162 return;
144 } 163 }
145 if (configuration.searchSpaceConstraints.maxDepth == 0) { 164 if (configuration.searchSpaceConstraints.maxDepth == 0) {
146 logger.info("Maximal depth is reached in the initial solution. Terminate."); 165 logger.info("Maximal depth is reached in the initial solution. Terminate.");
147 return; 166 return;
148 } 167 }
149 168
150 final Fitness firstFittness = context.calculateFitness(); 169 final Fitness firstFitness = calculateFitness();
151 checkForSolution(firstFittness); 170 checkForSolution(firstFitness);
152 171
153 final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper(); 172 final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper();
154 final Object[] firstTrajectory = context.getTrajectory().toArray(new Object[0]); 173 final Object[] firstTrajectory = context.getTrajectory().toArray(new Object[0]);
155 TrajectoryWithFitness currentTrajectoryWithFittness = new TrajectoryWithFitness(firstTrajectory, firstFittness); 174 TrajectoryWithFitness currentTrajectoryWithFitness = new TrajectoryWithFitness(firstTrajectory, firstFitness);
156 trajectoiresToExplore.add(currentTrajectoryWithFittness); 175 trajectoiresToExplore.add(currentTrajectoryWithFitness);
157
158 //if(configuration) 176 //if(configuration)
159 visualiseCurrentState(); 177 visualiseCurrentState();
160// for(ViatraQueryMatcher<? extends IPatternMatch> matcher : matchers) { 178// for(ViatraQueryMatcher<? extends IPatternMatch> matcher : matchers) {
@@ -168,22 +186,22 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
168 186
169 mainLoop: while (!isInterrupted && !configuration.progressMonitor.isCancelled()) { 187 mainLoop: while (!isInterrupted && !configuration.progressMonitor.isCancelled()) {
170 188
171 if (currentTrajectoryWithFittness == null) { 189 if (currentTrajectoryWithFitness == null) {
172 if (trajectoiresToExplore.isEmpty()) { 190 if (trajectoiresToExplore.isEmpty()) {
173 logger.debug("State space is fully traversed."); 191 logger.debug("State space is fully traversed.");
174 return; 192 return;
175 } else { 193 } else {
176 currentTrajectoryWithFittness = selectState(); 194 currentTrajectoryWithFitness = selectState();
177 if (logger.isDebugEnabled()) { 195 if (logger.isDebugEnabled()) {
178 logger.debug("Current trajectory: " + Arrays.toString(context.getTrajectory().toArray())); 196 logger.debug("Current trajectory: " + Arrays.toString(context.getTrajectory().toArray()));
179 logger.debug("New trajectory is chosen: " + currentTrajectoryWithFittness); 197 logger.debug("New trajectory is chosen: " + currentTrajectoryWithFitness);
180 } 198 }
181 context.getDesignSpaceManager().executeTrajectoryWithMinimalBacktrackWithoutStateCoding(currentTrajectoryWithFittness.trajectory); 199 context.getDesignSpaceManager().executeTrajectoryWithMinimalBacktrackWithoutStateCoding(currentTrajectoryWithFitness.trajectory);
182 } 200 }
183 } 201 }
184 202
185// visualiseCurrentState(); 203// visualiseCurrentState();
186// boolean consistencyCheckResult = checkConsistency(currentTrajectoryWithFittness); 204// boolean consistencyCheckResult = checkConsistency(currentTrajectoryWithfitness);
187// if(consistencyCheckResult == true) { 205// if(consistencyCheckResult == true) {
188// continue mainLoop; 206// continue mainLoop;
189// } 207// }
@@ -193,32 +211,30 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
193 211
194 while (!isInterrupted && !configuration.progressMonitor.isCancelled() && iterator.hasNext()) { 212 while (!isInterrupted && !configuration.progressMonitor.isCancelled() && iterator.hasNext()) {
195 final Object nextActivation = iterator.next(); 213 final Object nextActivation = iterator.next();
196// if (!iterator.hasNext()) {
197// logger.debug("Last untraversed activation of the state.");
198// trajectoiresToExplore.remove(currentTrajectoryWithFittness);
199// }
200 logger.debug("Executing new activation: " + nextActivation); 214 logger.debug("Executing new activation: " + nextActivation);
201 context.executeAcitvationId(nextActivation); 215 context.executeAcitvationId(nextActivation);
216 method.getStatistics().incrementDecisionCount();
202 217
203 visualiseCurrentState(); 218 visualiseCurrentState();
204// for(ViatraQueryMatcher<? extends IPatternMatch> matcher : matchers) { 219// for(ViatraQueryMatcher<? extends IPatternMatch> matcher : matchers) {
205// System.out.println(matcher.getPatternName()); 220// int c = matcher.countMatches();
206// System.out.println("---------"); 221// if(c>=1) {
207// for(IPatternMatch m : matcher.getAllMatches()) { 222// System.out.println(c+ " " +matcher.getPatternName());
208// System.out.println(m); 223// }
209// }
210// System.out.println("---------");
211// } 224// }
212 225
213 boolean consistencyCheckResult = checkConsistency(currentTrajectoryWithFittness); 226 boolean consistencyCheckResult = checkConsistency(currentTrajectoryWithFitness);
214 if(consistencyCheckResult == true) { continue mainLoop; } 227 if(consistencyCheckResult == true) { continue mainLoop; }
215 228
216 if (context.isCurrentStateAlreadyTraversed()) { 229 if (context.isCurrentStateAlreadyTraversed()) {
217 logger.info("The new state is already visited."); 230 logger.info("The new state is already visited.");
218 context.backtrack(); 231 context.backtrack();
219 } else if (!context.checkGlobalConstraints()) { 232 } else if (!checkGlobalConstraints()) {
220 logger.debug("Global contraint is not satisifed."); 233 logger.debug("Global contraint is not satisifed.");
221 context.backtrack(); 234 context.backtrack();
235 } else if (!numericSolver.maySatisfiable()) {
236 logger.debug("Numeric constraints are not satisifed.");
237 context.backtrack();
222 } else { 238 } else {
223 final Fitness nextFitness = context.calculateFitness(); 239 final Fitness nextFitness = context.calculateFitness();
224 checkForSolution(nextFitness); 240 checkForSolution(nextFitness);
@@ -228,59 +244,89 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
228 continue; 244 continue;
229 } 245 }
230 246
231 TrajectoryWithFitness nextTrajectoryWithFittness = new TrajectoryWithFitness( 247 TrajectoryWithFitness nextTrajectoryWithfitness = new TrajectoryWithFitness(
232 context.getTrajectory().toArray(), nextFitness); 248 context.getTrajectory().toArray(), nextFitness);
233 trajectoiresToExplore.add(nextTrajectoryWithFittness); 249 trajectoiresToExplore.add(nextTrajectoryWithfitness);
234 250
235 int compare = objectiveComparatorHelper.compare(currentTrajectoryWithFittness.fitness, 251 int compare = objectiveComparatorHelper.compare(currentTrajectoryWithFitness.fitness,
236 nextTrajectoryWithFittness.fitness); 252 nextTrajectoryWithfitness.fitness);
237 if (compare < 0) { 253 if (compare < 0) {
238 logger.debug("Better fitness, moving on: " + nextFitness); 254 logger.debug("Better fitness, moving on: " + nextFitness);
239 currentTrajectoryWithFittness = nextTrajectoryWithFittness; 255 currentTrajectoryWithFitness = nextTrajectoryWithfitness;
240 continue mainLoop; 256 continue mainLoop;
241 } else if (compare == 0) { 257 } else if (compare == 0) {
242 logger.debug("Equally good fitness, moving on: " + nextFitness); 258 logger.debug("Equally good fitness, moving on: " + nextFitness);
243 currentTrajectoryWithFittness = nextTrajectoryWithFittness; 259 currentTrajectoryWithFitness = nextTrajectoryWithfitness;
244 continue mainLoop; 260 continue mainLoop;
245 } else { 261 } else {
246 logger.debug("Worse fitness."); 262 logger.debug("Worse fitness.");
247 currentTrajectoryWithFittness = null; 263 currentTrajectoryWithFitness = null;
248 continue mainLoop; 264 continue mainLoop;
249 } 265 }
250 } 266 }
251 } 267 }
252 268
253 logger.debug("State is fully traversed."); 269 logger.debug("State is fully traversed.");
254 trajectoiresToExplore.remove(currentTrajectoryWithFittness); 270 trajectoiresToExplore.remove(currentTrajectoryWithFitness);
255 currentTrajectoryWithFittness = null; 271 currentTrajectoryWithFitness = null;
256 272
257 } 273 }
258 logger.info("Interrupted."); 274 logger.info("Interrupted.");
259 } 275 }
260 276
277 private boolean checkGlobalConstraints() {
278 long start = System.nanoTime();
279 boolean result = context.checkGlobalConstraints();
280 globalConstraintEvaluationTime += System.nanoTime() - start;
281 return result;
282 }
283
284 private Fitness calculateFitness() {
285 long start = System.nanoTime();
286 Fitness fitness = context.calculateFitness();
287 fitnessCalculationTime += System.nanoTime() - start;
288 return fitness;
289 }
290
261 private List<Object> selectActivation() { 291 private List<Object> selectActivation() {
262 List<Object> activationIds; 292 List<Object> activationIds;
263 try { 293 try {
264 activationIds = new ArrayList<Object>(context.getUntraversedActivationIds()); 294 activationIds = this.activationSelector.randomizeActivationIDs(context.getUntraversedActivationIds());
265 Collections.shuffle(activationIds);
266 } catch (NullPointerException e) { 295 } catch (NullPointerException e) {
296// logger.warn("Unexpected state code: " + context.getDesignSpaceManager().getCurrentState());
267 numberOfStatecoderFail++; 297 numberOfStatecoderFail++;
268 activationIds = Collections.emptyList(); 298 activationIds = Collections.emptyList();
269 } 299 }
270 return activationIds; 300 return activationIds;
271 } 301 }
272 302
273 private void checkForSolution(final Fitness fittness) { 303 private void checkForSolution(final Fitness fitness) {
274 if (fittness.isSatisifiesHardObjectives()) { 304 solutionStore.newSolution(context);
275 if (solutionStoreWithDiversityDescriptor.isDifferent(context)) { 305 }
276 solutionStoreWithCopy.newSolution(context); 306
277 solutionStoreWithDiversityDescriptor.newSolution(context); 307 public List<String> times = new LinkedList<String>();
278 solutionStore.newSolution(context); 308 private void saveTimes() {
279 configuration.progressMonitor.workedModelFound(configuration.solutionScope.numberOfRequiredSolution); 309 long forwardTime = context.getDesignSpaceManager().getForwardTime()/1000000;
280 310 long backtrackingTime = context.getDesignSpaceManager().getBacktrackingTime()/1000000;
281 logger.debug("Found a solution."); 311 long activationSelection = this.activationSelector.getRuntime()/1000000;
282 } 312 long solutionCopierTime = this.solutionSaver.getTotalCopierRuntime()/1000000;
283 } 313 long numericalSolverSumTime = this.numericSolver.getRuntime()/1000000;
314 long numericalSolverProblemForming = this.numericSolver.getSolverSolvingProblem()/1000000;
315 long numericalSolverSolving = this.numericSolver.getSolverSolvingProblem()/1000000;
316 long numericalSolverInterpreting = this.numericSolver.getSolverSolution()/1000000;
317 this.times.add(
318 "(TransformationExecutionTime"+method.getStatistics().transformationExecutionTime/1000000+
319 "|ForwardTime:"+forwardTime+
320 "|Backtrackingtime:"+backtrackingTime+
321 "|GlobalConstraintEvaluationTime:"+(globalConstraintEvaluationTime/1000000)+
322 "|FitnessCalculationTime:"+(fitnessCalculationTime/1000000)+
323 "|ActivationSelectionTime:"+activationSelection+
324 "|SolutionCopyTime:"+solutionCopierTime+
325 "|NumericalSolverSumTime:"+numericalSolverSumTime+
326 "|NumericalSolverProblemFormingTime:"+numericalSolverProblemForming+
327 "|NumericalSolverSolvingTime:"+numericalSolverSolving+
328 "|NumericalSolverInterpretingSolution:"+numericalSolverInterpreting+")");
329
284 } 330 }
285 331
286 @Override 332 @Override
@@ -309,7 +355,7 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
309 } else { 355 } else {
310 return trajectoiresToExplore.element(); 356 return trajectoiresToExplore.element();
311 } 357 }
312 } 358 }
313 359
314// private void logCurrentStateMetric() { 360// private void logCurrentStateMetric() {
315// if(this.configuration.documentationLevel != DocumentationLevel.NONE || workspace == null) { 361// if(this.configuration.documentationLevel != DocumentationLevel.NONE || workspace == null) {
@@ -322,13 +368,16 @@ public class BestFirstStrategyForModelGeneration implements IStrategy {
322 368
323 369
324 public void visualiseCurrentState() { 370 public void visualiseCurrentState() {
325 PartialInterpretationVisualiser partialInterpretatioVisualiser = configuration.debugCongiguration.partialInterpretatioVisualiser; 371 PartialInterpretationVisualiser partialInterpretatioVisualiser = configuration.debugConfiguration.partialInterpretatioVisualiser;
326 if(partialInterpretatioVisualiser != null && this.configuration.documentationLevel == DocumentationLevel.FULL && workspace != null) { 372 if(partialInterpretatioVisualiser != null && this.configuration.documentationLevel == DocumentationLevel.FULL && workspace != null) {
327 PartialInterpretation p = (PartialInterpretation) (context.getModel()); 373 PartialInterpretation p = (PartialInterpretation) (context.getModel());
328 int id = ++numberOfPrintedModel; 374 int id = ++numberOfPrintedModel;
329 if (id % configuration.debugCongiguration.partalInterpretationVisualisationFrequency == 0) { 375 if (id % configuration.debugConfiguration.partalInterpretationVisualisationFrequency == 0) {
330 PartialInterpretationVisualisation visualisation = partialInterpretatioVisualiser.visualiseConcretization(p); 376 PartialInterpretationVisualisation visualisation = partialInterpretatioVisualiser.visualiseConcretization(p);
331 visualisation.writeToFile(workspace, String.format("state%09d.png", id)); 377 logger.debug("Visualizing state: " + id + " (" + context.getDesignSpaceManager().getCurrentState() + ")");
378 String name = String.format("state%09d", id);
379 visualisation.writeToFile(workspace, name + ".png");
380 workspace.writeModel((EObject) context.getModel(), name + ".xmi");
332 } 381 }
333 } 382 }
334 } 383 }
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/DiversityChecker.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/DiversityChecker.xtend
new file mode 100644
index 00000000..fb1b2066
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/DiversityChecker.xtend
@@ -0,0 +1,184 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import com.google.common.collect.HashMultiset
4import com.google.common.collect.ImmutableSet
5import com.google.common.collect.Multiset
6import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.AbstractNodeDescriptor
7import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.NeighbourhoodWithTraces
8import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.PartialInterpretation2ImmutableTypeLattice
9import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
10import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.DiversityDescriptor
11import java.util.Collection
12import java.util.HashSet
13import java.util.Map
14import java.util.Set
15import org.eclipse.viatra.dse.base.ThreadContext
16import org.eclipse.xtend.lib.annotations.Accessors
17
18interface DiversityChecker {
19 public static val NO_DIVERSITY_CHECKER = new DiversityChecker {
20 override isActive() {
21 false
22 }
23
24 override getTotalRuntime() {
25 0
26 }
27
28 override getSuccessRate() {
29 1.0
30 }
31
32 override newSolution(ThreadContext threadContext, Object solutionId, Collection<Object> dominatedSolutionIds) {
33 true
34 }
35 }
36
37 def boolean isActive()
38
39 def long getTotalRuntime()
40
41 def double getSuccessRate()
42
43 def boolean newSolution(ThreadContext threadContext, Object solutionId, Collection<Object> dominatedSolutionIds)
44
45 static def of(DiversityDescriptor descriptor) {
46 if (descriptor.ensureDiversity) {
47 new NodewiseDiversityChecker(descriptor)
48 } else {
49 NO_DIVERSITY_CHECKER
50 }
51 }
52}
53
54abstract class AbstractDiversityChecker implements DiversityChecker {
55 val DiversityDescriptor descriptor
56 val PartialInterpretation2ImmutableTypeLattice solutionCoder = new PartialInterpretation2ImmutableTypeLattice
57
58 @Accessors(PUBLIC_GETTER) var long totalRuntime = 0
59 var int allCheckCount = 0
60 var int successfulCheckCount = 0
61
62 protected new(DiversityDescriptor descriptor) {
63 if (!descriptor.ensureDiversity) {
64 throw new IllegalArgumentException(
65 "Diversity description should enforce diversity or NO_DIVERSITY_CHECKER should be used instead.")
66 }
67 this.descriptor = descriptor
68 }
69
70 override isActive() {
71 true
72 }
73
74 override getTotalRuntime() {
75 throw new UnsupportedOperationException("TODO: auto-generated method stub")
76 }
77
78 override getSuccessRate() {
79 (allCheckCount as double) / (successfulCheckCount as double)
80 }
81
82 override newSolution(ThreadContext threadContext, Object solutionId, Collection<Object> dominatedSolutionIds) {
83 val start = System.nanoTime
84 val model = threadContext.model as PartialInterpretation
85 val representation = solutionCoder.createRepresentation(model, descriptor.range, descriptor.parallels,
86 descriptor.maxNumber, descriptor.relevantTypes, descriptor.relevantRelations)
87 val isDifferent = internalNewSolution(representation, solutionId, dominatedSolutionIds)
88 totalRuntime += System.nanoTime - start
89 allCheckCount++
90 if (isDifferent) {
91 successfulCheckCount++
92 }
93 isDifferent
94 }
95
96 protected abstract def boolean internalNewSolution(
97 NeighbourhoodWithTraces<Map<? extends AbstractNodeDescriptor, Integer>, AbstractNodeDescriptor> representation,
98 Object solutionId, Collection<Object> dominatedSolutionIds)
99}
100
101class NodewiseDiversityChecker extends AbstractDiversityChecker {
102 var Multiset<Integer> nodeCodes = HashMultiset.create
103 val Map<Object, Set<Integer>> tracedNodeCodes = newHashMap
104
105 new(DiversityDescriptor descriptor) {
106 super(descriptor)
107 }
108
109 override protected internalNewSolution(
110 NeighbourhoodWithTraces<Map<? extends AbstractNodeDescriptor, Integer>, AbstractNodeDescriptor> representation,
111 Object solutionId, Collection<Object> dominatedSolutionIds) {
112 val nodeCodesInSolution = ImmutableSet.copyOf(representation.modelRepresentation.keySet.map[hashCode])
113 val remainingNodeCodes = if (dominatedSolutionIds.empty) {
114 nodeCodes
115 } else {
116 getRemainingNodeCodes(dominatedSolutionIds)
117 }
118 val hasNewCode = nodeCodesInSolution.exists[!remainingNodeCodes.contains(it)]
119 if (hasNewCode) {
120 nodeCodes = remainingNodeCodes
121 nodeCodes.addAll(nodeCodesInSolution)
122 for (dominatedSolutionId : dominatedSolutionIds) {
123 tracedNodeCodes.remove(dominatedSolutionId)
124 }
125 tracedNodeCodes.put(solutionId, nodeCodesInSolution)
126 }
127 hasNewCode
128 }
129
130 private def getRemainingNodeCodes(Collection<Object> dominatedSolutionIds) {
131 // TODO Optimize multiset operations.
132 val copyOfNodeCodes = HashMultiset.create(nodeCodes)
133 for (dominatedSolutionId : dominatedSolutionIds) {
134 val dominatedModelCode = tracedNodeCodes.get(dominatedSolutionId)
135 if (dominatedModelCode === null) {
136 throw new IllegalArgumentException("Unknown dominated solution: " + dominatedSolutionId)
137 }
138 copyOfNodeCodes.removeAll(dominatedModelCode)
139 }
140 copyOfNodeCodes
141 }
142}
143
144class GraphwiseDiversityChecker extends AbstractDiversityChecker {
145 var Set<Integer> modelCodes = newHashSet
146 val Map<Object, Integer> tracedModelCodes = newHashMap
147
148 new(DiversityDescriptor descriptor) {
149 super(descriptor)
150 }
151
152 override protected internalNewSolution(
153 NeighbourhoodWithTraces<Map<? extends AbstractNodeDescriptor, Integer>, AbstractNodeDescriptor> representation,
154 Object solutionId, Collection<Object> dominatedSolutionIds) {
155 val modelCodeOfSolution = representation.modelRepresentation.hashCode
156 val remainingModelCodes = if (dominatedSolutionIds.empty) {
157 modelCodes
158 } else {
159 getRemainingModelCodes(dominatedSolutionIds)
160 }
161 val isNewCode = !remainingModelCodes.contains(modelCodeOfSolution)
162 if (isNewCode) {
163 modelCodes = remainingModelCodes
164 modelCodes += modelCodeOfSolution
165 for (dominatedSolutionId : dominatedSolutionIds) {
166 tracedModelCodes.remove(dominatedSolutionId)
167 }
168 tracedModelCodes.put(solutionId, modelCodeOfSolution)
169 }
170 isNewCode
171 }
172
173 private def getRemainingModelCodes(Collection<Object> dominatedSolutionIds) {
174 val copyOfModelCodes = new HashSet(modelCodes)
175 for (dominatedSolutionId : dominatedSolutionIds) {
176 val dominatedModelCode = tracedModelCodes.get(dominatedSolutionId)
177 if (dominatedModelCode === null) {
178 throw new IllegalArgumentException("Unknown dominated solution: " + dominatedSolutionId)
179 }
180 copyOfModelCodes -= dominatedModelCode
181 }
182 copyOfModelCodes
183 }
184}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/DseUtils.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/DseUtils.xtend
new file mode 100644
index 00000000..3c2e3319
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/DseUtils.xtend
@@ -0,0 +1,66 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.IThreeValuedObjective
4import org.eclipse.viatra.dse.base.ThreadContext
5import org.eclipse.viatra.dse.objectives.Comparators
6import org.eclipse.viatra.dse.objectives.Fitness
7import org.eclipse.viatra.dse.objectives.IObjective
8
9final class DseUtils {
10 private new() {
11 throw new IllegalStateException("This is a static utility class and should not be instantiated directly.")
12 }
13
14 static def calculateFitness(ThreadContext it, (IObjective)=>Double getFitness) {
15 val result = new Fitness
16 var boolean satisifiesHardObjectives = true
17 for (objective : objectives) {
18 val fitness = getFitness.apply(objective)
19 result.put(objective.name, fitness)
20 if (objective.isHardObjective() && !objective.satisifiesHardObjective(fitness)) {
21 satisifiesHardObjectives = false
22 }
23 }
24 result.satisifiesHardObjectives = satisifiesHardObjectives
25 result
26 }
27
28 static def caclulateBestPossibleFitness(ThreadContext threadContext) {
29 threadContext.calculateFitness [ objective |
30 if (objective instanceof IThreeValuedObjective) {
31 objective.getBestPossibleFitness(threadContext)
32 } else {
33 switch (objective.comparator) {
34 case Comparators.LOWER_IS_BETTER:
35 Double.NEGATIVE_INFINITY
36 case Comparators.HIGHER_IS_BETTER:
37 Double.POSITIVE_INFINITY
38 case Comparators.DIFFERENCE_TO_ZERO_IS_BETTER:
39 0.0
40 default:
41 throw new IllegalArgumentException("Unknown comparator for non-three-valued objective: " +
42 objective.name)
43 }
44 }
45 ]
46 }
47
48 static def caclulateWorstPossibleFitness(ThreadContext threadContext) {
49 threadContext.calculateFitness [ objective |
50 if (objective instanceof IThreeValuedObjective) {
51 objective.getWorstPossibleFitness(threadContext)
52 } else {
53 switch (objective.comparator) {
54 case Comparators.LOWER_IS_BETTER,
55 case Comparators.DIFFERENCE_TO_ZERO_IS_BETTER:
56 Double.POSITIVE_INFINITY
57 case Comparators.HIGHER_IS_BETTER:
58 Double.NEGATIVE_INFINITY
59 default:
60 throw new IllegalArgumentException("Unknown comparator for non-three-valued objective: " +
61 objective.name)
62 }
63 }
64 ]
65 }
66}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/EvenActivationSelector.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/EvenActivationSelector.xtend
new file mode 100644
index 00000000..82a5f32d
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/EvenActivationSelector.xtend
@@ -0,0 +1,20 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import java.util.Random
4import java.util.Collection
5import java.util.Collections
6import java.util.ArrayList
7
8class EvenActivationSelector extends ActivationSelector {
9
10 new(Random r) {
11 super(r)
12 }
13
14 override protected internalRandomizationOfActivationIDs(Collection<Object> activationIDs) {
15 val toShuffle = new ArrayList<Object>(activationIDs);
16 Collections.shuffle(toShuffle);
17 return toShuffle
18 }
19
20} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/HillClimbingOnRealisticMetricStrategyForModelGeneration.java b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/HillClimbingOnRealisticMetricStrategyForModelGeneration.java
index eb7df089..d9f84b36 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/HillClimbingOnRealisticMetricStrategyForModelGeneration.java
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/HillClimbingOnRealisticMetricStrategyForModelGeneration.java
@@ -16,6 +16,7 @@ import java.util.Random;
16import java.util.Set; 16import java.util.Set;
17 17
18import org.apache.log4j.Logger; 18import org.apache.log4j.Logger;
19import org.eclipse.emf.ecore.EObject;
19import org.eclipse.emf.ecore.util.EcoreUtil; 20import org.eclipse.emf.ecore.util.EcoreUtil;
20import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy; 21import org.eclipse.viatra.dse.api.strategy.interfaces.IStrategy;
21import org.eclipse.viatra.dse.base.ThreadContext; 22import org.eclipse.viatra.dse.base.ThreadContext;
@@ -35,480 +36,540 @@ import hu.bme.mit.inf.dslreasoner.logic.model.logicproblem.LogicProblem;
35import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.InconsistencyResult; 36import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.InconsistencyResult;
36import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.LogicResult; 37import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.LogicResult;
37import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.ModelResult; 38import hu.bme.mit.inf.dslreasoner.logic.model.logicresult.ModelResult;
38import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.ModelGenerationMethod;
39import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretation2logic.PartialInterpretation2Logic; 39import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretation2logic.PartialInterpretation2Logic;
40import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation; 40import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation;
41import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.statecoder.NeighbourhoodBasedPartialInterpretationStateCoder;
41import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualisation; 42import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualisation;
42import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualiser; 43import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.visualisation.PartialInterpretationVisualiser;
44import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ModelGenerationMethod;
43import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.RealisticGuidance; 45import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.RealisticGuidance;
44import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasonerConfiguration; 46import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasonerConfiguration;
45import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace; 47import hu.bme.mit.inf.dslreasoner.workspace.ReasonerWorkspace;
46 48
47public class HillClimbingOnRealisticMetricStrategyForModelGeneration implements IStrategy { 49public class HillClimbingOnRealisticMetricStrategyForModelGeneration implements IStrategy {
48 // Services and Configuration 50 // Services and Configuration
49 private ThreadContext context; 51 private ThreadContext context;
50 private ReasonerWorkspace workspace; 52 private ReasonerWorkspace workspace;
51 private ViatraReasonerConfiguration configuration; 53 private ViatraReasonerConfiguration configuration;
52 private ModelGenerationMethod method; 54 private ModelGenerationMethod method;
53 private PartialInterpretation2Logic partialInterpretation2Logic = new PartialInterpretation2Logic(); 55 private PartialInterpretation2Logic partialInterpretation2Logic = new PartialInterpretation2Logic();
54 private Comparator<TrajectoryWithFitness> comparator; 56 private Comparator<TrajectoryWithFitness> comparator;
55 private Logger logger = Logger.getLogger(IStrategy.class); 57 private Logger logger = Logger.getLogger(IStrategy.class);
58 public NumericSolver numericSolver = null;
59
60 // Running
61 private PriorityQueue<TrajectoryWithFitness> trajectoiresToExplore;
62 private SolutionStore solutionStore;
63 private SolutionStoreWithCopy solutionStoreWithCopy;
64 private SolutionStoreWithDiversityDescriptor solutionStoreWithDiversityDescriptor;
65 private volatile boolean isInterrupted = false;
66 private ModelResult modelResultByInternalSolver = null;
67 private Random random = new Random();
68
69 // matchers for detecting the number of violations
70 private Collection<ViatraQueryMatcher<? extends IPatternMatch>> mustMatchers;
71 private Collection<ViatraQueryMatcher<? extends IPatternMatch>> mayMatchers;
72
73 // Encode the used activations of a particular state
74 private Map<Object, List<Object>> stateAndActivations;
75 private boolean allowMustViolation;
76 private Domain domain;
77 int targetSize;
78 public ActivationSelector activationSelector = new EvenActivationSelector(random);
79 // Statistics
80 private int numberOfStatecoderFail = 0;
81 private int numberOfPrintedModel = 0;
82 private int numberOfSolverCalls = 0;
83 private PartialInterpretationMetricDistance metricDistance;
84 private double currentStateValue = Double.MAX_VALUE;
85 private double currentNodeTypeDistance = 1;
86 private int numNodesToGenerate = 0;
87 public long explorationStarted = 0;
88 public long globalConstraintEvaluationTime = 0;
89 public long fitnessCalculationTime = 0;
90
91 public HillClimbingOnRealisticMetricStrategyForModelGeneration(
92 ReasonerWorkspace workspace,
93 ViatraReasonerConfiguration configuration,
94 ModelGenerationMethod method)
95 {
96 this.workspace = workspace;
97 this.configuration = configuration;
98 this.method = method;
99 }
100
101 public SolutionStoreWithCopy getSolutionStoreWithCopy() {
102 return solutionStoreWithCopy;
103 }
104 public SolutionStoreWithDiversityDescriptor getSolutionStoreWithDiversityDescriptor() {
105 return solutionStoreWithDiversityDescriptor;
106 }
107 public int getNumberOfStatecoderFail() {
108 return numberOfStatecoderFail;
109 }
110
111 public long getForwardTime() {
112 return context.getDesignSpaceManager().getForwardTime();
113 }
114 public long getBacktrackingTime() {
115 return context.getDesignSpaceManager().getBacktrackingTime();
116 }
117
118 @Override
119 public void initStrategy(ThreadContext context) {
120 this.context = context;
121 this.solutionStore = context.getGlobalContext().getSolutionStore();
122 domain = Domain.valueOf(configuration.domain);
123
124 ViatraQueryEngine engine = context.getQueryEngine();
125// // TODO: visualisation
126 mustMatchers = new LinkedList<ViatraQueryMatcher<? extends IPatternMatch>>();
127 mayMatchers = new LinkedList<ViatraQueryMatcher<? extends IPatternMatch>>();
56 128
57 // Running 129 // manully restict the number of super types of one class
58 private PriorityQueue<TrajectoryWithFitness> trajectoiresToExplore; 130 this.method.getInvalidWF().forEach(a ->{
59 private SolutionStore solutionStore; 131 ViatraQueryMatcher<? extends IPatternMatch> matcher = a.getMatcher(engine);
60 private SolutionStoreWithCopy solutionStoreWithCopy; 132 mustMatchers.add(matcher);
61 private SolutionStoreWithDiversityDescriptor solutionStoreWithDiversityDescriptor; 133 });
62 private volatile boolean isInterrupted = false;
63 private ModelResult modelResultByInternalSolver = null;
64 private Random random = new Random();
65 134
66 // matchers for detecting the number of violations 135 this.method.getUnfinishedWF().forEach(a ->{
67 private Collection<ViatraQueryMatcher<? extends IPatternMatch>> mustMatchers; 136 ViatraQueryMatcher<? extends IPatternMatch> matcher = a.getMatcher(engine);
68 private Collection<ViatraQueryMatcher<? extends IPatternMatch>> mayMatchers; 137 mayMatchers.add(matcher);
138 });
69 139
70 // Encode the used activations of a particular state
71 private Map<Object, List<Object>> stateAndActivations;
72 private boolean allowMustViolation;
73 private Domain domain;
74 int targetSize;
75
76 // Statistics
77 private int numberOfStatecoderFail = 0;
78 private int numberOfPrintedModel = 0;
79 private int numberOfSolverCalls = 0;
80 private PartialInterpretationMetricDistance metricDistance;
81 private double currentStateValue = Double.MAX_VALUE;
82 private double currentNodeTypeDistance = 1;
83 private int numNodesToGenerate = 0;
84 140
85 public HillClimbingOnRealisticMetricStrategyForModelGeneration( 141 //set up comparator
86 ReasonerWorkspace workspace, 142 final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper();
87 ViatraReasonerConfiguration configuration, 143 this.comparator = new Comparator<TrajectoryWithFitness>() {
88 ModelGenerationMethod method) 144 @Override
89 { 145 public int compare(TrajectoryWithFitness o1, TrajectoryWithFitness o2) {
90 this.workspace = workspace; 146 return objectiveComparatorHelper.compare(o2.fitness, o1.fitness);
91 this.configuration = configuration; 147 }
92 this.method = method; 148 };
93 }
94 149
95 public SolutionStoreWithCopy getSolutionStoreWithCopy() { 150 this.solutionStoreWithCopy = new SolutionStoreWithCopy();
96 return solutionStoreWithCopy; 151 this.solutionStoreWithDiversityDescriptor = new SolutionStoreWithDiversityDescriptor(configuration.diversityRequirement);
97 } 152
98 public SolutionStoreWithDiversityDescriptor getSolutionStoreWithDiversityDescriptor() { 153 trajectoiresToExplore = new PriorityQueue<TrajectoryWithFitness>(11, comparator);
99 return solutionStoreWithDiversityDescriptor; 154 stateAndActivations = new HashMap<Object, List<Object>>();
155 metricDistance = new PartialInterpretationMetricDistance(domain);
156
157 //set whether allows must violations during the realistic generation
158 allowMustViolation = configuration.allowMustViolations;
159 targetSize = configuration.typeScopes.maxNewElements + 2;
160 //this.numericSolver = new NumericSolver(method, this.configuration.runIntermediateNumericalConsistencyChecks, false);
161 }
162
163 @Override
164 public void explore() {
165 this.explorationStarted=System.nanoTime();
166 if (!checkGlobalConstraints()) {
167 logger.info("Global contraint is not satisifed in the first state. Terminate.");
168 return;
100 } 169 }
101 public int getNumberOfStatecoderFail() { 170 if (configuration.searchSpaceConstraints.maxDepth == 0) {
102 return numberOfStatecoderFail; 171 logger.info("Maximal depth is reached in the initial solution. Terminate.");
172 return;
103 } 173 }
104
105 @Override
106 public void initStrategy(ThreadContext context) {
107 this.context = context;
108 this.solutionStore = context.getGlobalContext().getSolutionStore();
109 domain = Domain.valueOf(configuration.domain);
110
111 ViatraQueryEngine engine = context.getQueryEngine();
112// // TODO: visualisation
113 mustMatchers = new LinkedList<ViatraQueryMatcher<? extends IPatternMatch>>();
114 mayMatchers = new LinkedList<ViatraQueryMatcher<? extends IPatternMatch>>();
115
116 // manully restict the number of super types of one class
117 this.method.getInvalidWF().forEach(a ->{
118 ViatraQueryMatcher<? extends IPatternMatch> matcher = a.getMatcher(engine);
119 mustMatchers.add(matcher);
120 });
121
122 this.method.getUnfinishedWF().forEach(a ->{
123 ViatraQueryMatcher<? extends IPatternMatch> matcher = a.getMatcher(engine);
124 mayMatchers.add(matcher);
125 });
126 174
127 175 final Fitness firstFittness = context.calculateFitness();
128 //set up comparator 176
129 final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper(); 177 //final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper();
130 this.comparator = new Comparator<TrajectoryWithFitness>() { 178 final Object[] firstTrajectory = context.getTrajectory().toArray(new Object[0]);
131 @Override 179 TrajectoryWithFitness currentTrajectoryWithFittness = new TrajectoryWithFitness(firstTrajectory, firstFittness);
132 public int compare(TrajectoryWithFitness o1, TrajectoryWithFitness o2) { 180 trajectoiresToExplore.add(currentTrajectoryWithFittness);
133 return objectiveComparatorHelper.compare(o2.fitness, o1.fitness); 181 Object lastState = null;
182
183 //if(configuration)
184 visualiseCurrentState();
185 // the two is the True and False node generated at the beginning of the generation
186 int count = 0;
187 mainLoop: while (!isInterrupted && !configuration.progressMonitor.isCancelled()) {
188
189 if (currentTrajectoryWithFittness == null) {
190 if (trajectoiresToExplore.isEmpty()) {
191 logger.debug("State space is fully traversed.");
192 return;
193 } else {
194 currentTrajectoryWithFittness = selectState();
195 if (logger.isDebugEnabled()) {
196 logger.debug("Current trajectory: " + Arrays.toString(context.getTrajectory().toArray()));
197 logger.debug("New trajectory is chosen: " + currentTrajectoryWithFittness);
198 }
199 context.getDesignSpaceManager().executeTrajectoryWithMinimalBacktrackWithoutStateCoding(currentTrajectoryWithFittness.trajectory);
200
201 // reset the regression for this trajectory
202 metricDistance.getLinearModel().resetRegression(context.getCurrentStateId());
134 } 203 }
135 }; 204 }
136 205
137 this.solutionStoreWithCopy = new SolutionStoreWithCopy(); 206 List<Object> activationIds = selectActivation();
138 this.solutionStoreWithDiversityDescriptor = new SolutionStoreWithDiversityDescriptor(configuration.diversityRequirement); 207 PartialInterpretation model = (PartialInterpretation) context.getModel();
208 System.out.println(model.getNewElements().size());
209 System.out.println("# violations: " + getNumberOfViolations(mayMatchers));
139 210
140 trajectoiresToExplore = new PriorityQueue<TrajectoryWithFitness>(11, comparator); 211 Map<Object, Double> valueMap = new HashMap<Object,Double>();
141 stateAndActivations = new HashMap<Object, List<Object>>();
142 metricDistance = new PartialInterpretationMetricDistance(domain);
143 212
144 //set whether allows must violations during the realistic generation 213 //init epsilon and draw
145 allowMustViolation = configuration.allowMustViolations; 214 MetricDistanceGroup heuristics = metricDistance.calculateMetricDistanceKS(model);
146 targetSize = configuration.typeScopes.maxNewElements + 2;
147 }
148 215
149 @Override 216 if(!stateAndActivations.containsKey(context.getCurrentStateId())) {
150 public void explore() { 217 stateAndActivations.put(context.getCurrentStateId(), new ArrayList<Object>());
151 if (!context.checkGlobalConstraints()) {
152 logger.info("Global contraint is not satisifed in the first state. Terminate.");
153 return;
154 }
155 if (configuration.searchSpaceConstraints.maxDepth == 0) {
156 logger.info("Maximal depth is reached in the initial solution. Terminate.");
157 return;
158 } 218 }
159 219
160 final Fitness firstFittness = context.calculateFitness(); 220 // calculate values for epsilon greedy
161 221 double epsilon = 1.0/count;
162 //final ObjectiveComparatorHelper objectiveComparatorHelper = context.getObjectiveComparatorHelper(); 222 double draw = Math.random();
163 final Object[] firstTrajectory = context.getTrajectory().toArray(new Object[0]); 223 count++;
164 TrajectoryWithFitness currentTrajectoryWithFittness = new TrajectoryWithFitness(firstTrajectory, firstFittness); 224 this.currentNodeTypeDistance = heuristics.getNodeTypeDistance();
165 trajectoiresToExplore.add(currentTrajectoryWithFittness); 225 numNodesToGenerate = model.getMaxNewElements();
166 Object lastState = null; 226 System.out.println("NA distance: " + heuristics.getNADistance());
167 227 System.out.println("MPC distance: " + heuristics.getMPCDistance());
168 //if(configuration) 228 System.out.println("Out degree distance:" + heuristics.getOutDegreeDistance());
169 visualiseCurrentState(); 229 System.out.println("NodeType :" + currentNodeTypeDistance);
170 // the two is the True and False node generated at the beginning of the generation
171 int count = 0;
172 mainLoop: while (!isInterrupted && !configuration.progressMonitor.isCancelled()) {
173 230
174 if (currentTrajectoryWithFittness == null) {
175 if (trajectoiresToExplore.isEmpty()) {
176 logger.debug("State space is fully traversed.");
177 return;
178 } else {
179 currentTrajectoryWithFittness = selectState();
180 if (logger.isDebugEnabled()) {
181 logger.debug("Current trajectory: " + Arrays.toString(context.getTrajectory().toArray()));
182 logger.debug("New trajectory is chosen: " + currentTrajectoryWithFittness);
183 }
184 context.getDesignSpaceManager().executeTrajectoryWithMinimalBacktrackWithoutStateCoding(currentTrajectoryWithFittness.trajectory);
185
186 // reset the regression for this trajectory
187 metricDistance.getLinearModel().resetRegression(context.getCurrentStateId());
188 }
189 }
190
191 List<Object> activationIds = selectActivation();
192 PartialInterpretation model = (PartialInterpretation) context.getModel();
193// System.out.println(model.getNewElements().size());
194// System.out.println("# violations: " + getNumberOfViolations(mayMatchers));
195
196 Map<Object, Double> valueMap = new HashMap<Object,Double>();
197
198 //init epsilon and draw
199 MetricDistanceGroup heuristics = metricDistance.calculateMetricDistanceKS(model);
200 231
201 if(!stateAndActivations.containsKey(context.getCurrentStateId())) { 232 //TODO: the number of activations to be checked should be configurasble
202 stateAndActivations.put(context.getCurrentStateId(), new ArrayList<Object>()); 233 if(activationIds.size() > 50) {
203 } 234 activationIds = activationIds.subList(0, 50);
235 }
236
237 valueMap = sortWithWeight(activationIds);
238 lastState = context.getCurrentStateId();
239 while (!isInterrupted && !configuration.progressMonitor.isCancelled() && activationIds.size() > 0) {
240 final Object nextActivation = drawWithEpsilonProbabilty(activationIds, valueMap, epsilon, draw);
241
242 stateAndActivations.get(context.getCurrentStateId()).add(nextActivation);
243 logger.debug("Executing new activation: " + nextActivation);
244 context.executeAcitvationId(nextActivation);
245 visualiseCurrentState();
246 boolean consistencyCheckResult = checkConsistency(currentTrajectoryWithFittness);
247 if(consistencyCheckResult == true) { continue mainLoop; }
204 248
205 // calculate values for epsilon greedy 249// if (context.isCurrentStateAlreadyTraversed()) {
206 double epsilon = 1.0/count; 250// logger.info("The new state is already visited.");
207 double draw = Math.random(); 251// context.backtrack();
208 count++; 252// } else if (!checkGlobalConstraints()) {
209 this.currentNodeTypeDistance = heuristics.getNodeTypeDistance(); 253// logger.debug("Global contraint is not satisifed.");
210 numNodesToGenerate = model.getMaxNewElements(); 254// context.backtrack();
211// System.out.println("NA distance: " + heuristics.getNADistance()); 255// }
212// System.out.println("MPC distance: " + heuristics.getMPCDistance());
213// System.out.println("Out degree distance:" + heuristics.getOutDegreeDistance());
214// System.out.println("NodeType :" + currentNodeTypeDistance);
215
216
217 //TODO: the number of activations to be checked should be configurasble
218 if(activationIds.size() > 50) {
219 activationIds = activationIds.subList(0, 50);
220 }
221 256
222 valueMap = sortWithWeight(activationIds); 257 int currentSize = model.getNewElements().size();
223 lastState = context.getCurrentStateId(); 258 int targetDiff = targetSize - currentSize;
224 while (!isInterrupted && !configuration.progressMonitor.isCancelled() && activationIds.size() > 0) { 259 boolean shouldFinish = currentSize >= targetSize;
225 final Object nextActivation = drawWithEpsilonProbabilty(activationIds, valueMap, epsilon, draw); 260
226 261 // does not allow must violations
227 stateAndActivations.get(context.getCurrentStateId()).add(nextActivation); 262 if((getNumberOfViolations(mustMatchers) > 0|| getNumberOfViolations(mayMatchers) > targetDiff) && !allowMustViolation && !shouldFinish) {
228 logger.debug("Executing new activation: " + nextActivation); 263 context.backtrack();
229 context.executeAcitvationId(nextActivation); 264 }else {
230 visualiseCurrentState(); 265 final Fitness nextFitness = context.calculateFitness();
231 boolean consistencyCheckResult = checkConsistency(currentTrajectoryWithFittness);
232 if(consistencyCheckResult == true) { continue mainLoop; }
233
234 int currentSize = model.getNewElements().size();
235 int targetDiff = targetSize - currentSize;
236 boolean shouldFinish = currentSize >= targetSize;
237 266
238 // does not allow must violations 267 // the only hard objectives are configured in the config file
239 if((getNumberOfViolations(mustMatchers) > 0|| getNumberOfViolations(mayMatchers) > targetDiff) && !allowMustViolation && !shouldFinish) { 268 checkForSolution(nextFitness);
269
270 if (context.getDepth() > configuration.searchSpaceConstraints.maxDepth) {
271 logger.debug("Reached max depth.");
240 context.backtrack(); 272 context.backtrack();
241 }else { 273 continue;
242 final Fitness nextFitness = context.calculateFitness();
243
244 // the only hard objectives are configured in the config file
245 checkForSolution(nextFitness);
246
247 if (context.getDepth() > configuration.searchSpaceConstraints.maxDepth) {
248 logger.debug("Reached max depth.");
249 context.backtrack();
250 continue;
251 }
252
253 //Record value for current trajectory
254 TrajectoryWithFitness nextTrajectoryWithFittness = new TrajectoryWithFitness(
255 context.getTrajectory().toArray(), nextFitness);
256 int nodeSize = ((PartialInterpretation) context.getModel()).getNewElements().size();
257 int violation = getNumberOfViolations(mayMatchers);
258 double currentValue = calculateCurrentStateValue(nodeSize, violation);
259 metricDistance.getLinearModel().feedData(context.getCurrentStateId(), metricDistance.calculateFeature(nodeSize, violation), currentValue, lastState);
260 trajectoiresToExplore.add(nextTrajectoryWithFittness);
261 currentStateValue = currentValue;
262 //Currently, just go to the next state without considering the value of trajectory
263 currentTrajectoryWithFittness = nextTrajectoryWithFittness;
264 continue mainLoop;
265
266 } 274 }
275
276 //Record value for current trajectory
277 TrajectoryWithFitness nextTrajectoryWithFittness = new TrajectoryWithFitness(
278 context.getTrajectory().toArray(), nextFitness);
279 int nodeSize = ((PartialInterpretation) context.getModel()).getNewElements().size();
280 int violation = getNumberOfViolations(mayMatchers);
281 double currentValue = calculateCurrentStateValue(nodeSize, violation);
282 metricDistance.getLinearModel().feedData(context.getCurrentStateId(), metricDistance.calculateFeature(nodeSize, violation), currentValue, lastState);
283 trajectoiresToExplore.add(nextTrajectoryWithFittness);
284 currentStateValue = currentValue;
285 //Currently, just go to the next state without considering the value of trajectory
286 currentTrajectoryWithFittness = nextTrajectoryWithFittness;
287 continue mainLoop;
288
267 } 289 }
268 logger.debug("State is fully traversed.");
269 trajectoiresToExplore.remove(currentTrajectoryWithFittness);
270 currentTrajectoryWithFittness = null;
271 context.backtrack();
272 } 290 }
273 logger.info("Interrupted."); 291 logger.debug("State is fully traversed.");
292 trajectoiresToExplore.remove(currentTrajectoryWithFittness);
293 currentTrajectoryWithFittness = null;
294 context.backtrack();
274 } 295 }
296 logger.info("Interrupted.");
297 }
275 298
276 /** 299 private boolean checkGlobalConstraints() {
277 * 300 long start = System.nanoTime();
278 * @param activationIds 301 boolean result = context.checkGlobalConstraints();
279 * @return: activation to value map 302 globalConstraintEvaluationTime += System.nanoTime() - start;
280 */ 303 return result;
281 private Map<Object, Double> sortWithWeight(List<Object> activationIds){ 304 }
282 Map<Object, Double> valueMap = new HashMap<Object, Double>(); 305
283 Object currentId = context.getCurrentStateId(); 306 private Fitness calculateFitness() {
284 // check for next states 307 long start = System.nanoTime();
285 for(Object id : activationIds) { 308 Fitness fitness = context.calculateFitness();
286 context.executeAcitvationId(id); 309 fitnessCalculationTime += System.nanoTime() - start;
287 int violation = getNumberOfViolations(mayMatchers); 310 return fitness;
311 }
312
313 /**
314 *
315 * @param activationIds
316 * @return: activation to value map
317 */
318 private Map<Object, Double> sortWithWeight(List<Object> activationIds){
319 Map<Object, Double> valueMap = new HashMap<Object, Double>();
320 Object currentId = context.getCurrentStateId();
321 // check for next states
322 for(Object id : activationIds) {
323 context.executeAcitvationId(id);
324 int violation = getNumberOfViolations(mayMatchers);
288 325
289 if(!allowMustViolation && getNumberOfViolations(mustMatchers) > 0) { 326 if(!allowMustViolation && getNumberOfViolations(mustMatchers) > 0) {
290 valueMap.put(id, Double.MAX_VALUE); 327 valueMap.put(id, Double.MAX_VALUE);
291 stateAndActivations.get(currentId).add(id); 328 stateAndActivations.get(currentId).add(id);
292 }else { 329 }else {
293 valueMap.put(id, calculateFutureStateValue(violation)); 330 valueMap.put(id, calculateFutureStateValue(violation));
294 }
295
296
297
298 context.backtrack();
299 } 331 }
332
333
300 334
301 //remove all the elements having large distance 335 context.backtrack();
302 Collections.sort(activationIds, Comparator.comparing(li -> valueMap.get(li)));
303 return valueMap;
304 } 336 }
305 337
306 private double calculateFutureStateValue(int violation) { 338 //remove all the elements having large distance
307 long start = System.nanoTime(); 339 Collections.sort(activationIds, Comparator.comparing(li -> valueMap.get(li)));
308 int nodeSize = ((PartialInterpretation) context.getModel()).getNewElements().size(); 340 return valueMap;
309 double currentValue = calculateCurrentStateValue(nodeSize,violation); 341 }
310 double[] toPredict = metricDistance.calculateFeature(100, violation); 342
311 if(Math.abs(currentValue - currentStateValue) < 0.001) { 343 private double calculateFutureStateValue(int violation) {
312 this.method.getStatistics().addMetricCalculationTime(System.nanoTime() - start); 344 long start = System.nanoTime();
313 return Double.MAX_VALUE; 345 int nodeSize = ((PartialInterpretation) context.getModel()).getNewElements().size();
314 } 346 double currentValue = calculateCurrentStateValue(nodeSize,violation);
315 try { 347 double[] toPredict = metricDistance.calculateFeature(100, violation);
316 this.method.getStatistics().addMetricCalculationTime(System.nanoTime() - start); 348 if(Math.abs(currentValue - currentStateValue) < 0.001) {
317 return metricDistance.getLinearModel().getPredictionForNextDataSample(metricDistance.calculateFeature(nodeSize, violation), currentValue, toPredict); 349 this.method.getStatistics().addMetricCalculationTime(System.nanoTime() - start);
318 }catch(IllegalArgumentException e) { 350 return Double.MAX_VALUE;
319 this.method.getStatistics().addMetricCalculationTime(System.nanoTime() - start); 351 }
320 return currentValue; 352 try {
321 } 353 this.method.getStatistics().addMetricCalculationTime(System.nanoTime() - start);
322 354 return metricDistance.getLinearModel().getPredictionForNextDataSample(metricDistance.calculateFeature(nodeSize, violation), currentValue, toPredict);
355 }catch(IllegalArgumentException e) {
356 this.method.getStatistics().addMetricCalculationTime(System.nanoTime() - start);
357 return currentValue;
323 } 358 }
324 private double calculateCurrentStateValue(int factor, int violation) {
325 PartialInterpretation model = (PartialInterpretation) context.getModel();
326 MetricDistanceGroup g = metricDistance.calculateMetricDistanceKS(model);
327 if(configuration.realisticGuidance == RealisticGuidance.MPC) {
328 return g.getMPCDistance();
329 }else if(configuration.realisticGuidance == RealisticGuidance.NodeActivity) {
330 return g.getNADistance();
331 }else if(configuration.realisticGuidance == RealisticGuidance.OutDegree) {
332 return g.getOutDegreeDistance();
333 }else if(configuration.realisticGuidance == RealisticGuidance.NodeType) {
334 return g.getNodeTypeDistance();
335 }else if(configuration.realisticGuidance == RealisticGuidance.Composite) {
336 double consistenceWeights = 5 * factor / (configuration.typeScopes.maxNewElements + 2) * (1- 1.0/(1+violation));
337 if(domain == Domain.Yakindumm) {
338 double unfinishFactor = 50 * (1 - (double)factor / targetSize);
339 double nodeTypeFactor = g.getNodeTypeDistance();
340 double normalFactor = 5;
341 if(currentNodeTypeDistance <= 0.05 || numNodesToGenerate == 1) {
342 nodeTypeFactor = 0;
343 normalFactor = 100;
344 unfinishFactor = 0;
345 }
346
347 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + normalFactor / 5*consistenceWeights + unfinishFactor;
348 }else if (domain == Domain.Ecore) {
349 double unfinishFactor = 100 * (1 - (double)factor / targetSize);
350 double nodeTypeFactor = g.getNodeTypeDistance();
351 double normalFactor = 5;
352 if(currentNodeTypeDistance <= 0.12 || numNodesToGenerate == 1) {
353 nodeTypeFactor = 0;
354 normalFactor = 100;
355 unfinishFactor *= 0.5;
356 }
357
358 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + normalFactor / 5*consistenceWeights + unfinishFactor;
359 }else {
360 double unfinishFactor = context.calculateFitness().get("CompositeUnfinishednessObjective");
361 double nodeTypeFactor = g.getNodeTypeDistance();
362 double normalFactor = 5;
363 if(currentNodeTypeDistance <= 0.05 || numNodesToGenerate == 1) {
364 nodeTypeFactor = 0;
365 normalFactor = 100;
366 //unfinishFactor *= 0.5;
367 }
368
369 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + 2*g.getMPCDistance() + 2*g.getOutDegreeDistance()) + normalFactor / 5*consistenceWeights + unfinishFactor;
370 }
371 359
372 }else if(configuration.realisticGuidance == RealisticGuidance.Composite_Without_Violations) { 360 }
373 if(domain == Domain.Yakindumm) { 361 private double calculateCurrentStateValue(int factor, int violation) {
374 double unfinishFactor = 50 * (1 - (double)factor / targetSize); 362 PartialInterpretation model = (PartialInterpretation) context.getModel();
375 double nodeTypeFactor = g.getNodeTypeDistance(); 363 MetricDistanceGroup g = metricDistance.calculateMetricDistanceKS(model);
376 double normalFactor = 5; 364 if(configuration.realisticGuidance == RealisticGuidance.MPC) {
377 if(currentNodeTypeDistance <= 0.05 || numNodesToGenerate == 1) { 365 return g.getMPCDistance();
378 nodeTypeFactor = 0; 366 }else if(configuration.realisticGuidance == RealisticGuidance.NodeActivity) {
379 normalFactor = 100; 367 return g.getNADistance();
380 unfinishFactor = 0; 368 }else if(configuration.realisticGuidance == RealisticGuidance.OutDegree) {
381 } 369 return g.getOutDegreeDistance();
382 370 }else if(configuration.realisticGuidance == RealisticGuidance.NodeType) {
383 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + unfinishFactor; 371 return g.getNodeTypeDistance();
384 }else if (domain == Domain.Github) { 372 }else if(configuration.realisticGuidance == RealisticGuidance.Composite) {
385 double unfinishFactor = 100 * (1 - (double)factor / targetSize); 373 double consistenceWeights = 5 * factor / (configuration.typeScopes.maxNewElements + 2) * (1- 1.0/(1+violation));
386 double nodeTypeFactor = g.getNodeTypeDistance(); 374 if(domain == Domain.Yakindumm) {
387 double normalFactor = 5; 375 double unfinishFactor = 50 * (1 - (double)factor / targetSize);
388 if(currentNodeTypeDistance <= 0.12 || numNodesToGenerate == 1) { 376 double nodeTypeFactor = g.getNodeTypeDistance();
389 nodeTypeFactor = 0; 377 double normalFactor = 5;
390 normalFactor = 100; 378 if(currentNodeTypeDistance <= 0.05 || numNodesToGenerate == 1) {
391 unfinishFactor *= 0.5; 379 nodeTypeFactor = 0;
392 } 380 normalFactor = 100;
393 381 unfinishFactor = 0;
394 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + unfinishFactor;
395 } else {
396 double unfinishFactor = 100 * (1 - (double)factor / targetSize);
397 double nodeTypeFactor = g.getNodeTypeDistance();
398 double normalFactor = 5;
399 if(currentNodeTypeDistance <= 0.20 || numNodesToGenerate == 1) {
400 nodeTypeFactor = 0;
401 normalFactor = 100;
402 unfinishFactor *= 0.5;
403 }
404
405 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + unfinishFactor;
406 } 382 }
383
384 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + normalFactor / 5*consistenceWeights + unfinishFactor;
385 }else if (domain == Domain.Ecore) {
386 double unfinishFactor = 100 * (1 - (double)factor / targetSize);
387 double nodeTypeFactor = g.getNodeTypeDistance();
388 double normalFactor = 5;
389 if(currentNodeTypeDistance <= 0.12 || numNodesToGenerate == 1) {
390 nodeTypeFactor = 0;
391 normalFactor = 100;
392 unfinishFactor *= 0.5;
393 }
394
395 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + normalFactor / 5*consistenceWeights + unfinishFactor;
407 }else { 396 }else {
408 return violation; 397 double unfinishFactor = context.calculateFitness().get("CompositeUnfinishednessObjective");
409 } 398 double nodeTypeFactor = g.getNodeTypeDistance();
410 } 399 double normalFactor = 5;
411 400 if(currentNodeTypeDistance <= 0.05 || numNodesToGenerate == 1) {
412 private int getNumberOfViolations(Collection<ViatraQueryMatcher<? extends IPatternMatch>> matchers) { 401 nodeTypeFactor = 0;
413 int violations = matchers.stream().mapToInt(m -> m.countMatches()).sum(); 402 normalFactor = 100;
414 403 //unfinishFactor *= 0.5;
415 return violations; 404 }
416 } 405
417 406 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + 2*g.getMPCDistance() + 2*g.getOutDegreeDistance()) + normalFactor / 5*consistenceWeights + unfinishFactor;
418 // Modified epsilon greedy choose for action based on value function
419 // with probability epsilon, choose the state with probability based on the weight
420 // with probability 1 - epsilon, choose the best state
421 // epsilon should decay w.r.t. time
422 private Object drawWithEpsilonProbabilty(List<Object> activationIds, Map<Object, Double> valueMap, double epsilon, double currentDraw) {
423 if(activationIds.size() <= 0) {
424 return null;
425 } 407 }
426 408
427 // if epsilon is smaller than current draw, return greedy choice 409 }else if(configuration.realisticGuidance == RealisticGuidance.Composite_Without_Violations) {
428 if(epsilon < currentDraw) { 410 if(domain == Domain.Yakindumm) {
429 return activationIds.remove(0); 411 double unfinishFactor = 50 * (1 - (double)factor / targetSize);
430 }else { 412 double nodeTypeFactor = g.getNodeTypeDistance();
431 //else return draw with probability of the weights 413 double normalFactor = 5;
432 //find the sum of all 1-weights: the smaller the better 414 if(currentNodeTypeDistance <= 0.05 || numNodesToGenerate == 1) {
433 double sum = valueMap.values().stream().mapToDouble(d->1).sum(); 415 nodeTypeFactor = 0;
434 double rand = Math.random() * sum; 416 normalFactor = 100;
435 double iterator = 0.0; 417 unfinishFactor = 0;
436 Object idToReturn = null; 418 }
437 419
438 // draw an item with probability 420 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + unfinishFactor;
439 for(Object o : valueMap.keySet()) { 421 }else if (domain == Domain.Github) {
440 iterator += (1); 422 double unfinishFactor = 100 * (1 - (double)factor / targetSize);
441 if(rand < iterator) { 423 double nodeTypeFactor = g.getNodeTypeDistance();
442 idToReturn = o; 424 double normalFactor = 5;
443 break; 425 if(currentNodeTypeDistance <= 0.12 || numNodesToGenerate == 1) {
444 } 426 nodeTypeFactor = 0;
427 normalFactor = 100;
428 unfinishFactor *= 0.5;
429 }
430
431 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + unfinishFactor;
432 } else {
433 double unfinishFactor = 100 * (1 - (double)factor / targetSize);
434 double nodeTypeFactor = g.getNodeTypeDistance();
435 double normalFactor = 5;
436 if(currentNodeTypeDistance <= 0.20 || numNodesToGenerate == 1) {
437 nodeTypeFactor = 0;
438 normalFactor = 100;
439 unfinishFactor *= 0.5;
445 } 440 }
446 441
447 //delete the item from the list 442 return 100*(nodeTypeFactor) + normalFactor*(2*g.getNADistance() + g.getMPCDistance() + 2*g.getOutDegreeDistance()) + unfinishFactor;
448 activationIds.remove(idToReturn);
449 valueMap.remove(idToReturn);
450 return idToReturn;
451 } 443 }
444 }else {
445 return violation;
452 } 446 }
447 }
448
449 private int getNumberOfViolations(Collection<ViatraQueryMatcher<? extends IPatternMatch>> matchers) {
450 int violations = matchers.stream().mapToInt(m -> m.countMatches()).sum();
453 451
454 private List<Object> selectActivation() { 452 return violations;
455 List<Object> activationIds; 453 }
456 try { 454
457 activationIds = new ArrayList<Object>(context.getCurrentActivationIds()); 455 // Modified epsilon greedy choose for action based on value function
458 if(stateAndActivations.containsKey(context.getCurrentStateId())) { 456 // with probability epsilon, choose the state with probability based on the weight
459 activationIds.removeAll(stateAndActivations.get(context.getCurrentStateId())); 457 // with probability 1 - epsilon, choose the best state
458 // epsilon should decay w.r.t. time
459 private Object drawWithEpsilonProbabilty(List<Object> activationIds, Map<Object, Double> valueMap, double epsilon, double currentDraw) {
460 if(activationIds.size() <= 0) {
461 return null;
462 }
463
464 // if epsilon is smaller than current draw, return greedy choice
465 if(epsilon < currentDraw) {
466 return activationIds.remove(0);
467 }else {
468 //else return draw with probability of the weights
469 //find the sum of all 1-weights: the smaller the better
470 double sum = valueMap.values().stream().mapToDouble(d->1).sum();
471 double rand = Math.random() * sum;
472 double iterator = 0.0;
473 Object idToReturn = null;
474
475 // draw an item with probability
476 for(Object o : valueMap.keySet()) {
477 iterator += (1);
478 if(rand < iterator) {
479 idToReturn = o;
480 break;
460 } 481 }
461 Collections.shuffle(activationIds);
462 } catch (NullPointerException e) {
463 numberOfStatecoderFail++;
464 activationIds = Collections.emptyList();
465 } 482 }
466 return activationIds; 483
484 //delete the item from the list
485 activationIds.remove(idToReturn);
486 valueMap.remove(idToReturn);
487 return idToReturn;
467 } 488 }
489 }
490
491 private List<Object> selectActivation() {
492 List<Object> activationIds;
493 try {
494 activationIds = this.activationSelector.randomizeActivationIDs(context.getUntraversedActivationIds());
495 } catch (NullPointerException e) {
496 numberOfStatecoderFail++;
497 activationIds = Collections.emptyList();
498 }
499 return activationIds;
500 }
468 501
469 private void checkForSolution(final Fitness fittness) { 502 private void checkForSolution(final Fitness fittness) {
470 if (fittness.isSatisifiesHardObjectives()) { 503 if (fittness.isSatisifiesHardObjectives()) {
471 logger.debug("Solution Found!!"); 504 logger.debug("Solution Found!!");
472 logger.debug("# violations: " + (getNumberOfViolations(mustMatchers))); 505 logger.debug("# violations: " + (getNumberOfViolations(mustMatchers)));
473 if (solutionStoreWithDiversityDescriptor.isDifferent(context)) { 506 if (solutionStoreWithDiversityDescriptor.isDifferent(context)) {
474 solutionStoreWithCopy.newSolution(context); 507 solutionStoreWithCopy.newSolution(context);
475 solutionStoreWithDiversityDescriptor.newSolution(context); 508 solutionStoreWithDiversityDescriptor.newSolution(context);
476 solutionStore.newSolution(context); 509 solutionStore.newSolution(context);
477 configuration.progressMonitor.workedModelFound(configuration.solutionScope.numberOfRequiredSolution); 510 configuration.progressMonitor.workedModelFound(configuration.solutionScope.numberOfRequiredSolutions);
478 511
479 logger.debug("Found a solution."); 512 logger.debug("Found a solution.");
480 }
481 } 513 }
482 } 514 }
515 }
516
517 public List<String> times = new LinkedList<String>();
518 private void saveTimes() {
519 long forwardTime = context.getDesignSpaceManager().getForwardTime()/1000000;
520 long backtrackingTime = context.getDesignSpaceManager().getBacktrackingTime()/1000000;
521 long statecoderTime = ((NeighbourhoodBasedPartialInterpretationStateCoder)this.context.getStateCoder()).getStatecoderRuntime()/1000000;
522 long solutionCopy = solutionStoreWithCopy.getSumRuntime()/1000000;
523 long activationSelection = this.activationSelector.getRuntime()/1000000;
524// long numericalSolverSumTime = this.numericSolver.getRuntime()/1000000;
525// long numericalSolverProblemForming = this.numericSolver.getSolverSolvingProblem()/1000000;
526// long numericalSolverSolving = this.numericSolver.getSolverSolvingProblem()/1000000;
527// long numericalSolverInterpreting = this.numericSolver.getSolverSolution()/1000000;
528 long metricCalculationTime = this.method.getStatistics().metricCalculationTime / 1000000;
529 this.times.add(
530 "(TransformationExecutionTime"+method.getStatistics().transformationExecutionTime/1000000+
531 "|ForwardTime:"+forwardTime+
532 "|Backtrackingtime:"+backtrackingTime+
533 "|StateCoderTime:"+statecoderTime+
534 "|SolutionCopyTime:"+solutionCopy+
535 "|ActivationSelectionTime:"+activationSelection+
536 //"|NumericalSolverSumTime:"+numericalSolverSumTime+
537 //"|NumericalSolverProblemFormingTime:"+numericalSolverProblemForming+
538 //"|NumericalSolverSolvingTime:"+numericalSolverSolving+
539 //"|NumericalSolverInterpretingSolution:"+numericalSolverInterpreting+
540 "|MetricCalculationTime:"+metricCalculationTime + ")"
541 );
542
543 }
483 544
484 @Override 545 @Override
485 public void interruptStrategy() { 546 public void interruptStrategy() {
486 isInterrupted = true; 547 isInterrupted = true;
487 } 548 }
488 549
489 550
490 private TrajectoryWithFitness selectState() { 551 private TrajectoryWithFitness selectState() {
491 int randomNumber = random.nextInt(configuration.randomBacktrackChance); 552 int randomNumber = random.nextInt(configuration.randomBacktrackChance);
492 if (randomNumber == 0) { 553 if (randomNumber == 0) {
493 int elements = trajectoiresToExplore.size(); 554 int elements = trajectoiresToExplore.size();
494 int randomElementIndex = random.nextInt(elements); 555 int randomElementIndex = random.nextInt(elements);
495 logger.debug("Randomly backtract to the " + randomElementIndex + " best solution..."); 556 logger.debug("Randomly backtract to the " + randomElementIndex + " best solution...");
496 Iterator<TrajectoryWithFitness> iterator = trajectoiresToExplore.iterator(); 557 Iterator<TrajectoryWithFitness> iterator = trajectoiresToExplore.iterator();
497 while (randomElementIndex != 0) { 558 while (randomElementIndex != 0) {
498 iterator.next(); 559 iterator.next();
499 randomElementIndex--; 560 randomElementIndex--;
500 } 561 }
501 TrajectoryWithFitness res = iterator.next(); 562 TrajectoryWithFitness res = iterator.next();
502 if (res == null) { 563 if (res == null) {
503 return trajectoiresToExplore.element();
504 } else {
505 return res;
506 }
507 } else {
508 return trajectoiresToExplore.element(); 564 return trajectoiresToExplore.element();
565 } else {
566 return res;
509 } 567 }
510 } 568 } else {
511 569 return trajectoiresToExplore.element();
570 }
571 }
572
512// private void logCurrentStateMetric() { 573// private void logCurrentStateMetric() {
513// if(this.configuration.documentationLevel != DocumentationLevel.NONE || workspace == null) { 574// if(this.configuration.documentationLevel != DocumentationLevel.NONE || workspace == null) {
514// return; 575// return;
@@ -518,77 +579,80 @@ public class HillClimbingOnRealisticMetricStrategyForModelGeneration implements
518// PartialInterpretationMetric.calculateMetric(interpretation, "debug/metric/" + context.getModel().hashCode(), context.getCurrentStateId().toString()); 579// PartialInterpretationMetric.calculateMetric(interpretation, "debug/metric/" + context.getModel().hashCode(), context.getCurrentStateId().toString());
519// } 580// }
520 581
521 public void visualiseCurrentState() { 582 public void visualiseCurrentState() {
522 PartialInterpretationVisualiser partialInterpretatioVisualiser = configuration.debugCongiguration.partialInterpretatioVisualiser; 583 PartialInterpretationVisualiser partialInterpretatioVisualiser = configuration.debugConfiguration.partialInterpretatioVisualiser;
523 if(partialInterpretatioVisualiser != null && this.configuration.documentationLevel == DocumentationLevel.FULL && workspace != null) { 584 if(partialInterpretatioVisualiser != null && this.configuration.documentationLevel == DocumentationLevel.FULL && workspace != null) {
524 PartialInterpretation p = (PartialInterpretation) (context.getModel()); 585 PartialInterpretation p = (PartialInterpretation) (context.getModel());
525 int id = ++numberOfPrintedModel; 586 int id = ++numberOfPrintedModel;
526 if (id % configuration.debugCongiguration.partalInterpretationVisualisationFrequency == 0) { 587 if (id % configuration.debugConfiguration.partalInterpretationVisualisationFrequency == 0) {
527 PartialInterpretationVisualisation visualisation = partialInterpretatioVisualiser.visualiseConcretization(p); 588 PartialInterpretationVisualisation visualisation = partialInterpretatioVisualiser.visualiseConcretization(p);
528 visualisation.writeToFile(workspace, String.format("state%09d.png", id)); 589 logger.debug("Visualizing state: " + id + " (" + context.getDesignSpaceManager().getCurrentState() + ")");
529 } 590 String name = String.format("state%09d", id);
591 visualisation.writeToFile(workspace, name + ".png");
592 workspace.writeModel((EObject) context.getModel(), name + ".xmi");
530 } 593 }
531 } 594 }
595 }
532 596
533 protected boolean checkConsistency(TrajectoryWithFitness t) { 597 protected boolean checkConsistency(TrajectoryWithFitness t) {
534 LogicReasoner internalIncosnsitencyDetector = configuration.internalConsistencyCheckerConfiguration.internalIncosnsitencyDetector; 598 LogicReasoner internalIncosnsitencyDetector = configuration.internalConsistencyCheckerConfiguration.internalIncosnsitencyDetector;
535 if (internalIncosnsitencyDetector!= null) { 599 if (internalIncosnsitencyDetector!= null) {
536 int id = ++numberOfSolverCalls; 600 int id = ++numberOfSolverCalls;
537 if (id % configuration.internalConsistencyCheckerConfiguration.incternalConsistencyCheckingFrequency == 0) { 601 if (id % configuration.internalConsistencyCheckerConfiguration.incternalConsistencyCheckingFrequency == 0) {
538 try { 602 try {
539 PartialInterpretation interpretation = (PartialInterpretation) (context.getModel()); 603 PartialInterpretation interpretation = (PartialInterpretation) (context.getModel());
540 PartialInterpretation copied = EcoreUtil.copy(interpretation); 604 PartialInterpretation copied = EcoreUtil.copy(interpretation);
541 this.partialInterpretation2Logic.transformPartialIntepretation2Logic(copied.getProblem(), copied); 605 this.partialInterpretation2Logic.transformPartialIntepretation2Logic(copied.getProblem(), copied);
542 LogicProblem newProblem = copied.getProblem(); 606 LogicProblem newProblem = copied.getProblem();
543 607
544 this.configuration.typeScopes.maxNewElements = interpretation.getMaxNewElements(); 608 this.configuration.typeScopes.maxNewElements = interpretation.getMaxNewElements();
545 this.configuration.typeScopes.minNewElements = interpretation.getMinNewElements(); 609 this.configuration.typeScopes.minNewElements = interpretation.getMinNewElements();
546 LogicResult result = internalIncosnsitencyDetector.solve(newProblem, configuration, workspace); 610 LogicResult result = internalIncosnsitencyDetector.solve(newProblem, configuration, workspace);
547 if (result instanceof InconsistencyResult) { 611 if (result instanceof InconsistencyResult) {
548 logger.debug("Solver found an Inconsistency!"); 612 logger.debug("Solver found an Inconsistency!");
549 removeSubtreeFromQueue(t); 613 removeSubtreeFromQueue(t);
550 return true; 614 return true;
551 } else if (result instanceof ModelResult) { 615 } else if (result instanceof ModelResult) {
552 logger.debug("Solver found a model!"); 616 logger.debug("Solver found a model!");
553 solutionStore.newSolution(context); 617 solutionStore.newSolution(context);
554 618
555 this.modelResultByInternalSolver = (ModelResult) result; 619 this.modelResultByInternalSolver = (ModelResult) result;
556 return true; 620 return true;
557 } else { 621 } else {
558 logger.debug("Failed consistency check."); 622 logger.debug("Failed consistency check.");
559 return false;
560 }
561 } catch (Exception e) {
562 logger.debug("Problem with internal consistency checking: "+e.getMessage());
563 e.printStackTrace();
564 return false; 623 return false;
565 } 624 }
625 } catch (Exception e) {
626 logger.debug("Problem with internal consistency checking: "+e.getMessage());
627 e.printStackTrace();
628 return false;
566 } 629 }
567
568 } 630 }
569 return false;
570 }
571 631
572 protected void removeSubtreeFromQueue(TrajectoryWithFitness t) {
573 PriorityQueue<TrajectoryWithFitness> previous = this.trajectoiresToExplore;
574 this.trajectoiresToExplore = new PriorityQueue<>(this.comparator);
575 for (TrajectoryWithFitness trajectoryWithFitness : previous) {
576 if (!containsAsSubstring(trajectoryWithFitness.trajectory, t.trajectory)) {
577 this.trajectoiresToExplore.add(trajectoryWithFitness);
578 } else {
579 logger.debug("State has been excluded due to inherent inconsistency");
580 }
581 }
582 } 632 }
633 return false;
634 }
583 635
584 private boolean containsAsSubstring(Object[] full, Object[] substring) { 636 protected void removeSubtreeFromQueue(TrajectoryWithFitness t) {
585 if (substring.length > full.length) { 637 PriorityQueue<TrajectoryWithFitness> previous = this.trajectoiresToExplore;
586 return false; 638 this.trajectoiresToExplore = new PriorityQueue<>(this.comparator);
587 } else if (substring.length == full.length) { 639 for (TrajectoryWithFitness trajectoryWithFitness : previous) {
588 return Arrays.equals(full, substring); 640 if (!containsAsSubstring(trajectoryWithFitness.trajectory, t.trajectory)) {
641 this.trajectoiresToExplore.add(trajectoryWithFitness);
589 } else { 642 } else {
590 Object[] part = Arrays.copyOfRange(full, 0, substring.length); 643 logger.debug("State has been excluded due to inherent inconsistency");
591 return Arrays.equals(part, substring);
592 } 644 }
593 } 645 }
646 }
647
648 private boolean containsAsSubstring(Object[] full, Object[] substring) {
649 if (substring.length > full.length) {
650 return false;
651 } else if (substring.length == full.length) {
652 return Arrays.equals(full, substring);
653 } else {
654 Object[] part = Arrays.copyOfRange(full, 0, substring.length);
655 return Arrays.equals(part, substring);
656 }
657 }
594} 658}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/InconsistentScopeGlobalConstraint.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/InconsistentScopeGlobalConstraint.xtend
new file mode 100644
index 00000000..2e039ca2
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/InconsistentScopeGlobalConstraint.xtend
@@ -0,0 +1,25 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import org.eclipse.viatra.dse.objectives.IGlobalConstraint
4import org.eclipse.viatra.dse.base.ThreadContext
5import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
6
7class InconsistentScopeGlobalConstraint implements IGlobalConstraint {
8
9 override init(ThreadContext context) {
10 // Nothing to initialize.
11 }
12
13 override createNew() {
14 this
15 }
16
17 override getName() {
18 class.name
19 }
20
21 override checkGlobalConstraint(ThreadContext context) {
22 val partialModel = context.model as PartialInterpretation
23 partialModel.minNewElements <= partialModel.maxNewElements || partialModel.maxNewElements < 0
24 }
25}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/LoggerSolutionFoundHandler.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/LoggerSolutionFoundHandler.xtend
new file mode 100644
index 00000000..39ef5f9a
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/LoggerSolutionFoundHandler.xtend
@@ -0,0 +1,24 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasonerConfiguration
4import org.apache.log4j.Logger
5import org.eclipse.viatra.dse.api.SolutionTrajectory
6import org.eclipse.viatra.dse.base.ThreadContext
7import org.eclipse.viatra.dse.solutionstore.ISolutionFoundHandler
8import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
9
10@FinalFieldsConstructor
11class LoggerSolutionFoundHandler implements ISolutionFoundHandler {
12 val ViatraReasonerConfiguration configuration
13
14 val logger = Logger.getLogger(SolutionCopier)
15
16 override solutionFound(ThreadContext context, SolutionTrajectory trajectory) {
17 configuration.progressMonitor.workedModelFound(configuration.solutionScope.numberOfRequiredSolutions)
18 logger.debug("Found a solution.")
19 }
20
21 override solutionTriedToSave(ThreadContext context, SolutionTrajectory trajectory) {
22 // We are not interested in invalid solutions, ignore.
23 }
24}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ModelGenerationCompositeObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ModelGenerationCompositeObjective.xtend
index 9fc6853c..27208cf4 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ModelGenerationCompositeObjective.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ModelGenerationCompositeObjective.xtend
@@ -1,99 +1,123 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse 1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2 2
3import com.google.common.collect.ImmutableList
4import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
5import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ViatraReasonerConfiguration
6import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.IThreeValuedObjective
3import java.util.Comparator 7import java.util.Comparator
4import java.util.List 8import java.util.List
5import org.eclipse.viatra.dse.base.ThreadContext 9import org.eclipse.viatra.dse.base.ThreadContext
6import org.eclipse.viatra.dse.objectives.Comparators 10import org.eclipse.viatra.dse.objectives.Comparators
7import org.eclipse.viatra.dse.objectives.IObjective 11import org.eclipse.viatra.dse.objectives.IObjective
8import org.eclipse.viatra.dse.objectives.impl.BaseObjective 12import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PrimitiveElement
9 13
10//class ViatraReasonerNumbers { 14class ModelGenerationCompositeObjective implements IThreeValuedObjective {
11// public static val scopePriority = 2 15 val IObjective scopeObjective
12// public static val unfinishedMultiplicityPriority = 2
13// public static val unifinshedWFPriority = 2
14// //public static val complexityPriority = 4
15//
16// public static val scopeWeigth = 1.0
17// public static val unfinishedMultiplicityWeigth = 1.5
18// public static val unfinishedWFWeigth = 1.5
19// //public static val complexityWeigth = 0.1
20//
21// public static val useCompositeObjective = true
22// public static val compositePriority = 2
23//}
24
25class ModelGenerationCompositeObjective implements IObjective{
26 val ScopeObjective scopeObjective
27 val List<UnfinishedMultiplicityObjective> unfinishedMultiplicityObjectives 16 val List<UnfinishedMultiplicityObjective> unfinishedMultiplicityObjectives
28 val UnfinishedWFObjective unfinishedWFObjective 17 val UnfinishedWFObjective unfinishedWFObjective
29 var boolean isWFOptional = false; 18 var PartialInterpretation model = null
19 val int scopeWeight
20 val int conaintmentWeight
21 val int nonContainmentWeight
22 val int unfinishedWFWeight
30 23
31 public new( 24 new(
32 ScopeObjective scopeObjective, 25 IObjective scopeObjective,
26 List<UnfinishedMultiplicityObjective> unfinishedMultiplicityObjectives,
27 UnfinishedWFObjective unfinishedWFObjective,
28 ViatraReasonerConfiguration configuration)
29 {
30 this(
31 scopeObjective, unfinishedMultiplicityObjectives, unfinishedWFObjective,
32 configuration.scopeWeight, configuration.conaintmentWeight, configuration.nonContainmentWeight,
33 configuration.unfinishedWFWeight
34 )
35 }
36
37 new(
38 IObjective scopeObjective,
33 List<UnfinishedMultiplicityObjective> unfinishedMultiplicityObjectives, 39 List<UnfinishedMultiplicityObjective> unfinishedMultiplicityObjectives,
34 UnfinishedWFObjective unfinishedWFObjective, 40 UnfinishedWFObjective unfinishedWFObjective,
35 boolean isWFOptional) 41 int scopeWeight, int conaintmentWeight, int nonContainmentWeight, int unfinishedWFWeight)
36 { 42 {
37 this.scopeObjective = scopeObjective 43 this.scopeObjective = scopeObjective
38 this.unfinishedMultiplicityObjectives = unfinishedMultiplicityObjectives 44 this.unfinishedMultiplicityObjectives = unfinishedMultiplicityObjectives
39 this.unfinishedWFObjective = unfinishedWFObjective 45 this.unfinishedWFObjective = unfinishedWFObjective
40 this.isWFOptional = isWFOptional; 46
41 } 47 this.scopeWeight = scopeWeight
42 48 this.conaintmentWeight = conaintmentWeight
43 def getIsWFOptional(){ 49 this.nonContainmentWeight = nonContainmentWeight
44 return this.isWFOptional; 50 this.unfinishedWFWeight = unfinishedWFWeight
45 } 51 }
46 52
47 override init(ThreadContext context) { 53 override init(ThreadContext context) {
54 model = context.model as PartialInterpretation
48 this.scopeObjective.init(context) 55 this.scopeObjective.init(context)
49 this.unfinishedMultiplicityObjectives.forEach[it.init(context)] 56 this.unfinishedMultiplicityObjectives.forEach[it.init(context)]
50 this.unfinishedWFObjective.init(context) 57 this.unfinishedWFObjective.init(context)
51 } 58 }
52 59
53 override createNew() { 60 override createNew() {
54 return new ModelGenerationCompositeObjective( 61 return new ModelGenerationCompositeObjective(
55 this.scopeObjective, this.unfinishedMultiplicityObjectives, this.unfinishedWFObjective, this.isWFOptional) 62 scopeObjective.createNew,
63 ImmutableList.copyOf(unfinishedMultiplicityObjectives.map[createNew as UnfinishedMultiplicityObjective]),
64 unfinishedWFObjective.createNew as UnfinishedWFObjective,
65 scopeWeight, conaintmentWeight, nonContainmentWeight, unfinishedWFWeight
66 )
56 } 67 }
57 68
58 override getComparator() { Comparators.LOWER_IS_BETTER } 69 override getComparator() { Comparators.LOWER_IS_BETTER }
70
59 override getFitness(ThreadContext context) { 71 override getFitness(ThreadContext context) {
60 var sum = 0.0 72
61 val scopeFitnes = scopeObjective.getFitness(context) 73 val scopeFitnes = scopeObjective.getFitness(context)
62 //val unfinishedMultiplicitiesFitneses = unfinishedMultiplicityObjectives.map[x|x.getFitness(context)] 74 val unfinishedWFsFitness = unfinishedWFObjective.getFitness(context)
63 75
64 sum+=scopeFitnes 76 var containmentMultiplicity = 0.0
65 var multiplicity = 0.0 77 var nonContainmentMultiplicity = 0.0
66 for(multiplicityObjective : unfinishedMultiplicityObjectives) { 78 for(multiplicityObjective : unfinishedMultiplicityObjectives) {
67 multiplicity+=multiplicityObjective.getFitness(context)//*0.5 79 val multiplicity = multiplicityObjective.getFitness(context)
80// println(multiplicityObjective.name + "=" + multiplicity)
81 if(multiplicityObjective.containment) {
82 containmentMultiplicity+=multiplicity
83 } else {
84 nonContainmentMultiplicity+=multiplicity
85 }
86
68 } 87 }
69 sum+=multiplicity
70 88
71 // the WF can be optional when generating realistic models 89 var sum = 0.0
72 if(!isWFOptional){ 90 sum += scopeFitnes*scopeWeight
73 val unfinishedWFsFitness = unfinishedWFObjective.getFitness(context) 91 sum += containmentMultiplicity*conaintmentWeight
74 sum += unfinishedWFsFitness//*0.5 92 sum += nonContainmentMultiplicity*nonContainmentWeight
75 } 93 sum += unfinishedWFsFitness*unfinishedWFWeight
76 94
77 //println('''Sum=«sum»|Scope=«scopeFitnes»|Multiplicity=«multiplicity»|WFs=«unfinishedWFsFitness»''') 95// println('''scope=«scopeFitnes», containment=«containmentMultiplicity», nonContainment=«nonContainmentMultiplicity», wf=«unfinishedWFsFitness», sum=«sum»''')
78 96
79 return sum 97 return sum
80 } 98 }
81 99
82 override getLevel() { 2 } 100 override getWorstPossibleFitness(ThreadContext threadContext) {
83 override getName() { "CompositeUnfinishednessObjective"} 101 Double.POSITIVE_INFINITY
84 def getObjective(){
85 return this.unfinishedMultiplicityObjectives;
86 } 102 }
87 103
104 override getBestPossibleFitness(ThreadContext threadContext) {
105 0.0
106 }
107
108 override getLevel() { 2 }
109
110 override getName() { "CompositeUnfinishednessObjective" }
111
88 override isHardObjective() { true } 112 override isHardObjective() { true }
89 override satisifiesHardObjective(Double fitness) { fitness <= 0.001 } 113
90 114 override satisifiesHardObjective(Double fitness) { fitness < 0.01 }
91 115
92 override setComparator(Comparator<Double> comparator) { 116 override setComparator(Comparator<Double> comparator) {
93 throw new UnsupportedOperationException("TODO: auto-generated method stub") 117 throw new UnsupportedOperationException("Model generation objective comparator cannot be set.")
94 } 118 }
119
95 override setLevel(int level) { 120 override setLevel(int level) {
96 throw new UnsupportedOperationException("TODO: auto-generated method stub") 121 throw new UnsupportedOperationException("Model generation objective level cannot be set.")
97 } 122 }
98 123}
99} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/NumericSolver.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/NumericSolver.xtend
new file mode 100644
index 00000000..70e8e9c2
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/NumericSolver.xtend
@@ -0,0 +1,192 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import hu.bme.mit.inf.dslreasoner.viatra2logic.NumericTranslator
4import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.BooleanElement
5import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.IntegerElement
6import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
7import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PrimitiveElement
8import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.RealElement
9import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.StringElement
10import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.ModelGenerationMethod
11import java.math.BigDecimal
12import java.util.HashMap
13import java.util.LinkedHashMap
14import java.util.LinkedHashSet
15import java.util.List
16import java.util.Map
17import org.eclipse.emf.ecore.EObject
18import org.eclipse.viatra.dse.base.ThreadContext
19import org.eclipse.viatra.query.runtime.api.IPatternMatch
20import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher
21import org.eclipse.viatra.query.runtime.matchers.psystem.PConstraint
22
23class NumericSolver {
24 val ModelGenerationMethod method
25 var ThreadContext threadContext
26 val constraint2MustUnitPropagationPrecondition = new HashMap<PConstraint,ViatraQueryMatcher<? extends IPatternMatch>>
27 val constraint2CurrentUnitPropagationPrecondition = new HashMap<PConstraint,ViatraQueryMatcher<? extends IPatternMatch>>
28 NumericTranslator t = new NumericTranslator
29
30 val boolean intermediateConsistencyCheck
31 val boolean caching;
32 Map<LinkedHashMap<PConstraint, Iterable<List<Integer>>>,Boolean> satisfiabilityCache = new HashMap
33
34 var long runtime = 0
35 var long cachingTime = 0
36 var int numberOfSolverCalls = 0
37 var int numberOfCachedSolverCalls = 0
38
39 new(ModelGenerationMethod method, boolean intermediateConsistencyCheck, boolean caching) {
40 this.method = method
41 this.intermediateConsistencyCheck = intermediateConsistencyCheck
42 this.caching = caching
43 }
44
45 def init(ThreadContext context) {
46 // This makes the NumericSolver single-threaded,
47 // but that's not a problem, because we only use the solver on a single thread anyways.
48 this.threadContext = context
49 val engine = threadContext.queryEngine
50 for(entry : method.mustUnitPropagationPreconditions.entrySet) {
51 val constraint = entry.key
52 val querySpec = entry.value
53 val matcher = querySpec.getMatcher(engine);
54 constraint2MustUnitPropagationPrecondition.put(constraint,matcher)
55 }
56 for(entry : method.currentUnitPropagationPreconditions.entrySet) {
57 val constraint = entry.key
58 val querySpec = entry.value
59 val matcher = querySpec.getMatcher(engine);
60 constraint2CurrentUnitPropagationPrecondition.put(constraint,matcher)
61 }
62 }
63
64 def getRuntime(){runtime}
65 def getCachingTime(){cachingTime}
66 def getNumberOfSolverCalls(){numberOfSolverCalls}
67 def getNumberOfCachedSolverCalls(){numberOfCachedSolverCalls}
68 def getSolverFormingProblem(){this.t.formingProblemTime}
69 def getSolverSolvingProblem(){this.t.solvingProblemTime}
70 def getSolverSolution(){this.t.formingSolutionTime}
71
72 def boolean maySatisfiable() {
73 if(intermediateConsistencyCheck) {
74 return isSatisfiable(this.constraint2MustUnitPropagationPrecondition)
75 } else {
76 return true
77 }
78 }
79 def boolean currentSatisfiable() {
80 isSatisfiable(this.constraint2CurrentUnitPropagationPrecondition)
81 }
82
83 private def boolean isSatisfiable(Map<PConstraint,ViatraQueryMatcher<? extends IPatternMatch>> matches) {
84 val start = System.nanoTime
85 var boolean finalResult
86 if(matches.empty){
87 finalResult=true
88 } else {
89 val propagatedConstraints = new HashMap
90 for(entry : matches.entrySet) {
91 val constraint = entry.key
92 //println(constraint)
93 val allMatches = entry.value.allMatches.map[it.toArray]
94 //println(allMatches.toList)
95 propagatedConstraints.put(constraint,allMatches)
96 }
97 if(propagatedConstraints.values.forall[empty]) {
98 finalResult=true
99 } else {
100 if(caching) {
101 val code = getCode(propagatedConstraints)
102 val cachedResult = satisfiabilityCache.get(code)
103 if(cachedResult === null) {
104 // println('''new problem, call solver''')
105 // for(entry : code.entrySet) {
106 // println('''«entry.key» -> «entry.value»''')
107 // }
108 //println(code.hashCode)
109 this.numberOfSolverCalls++
110 val res = t.delegateIsSatisfiable(propagatedConstraints)
111 satisfiabilityCache.put(code,res)
112 finalResult=res
113 } else {
114 //println('''similar problem, answer from cache''')
115 finalResult=cachedResult
116 this.numberOfCachedSolverCalls++
117 }
118 } else {
119 finalResult= t.delegateIsSatisfiable(propagatedConstraints)
120 this.numberOfSolverCalls++
121 }
122 }
123 }
124 this.runtime+=System.nanoTime-start
125 return finalResult
126 }
127
128 def getCode(HashMap<PConstraint, Iterable<Object[]>> propagatedConstraints) {
129 val start = System.nanoTime
130 val involvedObjects = new LinkedHashSet(propagatedConstraints.values.flatten.map[toList].flatten.toList).toList
131 val res = new LinkedHashMap(propagatedConstraints.mapValues[matches | matches.map[objects | objects.map[object | involvedObjects.indexOf(object)].toList]])
132 this.cachingTime += System.nanoTime-start
133 return res
134 }
135
136 def fillSolutionCopy(Map<EObject, EObject> trace) {
137 val model = threadContext.getModel as PartialInterpretation
138 val dataObjects = model.newElements.filter(PrimitiveElement).filter[!model.openWorldElements.contains(it)].toList
139 if(constraint2CurrentUnitPropagationPrecondition.empty) {
140 fillWithDefaultValues(dataObjects,trace)
141 } else {
142 val propagatedConstraints = new HashMap
143 for(entry : constraint2CurrentUnitPropagationPrecondition.entrySet) {
144 val constraint = entry.key
145 val allMatches = entry.value.allMatches.map[it.toArray]
146 propagatedConstraints.put(constraint,allMatches)
147 }
148
149 if(propagatedConstraints.values.forall[empty]) {
150 fillWithDefaultValues(dataObjects,trace)
151 } else {
152 val solution = t.delegateGetSolution(dataObjects,propagatedConstraints)
153 fillWithSolutions(dataObjects,solution,trace)
154 }
155 }
156 }
157
158 def protected fillWithDefaultValues(List<PrimitiveElement> elements, Map<EObject, EObject> trace) {
159 for(element : elements) {
160 if(element.valueSet==false) {
161 val value = getDefaultValue(element)
162 val target = trace.get(element) as PrimitiveElement
163 target.fillWithValue(value)
164 }
165 }
166 }
167
168 def protected dispatch getDefaultValue(BooleanElement e) {false}
169 def protected dispatch getDefaultValue(IntegerElement e) {0}
170 def protected dispatch getDefaultValue(RealElement e) {0.0}
171 def protected dispatch getDefaultValue(StringElement e) {""}
172
173 def protected fillWithSolutions(List<PrimitiveElement> elements, Map<PrimitiveElement, Number> solution, Map<EObject, EObject> trace) {
174 for(element : elements) {
175 if(element.valueSet==false) {
176 if(solution.containsKey(element)) {
177 val value = solution.get(element)
178 val target = trace.get(element) as PrimitiveElement
179 target.fillWithValue(value)
180 } else {
181 val target = trace.get(element) as PrimitiveElement
182 target.fillWithValue(target.defaultValue)
183 }
184 }
185 }
186 }
187
188 def protected dispatch fillWithValue(BooleanElement e, Object value) {e.valueSet=true e.value=value as Boolean}
189 def protected dispatch fillWithValue(IntegerElement e, Object value) {e.valueSet=true e.value=value as Integer}
190 def protected dispatch fillWithValue(RealElement e, Object value) {e.valueSet=true e.value=BigDecimal.valueOf(value as Double) }
191 def protected dispatch fillWithValue(StringElement e, Object value) {e.valueSet=true e.value=value as String}
192} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/PartialModelAsLogicInterpretation.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/PartialModelAsLogicInterpretation.xtend
index f61c7333..b48d0831 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/PartialModelAsLogicInterpretation.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/PartialModelAsLogicInterpretation.xtend
@@ -22,12 +22,13 @@ import java.util.List
22import java.util.Map 22import java.util.Map
23import java.util.TreeSet 23import java.util.TreeSet
24import org.eclipse.emf.ecore.EObject 24import org.eclipse.emf.ecore.EObject
25import org.eclipse.xtend.lib.annotations.Accessors
25import org.eclipse.xtext.xbase.lib.Functions.Function1 26import org.eclipse.xtext.xbase.lib.Functions.Function1
26 27
27import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.* 28import static extension hu.bme.mit.inf.dslreasoner.util.CollectionsUtil.*
28 29
29class PartialModelAsLogicInterpretation implements LogicModelInterpretation{ 30class PartialModelAsLogicInterpretation implements LogicModelInterpretation{
30 val PartialInterpretation partialInterpretation 31 @Accessors val PartialInterpretation partialInterpretation
31 val Map<EObject, EObject> trace; 32 val Map<EObject, EObject> trace;
32 val Map<TypeDeclaration,PartialComplexTypeInterpretation> type2Interpretation 33 val Map<TypeDeclaration,PartialComplexTypeInterpretation> type2Interpretation
33 val Map<RelationDeclaration,PartialRelationInterpretation> relation2Interpretation 34 val Map<RelationDeclaration,PartialRelationInterpretation> relation2Interpretation
@@ -153,14 +154,70 @@ class PartialModelAsLogicInterpretation implements LogicModelInterpretation{
153 } 154 }
154 155
155 override getAllIntegersInStructure() { 156 override getAllIntegersInStructure() {
156 new TreeSet(this.integerForwardTrace.keySet) 157 new TreeSet(allIntegersWithInterpretation.values)
158 }
159
160 override getAllIntegersWithInterpretation() {
161 val builder = new HashMap
162 for (entry : integerForwardTrace.entrySet) {
163 builder.put(entry.value, entry.key)
164 }
165 for (element : partialInterpretation.newElements) {
166 if (element instanceof IntegerElement) {
167 builder.put(element, element.value)
168 }
169 }
170 builder
157 } 171 }
158 172
159 override getAllRealsInStructure() { 173 override getAllRealsInStructure() {
160 new TreeSet(this.realForwardTrace.keySet) 174 new TreeSet(allRealsWithInterpretation.values)
175 }
176
177 override getAllRealsWithInterpretation() {
178 val builder = new HashMap
179 for (entry : realForwardTrace.entrySet) {
180 builder.put(entry.value, entry.key)
181 }
182 for (element : partialInterpretation.newElements) {
183 if (element instanceof RealElement) {
184 builder.put(element, element.value)
185 }
186 }
187 builder
161 } 188 }
162 189
163 override getAllStringsInStructure() { 190 override getAllStringsInStructure() {
164 new TreeSet(this.stringForwardTrace.keySet) 191 new TreeSet(allStringsWithInterpretation.values)
192 }
193
194 override getAllStringsWithInterpretation() {
195 val builder = new HashMap
196 for (entry : stringForwardTrace.entrySet) {
197 builder.put(entry.value, entry.key)
198 }
199 for (element : partialInterpretation.newElements) {
200 if (element instanceof StringElement) {
201 builder.put(element, element.value)
202 }
203 }
204 builder
205 }
206
207 override getAllBooleansInStructure() {
208 new TreeSet(allBooleansWithInterpretation.values)
209 }
210
211 override getAllBooleansWithInterpretation() {
212 val builder = new HashMap
213 for (entry : booleanForwardTrace.entrySet) {
214 builder.put(entry.value, entry.key)
215 }
216 for (element : partialInterpretation.newElements) {
217 if (element instanceof BooleanElement) {
218 builder.put(element, element.value)
219 }
220 }
221 builder
165 } 222 }
166} \ No newline at end of file 223}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/PunishSizeObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/PunishSizeObjective.xtend
new file mode 100644
index 00000000..bad8e4d1
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/PunishSizeObjective.xtend
@@ -0,0 +1,52 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
4import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PrimitiveElement
5import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.AbstractThreeValuedObjective
6import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ObjectiveKind
7import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ObjectiveThreshold
8import org.eclipse.viatra.dse.base.ThreadContext
9
10class PunishSizeObjective extends AbstractThreeValuedObjective {
11 static val NAME = typeof(PunishSizeObjective).name
12
13 new(ObjectiveKind kind, int level) {
14 super(NAME, kind, ObjectiveThreshold.NO_THRESHOLD, level)
15 }
16
17 override createNew() {
18 new PunishSizeObjective(kind, level)
19 }
20
21 override init(ThreadContext context) {
22 // Nothing to initialize.
23 }
24
25 override getRawFitness(ThreadContext threadContext) {
26 val model = threadContext.model
27 if (model instanceof PartialInterpretation) {
28 val size = model.newObjectCount
29// println('''size=«size»''')
30 size as double
31 } else {
32 throw new IllegalArgumentException("notifier must be a PartialInterpretation")
33 }
34 }
35
36 override getLowestPossibleFitness(ThreadContext threadContext) {
37 getRawFitness(threadContext)
38 }
39
40 override getHighestPossibleFitness(ThreadContext threadContext) {
41 val model = threadContext.model
42 if (model instanceof PartialInterpretation) {
43 (model.newObjectCount + model.maxNewElements) as double
44 } else {
45 throw new IllegalArgumentException("notifier must be a PartialInterpretation")
46 }
47 }
48
49 private def getNewObjectCount(PartialInterpretation interpretation) {
50 interpretation.newElements.reject[it instanceof PrimitiveElement].size
51 }
52} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ScopeObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ScopeObjective.xtend
index 69efe0d7..b61bd20b 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ScopeObjective.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ScopeObjective.xtend
@@ -23,9 +23,9 @@ class ScopeObjective implements IObjective{
23 23
24 override getFitness(ThreadContext context) { 24 override getFitness(ThreadContext context) {
25 val interpretation = context.model as PartialInterpretation 25 val interpretation = context.model as PartialInterpretation
26 var res = interpretation.minNewElements.doubleValue 26 var res = interpretation.minNewElementsHeuristic.doubleValue
27 for(scope : interpretation.scopes) { 27 for(scope : interpretation.scopes) {
28 res += scope.minNewElements*2 28 res += scope.minNewElementsHeuristic * 2
29 } 29 }
30 return res 30 return res
31 } 31 }
@@ -41,4 +41,4 @@ class ScopeObjective implements IObjective{
41 throw new UnsupportedOperationException("TODO: auto-generated method stub") 41 throw new UnsupportedOperationException("TODO: auto-generated method stub")
42 } 42 }
43 override getLevel() { 2 } 43 override getLevel() { 2 }
44} \ No newline at end of file 44}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionCopier.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionCopier.xtend
new file mode 100644
index 00000000..888eda18
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionCopier.xtend
@@ -0,0 +1,82 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import com.google.common.collect.ImmutableList
4import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
5import java.util.LinkedHashMap
6import java.util.List
7import java.util.Map
8import org.eclipse.emf.ecore.EObject
9import org.eclipse.emf.ecore.util.EcoreUtil
10import org.eclipse.viatra.dse.base.ThreadContext
11import org.eclipse.xtend.lib.annotations.Accessors
12import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
13
14@FinalFieldsConstructor
15class CopiedSolution {
16 @Accessors val PartialInterpretation partialInterpretations
17 @Accessors val Map<EObject, EObject> trace
18 @Accessors val long copierRuntime
19 @Accessors var boolean current = true
20}
21
22/**
23 * Based on {@link SolutionStore.BestSolutionSaver}.
24 *
25 * Will also automatically fill any missing numerical values in the saved solutions
26 * using the supplied {@link NumericSolver}.
27 */
28class SolutionCopier {
29 val copiedSolutions = new LinkedHashMap<Object, CopiedSolution>
30
31 @Accessors NumericSolver numericSolver
32 long startTime = System.nanoTime
33 @Accessors(PUBLIC_GETTER) long totalCopierRuntime = 0
34
35 def void copySolution(ThreadContext context, Object solutionId) {
36 val existingCopy = copiedSolutions.get(solutionId)
37 if (existingCopy === null) {
38 val copyStart = System.nanoTime
39 val solution = context.model as PartialInterpretation
40 val copier = new EcoreUtil.Copier
41 val copiedPartialInterpretation = copier.copy(solution) as PartialInterpretation
42 copier.copyReferences
43 totalCopierRuntime += System.nanoTime - copyStart
44 val copierRuntime = System.nanoTime - startTime
45 val copiedSolution = new CopiedSolution(copiedPartialInterpretation, copier, copierRuntime)
46 //numericSolver?.fillSolutionCopy(copiedSolution.trace)
47 copiedSolutions.put(solutionId, copiedSolution)
48 } else {
49 existingCopy.current = true
50 }
51 }
52
53 def void markAsObsolete(Object solutionId) {
54 val copiedSolution = copiedSolutions.get(solutionId)
55 if (copiedSolution === null) {
56 throw new IllegalStateException("No solution to mark as obsolete for state code: " + solutionId)
57 }
58 copiedSolution.current = false
59 }
60
61 def List<PartialInterpretation> getPartialInterpretations(boolean currentOnly) {
62 getListOfCopiedSolutions(currentOnly).map[partialInterpretations]
63 }
64
65 def List<Map<EObject, EObject>> getTraces(boolean currentOnly) {
66 getListOfCopiedSolutions(currentOnly).map[trace]
67 }
68
69 def List<Long> getAllCopierRuntimes(boolean currentOnly) {
70 getListOfCopiedSolutions(currentOnly).map[copierRuntime]
71 }
72
73 def List<CopiedSolution> getListOfCopiedSolutions(boolean currentOnly) {
74 val values = copiedSolutions.values
75 val filteredSolutions = if (currentOnly) {
76 values.filter[current]
77 } else {
78 values
79 }
80 ImmutableList.copyOf(filteredSolutions)
81 }
82}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithCopy.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithCopy.xtend
index a8b7301e..4bd2c349 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithCopy.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithCopy.xtend
@@ -1,14 +1,12 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse 1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2 2
3import java.util.List
4import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation 3import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
5import java.util.LinkedList 4import java.util.LinkedList
6import org.eclipse.emf.ecore.EObject 5import java.util.List
7import java.util.Map 6import java.util.Map
7import org.eclipse.emf.ecore.EObject
8import org.eclipse.emf.ecore.util.EcoreUtil 8import org.eclipse.emf.ecore.util.EcoreUtil
9import org.eclipse.viatra.dse.base.ThreadContext 9import org.eclipse.viatra.dse.base.ThreadContext
10import java.util.TreeMap
11import java.util.SortedMap
12 10
13class SolutionStoreWithCopy { 11class SolutionStoreWithCopy {
14 12
@@ -25,7 +23,7 @@ class SolutionStoreWithCopy {
25 newSolution(context) 23 newSolution(context)
26 }*/ 24 }*/
27 25
28 def newSolution(ThreadContext context) { 26 def Map<EObject,EObject> newSolution(ThreadContext context) {
29 //print(System.nanoTime-initTime + ";") 27 //print(System.nanoTime-initTime + ";")
30 val copyStart = System.nanoTime 28 val copyStart = System.nanoTime
31 val solution = context.model as PartialInterpretation 29 val solution = context.model as PartialInterpretation
@@ -36,6 +34,7 @@ class SolutionStoreWithCopy {
36 copyTraces.add(copier) 34 copyTraces.add(copier)
37 runtime += System.nanoTime - copyStart 35 runtime += System.nanoTime - copyStart
38 solutionTimes.add(System.nanoTime-sartTime) 36 solutionTimes.add(System.nanoTime-sartTime)
37 return copier
39 } 38 }
40 def getSumRuntime() { 39 def getSumRuntime() {
41 return runtime 40 return runtime
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithDiversityDescriptor.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithDiversityDescriptor.xtend
deleted file mode 100644
index 1e7f18a8..00000000
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SolutionStoreWithDiversityDescriptor.xtend
+++ /dev/null
@@ -1,120 +0,0 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.neighbourhood.PartialInterpretation2ImmutableTypeLattice
4import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation
5import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.DiversityDescriptor
6import java.util.LinkedList
7import java.util.List
8import org.eclipse.viatra.dse.base.ThreadContext
9import java.util.HashSet
10import java.util.Set
11
12enum DiversityGranularity {
13 Nodewise, Graphwise
14}
15
16class SolutionStoreWithDiversityDescriptor {
17 val DiversityDescriptor descriptor
18 DiversityGranularity granularity
19 val PartialInterpretation2ImmutableTypeLattice solutionCoder = new PartialInterpretation2ImmutableTypeLattice
20 val Set<Integer> solutionCodeList = new HashSet
21
22 var long runtime
23 var int allCheck
24 var int successfulCheck
25
26 new(DiversityDescriptor descriptor) {
27 if(descriptor.ensureDiversity) {
28 this.descriptor = descriptor
29 this.granularity = DiversityGranularity::Nodewise
30 } else {
31 this.descriptor = null
32 this.granularity = DiversityGranularity::Nodewise
33 }
34 }
35
36 def public isActive() {
37 descriptor!==null
38 }
39
40 def getSumRuntime() {
41 return runtime
42 }
43 def getSuccessRate() {
44 return successfulCheck as double / allCheck
45 }
46
47 def isDifferent(ThreadContext context) {
48 if(active) {
49 val start = System.nanoTime
50 val model = context.model as PartialInterpretation
51 var boolean isDifferent
52 if(this.granularity == DiversityGranularity::Graphwise) {
53 val code = solutionCoder.createRepresentation(model,
54 descriptor.range,
55 descriptor.parallels,
56 descriptor.maxNumber,
57 descriptor.relevantTypes,
58 descriptor.relevantRelations).modelRepresentation.hashCode
59
60 isDifferent = !solutionCodeList.contains(code)
61 } else if(this.granularity == DiversityGranularity::Nodewise){
62 val codes = solutionCoder.createRepresentation(model,
63 descriptor.range,
64 descriptor.parallels,
65 descriptor.maxNumber,
66 descriptor.relevantTypes,
67 descriptor.relevantRelations).modelRepresentation.keySet.map[hashCode].toList
68 val differentCodes = codes.filter[!solutionCodeList.contains(it)]
69 //println(differentCodes.size)
70
71 isDifferent = differentCodes.size>=1
72 } else {
73 throw new UnsupportedOperationException('''Unsupported diversity type: «this.granularity»''')
74 }
75
76 runtime += System.nanoTime - start
77 allCheck++
78 if(isDifferent) { successfulCheck++ }
79 return isDifferent
80 } else {
81 allCheck++
82 successfulCheck++
83 return true
84 }
85 }
86
87 def canBeDifferent(ThreadContext context) {
88 return true
89 }
90
91 def newSolution(ThreadContext context) {
92 if(active) {
93 val start = System.nanoTime
94 val model = context.model as PartialInterpretation
95 if(this.granularity == DiversityGranularity::Graphwise) {
96 val code = solutionCoder.createRepresentation(model,
97 descriptor.range,
98 descriptor.parallels,
99 descriptor.maxNumber,
100 descriptor.relevantTypes,
101 descriptor.relevantRelations).modelRepresentation.hashCode
102
103 solutionCodeList += code.hashCode
104 } else if(this.granularity == DiversityGranularity::Nodewise){
105 val codes = solutionCoder.createRepresentation(model,
106 descriptor.range,
107 descriptor.parallels,
108 descriptor.maxNumber,
109 descriptor.relevantTypes,
110 descriptor.relevantRelations).modelRepresentation.keySet.map[hashCode].toList
111
112 solutionCodeList += codes.map[it.hashCode]
113 } else {
114 throw new UnsupportedOperationException('''Unsupported diversity type: «this.granularity»''')
115 }
116
117 runtime += System.nanoTime - start
118 }
119 }
120} \ No newline at end of file
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SurelyViolatedObjectiveGlobalConstraint.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SurelyViolatedObjectiveGlobalConstraint.xtend
new file mode 100644
index 00000000..8ed3e912
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/SurelyViolatedObjectiveGlobalConstraint.xtend
@@ -0,0 +1,27 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import org.eclipse.viatra.dse.base.ThreadContext
4import org.eclipse.viatra.dse.objectives.IGlobalConstraint
5import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
6
7@FinalFieldsConstructor
8class SurelyViolatedObjectiveGlobalConstraint implements IGlobalConstraint {
9 val ViatraReasonerSolutionSaver solutionSaver
10
11 override init(ThreadContext context) {
12 // Nothing to initialize.
13 }
14
15 override createNew() {
16 this
17 }
18
19 override getName() {
20 class.name
21 }
22
23 override checkGlobalConstraint(ThreadContext context) {
24 val bestFitness = DseUtils.caclulateBestPossibleFitness(context)
25 bestFitness.satisifiesHardObjectives && solutionSaver.fitnessMayBeSaved(bestFitness)
26 }
27}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedMultiplicityObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedMultiplicityObjective.xtend
index aad9a448..e1582d3b 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedMultiplicityObjective.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedMultiplicityObjective.xtend
@@ -1,15 +1,15 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse 1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2 2
3import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.MultiplicityGoalConstraintCalculator 3import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.MultiplicityGoalConstraintCalculator
4import java.util.Comparator 4import java.util.Comparator
5import org.eclipse.viatra.dse.base.ThreadContext 5import org.eclipse.viatra.dse.base.ThreadContext
6import org.eclipse.viatra.dse.objectives.IObjective
7import org.eclipse.viatra.dse.objectives.Comparators 6import org.eclipse.viatra.dse.objectives.Comparators
7import org.eclipse.viatra.dse.objectives.IObjective
8 8
9class UnfinishedMultiplicityObjective implements IObjective { 9class UnfinishedMultiplicityObjective implements IObjective {
10 val MultiplicityGoalConstraintCalculator unfinishedMultiplicity; 10 val MultiplicityGoalConstraintCalculator unfinishedMultiplicity
11 11
12 public new(MultiplicityGoalConstraintCalculator unfinishedMultiplicity) { 12 new(MultiplicityGoalConstraintCalculator unfinishedMultiplicity) {
13 this.unfinishedMultiplicity = unfinishedMultiplicity 13 this.unfinishedMultiplicity = unfinishedMultiplicity
14 } 14 }
15 15
@@ -29,9 +29,13 @@ class UnfinishedMultiplicityObjective implements IObjective {
29 override satisifiesHardObjective(Double fitness) { return fitness <=0.01 } 29 override satisifiesHardObjective(Double fitness) { return fitness <=0.01 }
30 30
31 override setComparator(Comparator<Double> comparator) { 31 override setComparator(Comparator<Double> comparator) {
32 throw new UnsupportedOperationException("TODO: auto-generated method stub") 32 throw new UnsupportedOperationException
33 } 33 }
34 override setLevel(int level) { 34 override setLevel(int level) {
35 throw new UnsupportedOperationException("TODO: auto-generated method stub") 35 throw new UnsupportedOperationException
36 }
37
38 def isContainment() {
39 return this.unfinishedMultiplicity.containment
36 } 40 }
37} \ No newline at end of file 41}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedWFObjective.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedWFObjective.xtend
index e0111cf6..1b61ffa5 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedWFObjective.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/UnfinishedWFObjective.xtend
@@ -1,56 +1,64 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse 1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2 2
3import org.eclipse.viatra.dse.objectives.IObjective 3import java.util.ArrayList
4import org.eclipse.viatra.query.runtime.api.IPatternMatch
5import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher
6import org.eclipse.viatra.query.runtime.api.IQuerySpecification
7import java.util.Collection 4import java.util.Collection
8import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine 5import java.util.Comparator
9import org.eclipse.viatra.query.runtime.emf.EMFScope
10import org.eclipse.viatra.dse.base.ThreadContext
11import java.util.List 6import java.util.List
7import org.eclipse.viatra.dse.base.ThreadContext
12import org.eclipse.viatra.dse.objectives.Comparators 8import org.eclipse.viatra.dse.objectives.Comparators
13import java.util.ArrayList 9import org.eclipse.viatra.dse.objectives.IObjective
14import java.util.Comparator 10import org.eclipse.viatra.query.runtime.api.IPatternMatch
11import org.eclipse.viatra.query.runtime.api.IQuerySpecification
12import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher
15 13
16class UnfinishedWFObjective implements IObjective { 14class UnfinishedWFObjective implements IObjective {
17 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> unfinishedWFs 15 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> unfinishedWFs
18 val List<ViatraQueryMatcher<?>> matchers 16 val List<ViatraQueryMatcher<?>> matchers
19 17
20 public new(Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> unfinishedWFs) { 18 new(
19 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> unfinishedWFs) {
21 this.unfinishedWFs = unfinishedWFs 20 this.unfinishedWFs = unfinishedWFs
22 matchers = new ArrayList(unfinishedWFs.size) 21 matchers = new ArrayList(unfinishedWFs.size)
23 } 22 }
23
24 override getName() '''unfinishedWFs''' 24 override getName() '''unfinishedWFs'''
25
25 override createNew() { 26 override createNew() {
26 return new UnfinishedWFObjective(unfinishedWFs) 27 return new UnfinishedWFObjective(unfinishedWFs)
27 } 28 }
29
28 override init(ThreadContext context) { 30 override init(ThreadContext context) {
29 val engine = context.queryEngine//ViatraQueryEngine.on(new EMFScope(context.model)) 31 val engine = context.queryEngine // ViatraQueryEngine.on(new EMFScope(context.model))
30 for(unfinishedWF : unfinishedWFs) { 32 for (unfinishedWF : unfinishedWFs) {
31 matchers += unfinishedWF.getMatcher(engine) 33 matchers += unfinishedWF.getMatcher(engine)
32 } 34 }
33 } 35 }
34 36
35 override getComparator() { Comparators.LOWER_IS_BETTER } 37 override getComparator() { Comparators.LOWER_IS_BETTER }
38
36 override getFitness(ThreadContext context) { 39 override getFitness(ThreadContext context) {
37 var sumOfMatches = 0 40 var sumOfMatches = 0
38 for(matcher : matchers) { 41 for (matcher : matchers) {
39 val number = matcher.countMatches 42 val number = matcher.countMatches
40 //println('''«matcher.patternName» = «number»''') 43// if (number > 0) {
41 sumOfMatches+=number 44// println('''«matcher.patternName» = «number»''')
45// }
46 sumOfMatches += number
42 } 47 }
43 return sumOfMatches.doubleValue 48 return sumOfMatches.doubleValue
44 } 49 }
45 50
46 override getLevel() { 2 } 51 override getLevel() { 2 }
52
47 override isHardObjective() { true } 53 override isHardObjective() { true }
48 override satisifiesHardObjective(Double fitness) { return fitness <=0.01 } 54
49 55 override satisifiesHardObjective(Double fitness) { return fitness <= 0.01 }
56
50 override setComparator(Comparator<Double> comparator) { 57 override setComparator(Comparator<Double> comparator) {
51 throw new UnsupportedOperationException("TODO: auto-generated method stub") 58 throw new UnsupportedOperationException()
52 } 59 }
60
53 override setLevel(int level) { 61 override setLevel(int level) {
54 throw new UnsupportedOperationException("TODO: auto-generated method stub") 62 throw new UnsupportedOperationException()
55 } 63 }
56} \ No newline at end of file 64}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ViatraReasonerSolutionSaver.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ViatraReasonerSolutionSaver.xtend
new file mode 100644
index 00000000..e00f76ff
--- /dev/null
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/ViatraReasonerSolutionSaver.xtend
@@ -0,0 +1,250 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2
3import hu.bme.mit.inf.dslreasoner.viatrasolver.logic2viatra.cardinality.Bounds
4import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.DirectionalThresholdObjective
5import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.IObjectiveBoundsProvider
6import hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.optimization.ObjectiveThreshold
7import java.util.HashMap
8import java.util.Map
9import org.eclipse.viatra.dse.api.DSEException
10import org.eclipse.viatra.dse.api.Solution
11import org.eclipse.viatra.dse.api.SolutionTrajectory
12import org.eclipse.viatra.dse.base.ThreadContext
13import org.eclipse.viatra.dse.objectives.Fitness
14import org.eclipse.viatra.dse.objectives.IObjective
15import org.eclipse.viatra.dse.objectives.ObjectiveComparatorHelper
16import org.eclipse.viatra.dse.solutionstore.SolutionStore.ISolutionSaver
17import org.eclipse.xtend.lib.annotations.Accessors
18
19/**
20 * Based on {@link SolutionStore.BestSolutionSaver}.
21 *
22 * Will also automatically fill any missing numerical values in the saved solutions
23 * using the supplied {@link NumericSolver}.
24 */
25class ViatraReasonerSolutionSaver implements ISolutionSaver, IObjectiveBoundsProvider {
26 static val TOLERANCE = 1e-10
27
28 @Accessors val SolutionCopier solutionCopier
29 @Accessors val DiversityChecker diversityChecker
30 val IObjective[][] leveledExtremalObjectives
31 val boolean hasExtremalObjectives
32 val int numberOfRequiredSolutions
33 val ObjectiveComparatorHelper comparatorHelper
34 val Map<SolutionTrajectory, Fitness> trajectories = new HashMap
35
36 @Accessors var NumericSolver numericSolver
37 @Accessors var Map<Object, Solution> solutionsCollection
38
39 new(IObjective[][] leveledExtremalObjectives, int numberOfRequiredSolutions, DiversityChecker diversityChecker) {
40 this.diversityChecker = diversityChecker
41 comparatorHelper = new ObjectiveComparatorHelper(leveledExtremalObjectives)
42 this.leveledExtremalObjectives = leveledExtremalObjectives
43 hasExtremalObjectives = leveledExtremalObjectives.exists[!empty]
44 this.numberOfRequiredSolutions = numberOfRequiredSolutions
45 this.solutionCopier = new SolutionCopier
46 }
47
48 def setNumericSolver(NumericSolver numericSolver) {
49 this.numericSolver = numericSolver
50 solutionCopier.numericSolver = numericSolver
51 }
52
53 override saveSolution(ThreadContext context, Object id, SolutionTrajectory solutionTrajectory) {
54 if (hasExtremalObjectives) {
55 saveBestSolutionOnly(context, id, solutionTrajectory)
56 } else {
57 saveAnyDiverseSolution(context, id, solutionTrajectory)
58 }
59 }
60
61 private def saveBestSolutionOnly(ThreadContext context, Object id, SolutionTrajectory solutionTrajectory) {
62 val fitness = context.lastFitness
63 if (!shouldSaveSolution(fitness, context)) {
64 return false
65 }
66 println("Found: " + fitness)
67 val dominatedTrajectories = newArrayList
68 for (entry : trajectories.entrySet) {
69 val isLastFitnessBetter = comparatorHelper.compare(fitness, entry.value)
70 if (isLastFitnessBetter < 0) {
71 // Found a trajectory that dominates the current one, no need to save
72 return false
73 }
74 if (isLastFitnessBetter > 0) {
75 dominatedTrajectories += entry.key
76 }
77 }
78 if (dominatedTrajectories.size == 0 && !needsMoreSolutionsWithSameFitness) {
79 return false
80 }
81 if (!diversityChecker.newSolution(context, id, dominatedTrajectories.map[solution.stateCode])) {
82 return false
83 }
84 // We must save the new trajectory before removing dominated trajectories
85 // to avoid removing the current solution when it is reachable only via dominated trajectories.
86 val solutionSaved = basicSaveSolution(context, id, solutionTrajectory, fitness)
87 for (dominatedTrajectory : dominatedTrajectories) {
88 trajectories -= dominatedTrajectory
89 val dominatedSolution = dominatedTrajectory.solution
90 if (!dominatedSolution.trajectories.remove(dominatedTrajectory)) {
91 throw new DSEException(
92 "Dominated solution is not reachable from dominated trajectory. This should never happen!")
93 }
94 if (dominatedSolution.trajectories.empty) {
95 val dominatedSolutionId = dominatedSolution.stateCode
96 solutionCopier.markAsObsolete(dominatedSolutionId)
97 solutionsCollection -= dominatedSolutionId
98 }
99 }
100 solutionSaved
101 }
102
103 private def saveAnyDiverseSolution(ThreadContext context, Object id, SolutionTrajectory solutionTrajectory) {
104 val fitness = context.lastFitness
105 if (!shouldSaveSolution(fitness, context)) {
106 return false
107 }
108 if (!diversityChecker.newSolution(context, id, emptyList)) {
109 return false
110 }
111 basicSaveSolution(context, id, solutionTrajectory, fitness)
112 }
113
114 private def shouldSaveSolution(Fitness fitness, ThreadContext context) {
115 fitness.satisifiesHardObjectives && (numericSolver === null || numericSolver.currentSatisfiable)
116 }
117
118 private def basicSaveSolution(ThreadContext context, Object id, SolutionTrajectory solutionTrajectory,
119 Fitness fitness) {
120 var boolean solutionSaved = false
121 var dseSolution = solutionsCollection.get(id)
122 if (dseSolution === null) {
123 solutionCopier.copySolution(context, id)
124 dseSolution = new Solution(id, solutionTrajectory)
125 solutionsCollection.put(id, dseSolution)
126 solutionSaved = true
127 } else {
128 solutionSaved = dseSolution.trajectories.add(solutionTrajectory)
129 }
130 if (solutionSaved) {
131 solutionTrajectory.solution = dseSolution
132 trajectories.put(solutionTrajectory, fitness)
133 }
134 solutionSaved
135 }
136
137 def fitnessMayBeSaved(Fitness fitness) {
138 if (!hasExtremalObjectives) {
139 return true
140 }
141 var boolean mayDominate
142 for (existingFitness : trajectories.values) {
143 val isNewFitnessBetter = comparatorHelper.compare(fitness, existingFitness)
144 if (isNewFitnessBetter < 0) {
145 return false
146 }
147 if (isNewFitnessBetter > 0) {
148 mayDominate = true
149 }
150 }
151 mayDominate || needsMoreSolutionsWithSameFitness
152 }
153
154 private def boolean needsMoreSolutionsWithSameFitness() {
155 if (solutionsCollection === null) {
156 // The solutions collection will only be initialized upon saving the first solution.
157 return true
158 }
159 solutionsCollection.size < numberOfRequiredSolutions
160 }
161
162 def getTotalCopierRuntime() {
163 solutionCopier.totalCopierRuntime
164 }
165
166 override computeRequiredBounds(IObjective objective, Bounds bounds) {
167 if (!hasExtremalObjectives) {
168 return
169 }
170 if (objective instanceof DirectionalThresholdObjective) {
171 switch (threshold : objective.threshold) {
172 case ObjectiveThreshold.NO_THRESHOLD: {
173 // No threshold to set.
174 }
175 ObjectiveThreshold.Exclusive: {
176 switch (kind : objective.kind) {
177 case HIGHER_IS_BETTER:
178 bounds.tightenLowerBound(Math.floor(threshold.threshold + 1) as int)
179 case LOWER_IS_BETTER:
180 bounds.tightenUpperBound(Math.ceil(threshold.threshold - 1) as int)
181 default:
182 throw new IllegalArgumentException("Unknown objective kind" + kind)
183 }
184 if (threshold.clampToThreshold) {
185 return
186 }
187 }
188 ObjectiveThreshold.Inclusive: {
189 switch (kind : objective.kind) {
190 case HIGHER_IS_BETTER:
191 bounds.tightenLowerBound(Math.ceil(threshold.threshold) as int)
192 case LOWER_IS_BETTER:
193 bounds.tightenUpperBound(Math.floor(threshold.threshold) as int)
194 default:
195 throw new IllegalArgumentException("Unknown objective kind" + kind)
196 }
197 if (threshold.clampToThreshold) {
198 return
199 }
200 }
201 default:
202 throw new IllegalArgumentException("Unknown threshold: " + threshold)
203 }
204 for (level : leveledExtremalObjectives) {
205 switch (level.size) {
206 case 0: {
207 // Nothing to do, wait for the next level.
208 }
209 case 1: {
210 val primaryObjective = level.get(0)
211 if (primaryObjective != objective) {
212 // There are no worst-case bounds for secondary objectives.
213 return
214 }
215 }
216 default:
217 // There are no worst-case bounds for Pareto front calculation.
218 return
219 }
220 }
221 val fitnessIterator = trajectories.values.iterator
222 if (!fitnessIterator.hasNext) {
223 return
224 }
225 val fitness = fitnessIterator.next.get(objective.name)
226 while (fitnessIterator.hasNext) {
227 val otherFitness = fitnessIterator.next.get(objective.name)
228 if (Math.abs(fitness - otherFitness) > TOLERANCE) {
229 throw new IllegalStateException("Inconsistent fitness: " + objective.name)
230 }
231 }
232 switch (kind : objective.kind) {
233 case HIGHER_IS_BETTER:
234 if (needsMoreSolutionsWithSameFitness) {
235 bounds.tightenLowerBound(Math.floor(fitness) as int)
236 } else {
237 bounds.tightenLowerBound(Math.floor(fitness + 1) as int)
238 }
239 case LOWER_IS_BETTER:
240 if (needsMoreSolutionsWithSameFitness) {
241 bounds.tightenUpperBound(Math.ceil(fitness) as int)
242 } else {
243 bounds.tightenUpperBound(Math.ceil(fitness - 1) as int)
244 }
245 default:
246 throw new IllegalArgumentException("Unknown objective kind" + kind)
247 }
248 }
249 }
250}
diff --git a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/WF2ObjectiveConverter.xtend b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/WF2ObjectiveConverter.xtend
index 5a528a9e..6d772f32 100644
--- a/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/WF2ObjectiveConverter.xtend
+++ b/Solvers/VIATRA-Solver/hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner/src/hu/bme/mit/inf/dslreasoner/viatrasolver/reasoner/dse/WF2ObjectiveConverter.xtend
@@ -1,5 +1,6 @@
1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse 1package hu.bme.mit.inf.dslreasoner.viatrasolver.reasoner.dse
2 2
3import com.google.common.collect.ImmutableList
3import java.util.ArrayList 4import java.util.ArrayList
4import java.util.Collection 5import java.util.Collection
5import org.eclipse.viatra.dse.objectives.Comparators 6import org.eclipse.viatra.dse.objectives.Comparators
@@ -12,25 +13,33 @@ import org.eclipse.viatra.query.runtime.api.IQuerySpecification
12import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher 13import org.eclipse.viatra.query.runtime.api.ViatraQueryMatcher
13 14
14class WF2ObjectiveConverter { 15class WF2ObjectiveConverter {
15 16 static val INVALIDATED_WFS_NAME = "invalidatedWFs"
17
16 def createCompletenessObjective( 18 def createCompletenessObjective(
17 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> unfinishedWF) 19 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> unfinishedWF) {
18 { 20 new UnfinishedWFObjective(unfinishedWF)
19 val res = new ConstraintsObjective('''unfinishedWFs''', 21 }
20 unfinishedWF.map[ 22
21 new QueryConstraint(it.fullyQualifiedName,it,2.0) 23 def createInvalidationObjective(
22 ].toList 24 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> invalidatedByWF) {
25 createConstraintObjective(INVALIDATED_WFS_NAME, invalidatedByWF)
26 }
27
28 def IGlobalConstraint createInvalidationGlobalConstraint(
29 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> invalidatedByWF) {
30 new ModelQueriesGlobalConstraint(INVALIDATED_WFS_NAME, new ArrayList(invalidatedByWF))
31 }
32
33 private def createConstraintObjective(String name,
34 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> queries) {
35 val res = new ConstraintsObjective(
36 name,
37 ImmutableList.copyOf(queries.map [
38 new QueryConstraint(it.fullyQualifiedName, it, 1.0)
39 ])
23 ) 40 )
24 res.withComparator(Comparators.LOWER_IS_BETTER) 41 res.withComparator(Comparators.LOWER_IS_BETTER)
25 res.level = 2 42 res.level = 2
26 return res 43 res
27 }
28
29 def IGlobalConstraint createInvalidationObjective(
30 Collection<? extends IQuerySpecification<? extends ViatraQueryMatcher<? extends IPatternMatch>>> invalidatedByWF)
31 {
32 return new ModelQueriesGlobalConstraint('''invalidatedWFs''',
33 new ArrayList(invalidatedByWF)
34 )
35 } 44 }
36} \ No newline at end of file 45}