diff options
Diffstat (limited to 'subprojects/store-dse/src')
9 files changed, 161 insertions, 76 deletions
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/DesignSpaceExplorationAdapter.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/DesignSpaceExplorationAdapter.java index 8963a496..c4aa97c2 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/DesignSpaceExplorationAdapter.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/DesignSpaceExplorationAdapter.java | |||
@@ -38,7 +38,9 @@ public interface DesignSpaceExplorationAdapter extends ModelAdapter { | |||
38 | 38 | ||
39 | public boolean backtrack(); | 39 | public boolean backtrack(); |
40 | 40 | ||
41 | public Fitness calculateFitness(); | 41 | public boolean backtrack(String reason); |
42 | |||
43 | public Fitness getFitness(); | ||
42 | 44 | ||
43 | public void newSolution(); | 45 | public void newSolution(); |
44 | 46 | ||
@@ -63,4 +65,6 @@ public interface DesignSpaceExplorationAdapter extends ModelAdapter { | |||
63 | public void setRandom(Random random); | 65 | public void setRandom(Random random); |
64 | 66 | ||
65 | public void setRandom(long seed); | 67 | public void setRandom(long seed); |
68 | |||
69 | public List<Version> getSolutions(); | ||
66 | } | 70 | } |
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/DesignSpaceExplorationStoreAdapter.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/DesignSpaceExplorationStoreAdapter.java index 186bfebb..0252748d 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/DesignSpaceExplorationStoreAdapter.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/DesignSpaceExplorationStoreAdapter.java | |||
@@ -6,6 +6,24 @@ | |||
6 | package tools.refinery.store.dse; | 6 | package tools.refinery.store.dse; |
7 | 7 | ||
8 | import tools.refinery.store.adapter.ModelStoreAdapter; | 8 | import tools.refinery.store.adapter.ModelStoreAdapter; |
9 | import tools.refinery.store.dse.internal.TransformationRule; | ||
10 | import tools.refinery.store.dse.objectives.Objective; | ||
11 | import tools.refinery.store.model.Model; | ||
12 | import tools.refinery.store.query.dnf.RelationalQuery; | ||
13 | |||
14 | import java.util.List; | ||
15 | import java.util.Set; | ||
9 | 16 | ||
10 | public interface DesignSpaceExplorationStoreAdapter extends ModelStoreAdapter { | 17 | public interface DesignSpaceExplorationStoreAdapter extends ModelStoreAdapter { |
18 | |||
19 | @Override | ||
20 | DesignSpaceExplorationAdapter createModelAdapter(Model model); | ||
21 | |||
22 | Set<TransformationRule> getTransformationSpecifications(); | ||
23 | |||
24 | Set<RelationalQuery> getGlobalConstraints(); | ||
25 | |||
26 | List<Objective> getObjectives(); | ||
27 | |||
28 | Strategy getStrategy(); | ||
11 | } | 29 | } |
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/Strategy.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/Strategy.java index e240f478..409fe8a6 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/Strategy.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/Strategy.java | |||
@@ -7,7 +7,7 @@ package tools.refinery.store.dse; | |||
7 | 7 | ||
8 | public interface Strategy { | 8 | public interface Strategy { |
9 | 9 | ||
10 | public void initStrategy(DesignSpaceExplorationAdapter designSpaceExplorationAdapter); | 10 | void initStrategy(DesignSpaceExplorationAdapter designSpaceExplorationAdapter); |
11 | 11 | ||
12 | public void explore(); | 12 | void explore(); |
13 | } | 13 | } |
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationAdapterImpl.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationAdapterImpl.java index b32e9696..4e5cc467 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationAdapterImpl.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationAdapterImpl.java | |||
@@ -33,26 +33,28 @@ public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExploration | |||
33 | private final Model model; | 33 | private final Model model; |
34 | private final ModelQueryAdapter queryEngine; | 34 | private final ModelQueryAdapter queryEngine; |
35 | private final DesignSpaceExplorationStoreAdapterImpl storeAdapter; | 35 | private final DesignSpaceExplorationStoreAdapterImpl storeAdapter; |
36 | private final LinkedHashSet<TransformationRule> transformationRules; | 36 | private final Set<TransformationRule> transformationRules; |
37 | private final LinkedHashSet<RelationalQuery> globalConstraints; | 37 | private final Set<RelationalQuery> globalConstraints; |
38 | private final List<Objective> objectives; | 38 | private final List<Objective> objectives; |
39 | private final LinkedHashSet<ResultSet<Boolean>> globalConstraintResultSets = new LinkedHashSet<>(); | 39 | private final LinkedHashSet<ResultSet<Boolean>> globalConstraintResultSets = new LinkedHashSet<>(); |
40 | private final Interpretation<Integer> sizeInterpretation; | 40 | private final Interpretation<Integer> sizeInterpretation; |
41 | private final Strategy strategy; | 41 | private final Strategy strategy; |
42 | 42 | ||
43 | private ObjectiveComparatorHelper objectiveComparatorHelper; | 43 | private ObjectiveComparatorHelper objectiveComparatorHelper; |
44 | private List<Version> trajectory = new LinkedList<>(); | 44 | private List<Version> trajectory = new ArrayList<>(); |
45 | private Map<Version, Version> parents = new HashMap<>(); | ||
45 | private Fitness lastFitness; | 46 | private Fitness lastFitness; |
46 | private final LinkedHashSet<Version> solutions = new LinkedHashSet<>(); | 47 | private final List<Version> solutions = new ArrayList<>(); |
47 | private Map<Version, LinkedHashSet<Activation>> statesAndUntraversedActivations; | 48 | private Map<Version, List<Activation>> statesAndTraversedActivations; |
48 | private Map<Version, LinkedHashSet<Activation>> statesAndTraversedActivations; | ||
49 | private Random random = new Random(); | 49 | private Random random = new Random(); |
50 | private boolean isNewState = false; | 50 | private boolean isNewState = false; |
51 | private final boolean isVisualizationEnabled; | 51 | private final boolean isVisualizationEnabled; |
52 | private final ModelVisualizerAdapter modelVisualizerAdapter; | 52 | private final ModelVisualizerAdapter modelVisualizerAdapter; |
53 | 53 | ||
54 | private final Map<Version, Fitness> fitnessCache = new HashMap<>(); | ||
55 | |||
54 | public List<Version> getTrajectory() { | 56 | public List<Version> getTrajectory() { |
55 | return new LinkedList<>(trajectory); | 57 | return new ArrayList<>(trajectory); |
56 | } | 58 | } |
57 | 59 | ||
58 | public DesignSpaceExplorationAdapterImpl(Model model, DesignSpaceExplorationStoreAdapterImpl storeAdapter) { | 60 | public DesignSpaceExplorationAdapterImpl(Model model, DesignSpaceExplorationStoreAdapterImpl storeAdapter) { |
@@ -72,7 +74,6 @@ public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExploration | |||
72 | } | 74 | } |
73 | 75 | ||
74 | objectives = storeAdapter.getObjectives(); | 76 | objectives = storeAdapter.getObjectives(); |
75 | statesAndUntraversedActivations = new HashMap<>(); | ||
76 | statesAndTraversedActivations = new HashMap<>(); | 77 | statesAndTraversedActivations = new HashMap<>(); |
77 | strategy = storeAdapter.getStrategy(); | 78 | strategy = storeAdapter.getStrategy(); |
78 | modelVisualizerAdapter = model.tryGetAdapter(ModelVisualizerAdapter.class).orElse(null); | 79 | modelVisualizerAdapter = model.tryGetAdapter(ModelVisualizerAdapter.class).orElse(null); |
@@ -91,11 +92,9 @@ public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExploration | |||
91 | } | 92 | } |
92 | 93 | ||
93 | @Override | 94 | @Override |
94 | public LinkedHashSet<Version> explore() { | 95 | public List<Version> explore() { |
95 | var state = model.commit(); | 96 | var state = model.commit(); |
96 | trajectory.add(state); | 97 | trajectory.add(state); |
97 | statesAndUntraversedActivations.put(state, getAllActivations()); | ||
98 | statesAndTraversedActivations.put(state, new LinkedHashSet<>()); | ||
99 | strategy.initStrategy(this); | 98 | strategy.initStrategy(this); |
100 | strategy.explore(); | 99 | strategy.explore(); |
101 | return solutions; | 100 | return solutions; |
@@ -137,14 +136,22 @@ public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExploration | |||
137 | 136 | ||
138 | @Override | 137 | @Override |
139 | public boolean backtrack() { | 138 | public boolean backtrack() { |
139 | return backtrack(""); | ||
140 | } | ||
141 | @Override | ||
142 | public boolean backtrack(String reason) { | ||
140 | if (trajectory.size() < 2) { | 143 | if (trajectory.size() < 2) { |
141 | return false; | 144 | return false; |
142 | } | 145 | } |
146 | var currentState = model.getState(); | ||
147 | if (!parents.containsKey(currentState)) { | ||
148 | return false; | ||
149 | } | ||
143 | if (isVisualizationEnabled) { | 150 | if (isVisualizationEnabled) { |
144 | modelVisualizerAdapter.addTransition(trajectory.get(trajectory.size() - 1), | 151 | modelVisualizerAdapter.addTransition(trajectory.get(trajectory.size() - 1), |
145 | trajectory.get(trajectory.size() - 2), "backtrack"); | 152 | trajectory.get(trajectory.size() - 2), "backtrack(" + reason + ")"); |
146 | } | 153 | } |
147 | model.restore(trajectory.get(trajectory.size() - 2)); | 154 | model.restore(parents.get(model.getState())); |
148 | trajectory.remove(trajectory.size() - 1); | 155 | trajectory.remove(trajectory.size() - 1); |
149 | return true; | 156 | return true; |
150 | } | 157 | } |
@@ -156,7 +163,7 @@ public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExploration | |||
156 | // modelVisualizerAdapter.addTransition(this.trajectory.get(trajectory.size() - 1), | 163 | // modelVisualizerAdapter.addTransition(this.trajectory.get(trajectory.size() - 1), |
157 | // trajectory.get(trajectory.size() - 1), "restore"); | 164 | // trajectory.get(trajectory.size() - 1), "restore"); |
158 | // } | 165 | // } |
159 | this.trajectory = trajectory; | 166 | this.trajectory = new ArrayList<>(trajectory); |
160 | 167 | ||
161 | } | 168 | } |
162 | 169 | ||
@@ -171,7 +178,18 @@ public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExploration | |||
171 | } | 178 | } |
172 | 179 | ||
173 | @Override | 180 | @Override |
174 | public Fitness calculateFitness() { | 181 | public List<Version> getSolutions() { |
182 | return solutions; | ||
183 | } | ||
184 | |||
185 | @Override | ||
186 | public Fitness getFitness() { | ||
187 | var result = fitnessCache.computeIfAbsent(model.getState(), s -> calculateFitness()); | ||
188 | lastFitness = result; | ||
189 | return result; | ||
190 | } | ||
191 | |||
192 | private Fitness calculateFitness() { | ||
175 | Fitness result = new Fitness(); | 193 | Fitness result = new Fitness(); |
176 | boolean satisfiesHardObjectives = true; | 194 | boolean satisfiesHardObjectives = true; |
177 | for (Objective objective : objectives) { | 195 | for (Objective objective : objectives) { |
@@ -203,15 +221,19 @@ public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExploration | |||
203 | } | 221 | } |
204 | 222 | ||
205 | public LinkedHashSet<Activation> getUntraversedActivations() { | 223 | public LinkedHashSet<Activation> getUntraversedActivations() { |
206 | // return statesAndUntraversedActivations.get(model.getState()); | 224 | var traversedActivations = statesAndTraversedActivations.get(model.getState()); |
207 | LinkedHashSet<Activation> untraversedActivations = new LinkedHashSet<>(); | 225 | if (traversedActivations == null) { |
208 | for (Activation activation : getAllActivations()) { | 226 | return new LinkedHashSet<>(getAllActivations()); |
209 | if (!statesAndTraversedActivations.get(model.getState()).contains(activation)) { | 227 | } |
210 | untraversedActivations.add(activation); | 228 | else { |
229 | LinkedHashSet<Activation> untraversedActivations = new LinkedHashSet<>(); | ||
230 | for (Activation activation : getAllActivations()) { | ||
231 | if (!traversedActivations.contains(activation)) { | ||
232 | untraversedActivations.add(activation); | ||
233 | } | ||
211 | } | 234 | } |
235 | return untraversedActivations; | ||
212 | } | 236 | } |
213 | |||
214 | return untraversedActivations; | ||
215 | } | 237 | } |
216 | 238 | ||
217 | @Override | 239 | @Override |
@@ -220,26 +242,20 @@ public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExploration | |||
220 | return false; | 242 | return false; |
221 | } | 243 | } |
222 | var previousState = model.getState(); | 244 | var previousState = model.getState(); |
223 | if (!statesAndUntraversedActivations.get(previousState).contains(activation)) { | ||
224 | // TODO: throw exception? | ||
225 | return false; | ||
226 | } | ||
227 | if (!activation.fire()) { | 245 | if (!activation.fire()) { |
228 | return false; | 246 | return false; |
229 | } | 247 | } |
230 | statesAndUntraversedActivations.get(previousState).remove(activation); | 248 | statesAndTraversedActivations.computeIfAbsent(previousState, s -> new ArrayList<>()).add(activation); |
231 | statesAndTraversedActivations.get(previousState).add(activation); | ||
232 | var newState = model.commit(); | 249 | var newState = model.commit(); |
233 | trajectory.add(newState); | 250 | trajectory.add(newState); |
234 | isNewState = !statesAndUntraversedActivations.containsKey(newState); | 251 | parents.put(newState, previousState); |
235 | statesAndUntraversedActivations.put(newState, getAllActivations()); | 252 | isNewState = !statesAndTraversedActivations.containsKey(newState); |
236 | statesAndTraversedActivations.put(newState, new LinkedHashSet<>()); | ||
237 | if (isVisualizationEnabled) { | 253 | if (isVisualizationEnabled) { |
238 | if (isNewState) { | 254 | if (isNewState) { |
239 | modelVisualizerAdapter.addState(newState); | 255 | modelVisualizerAdapter.addState(newState); |
240 | } | 256 | } |
241 | modelVisualizerAdapter.addTransition(trajectory.get(trajectory.size() - 2), | 257 | // TODO: Change to this: |
242 | trajectory.get(trajectory.size() - 1), activation.transformationRule().getName(), | 258 | modelVisualizerAdapter.addTransition(previousState, newState, activation.transformationRule().getName(), |
243 | activation.activation()); | 259 | activation.activation()); |
244 | } | 260 | } |
245 | return true; | 261 | return true; |
@@ -266,10 +282,10 @@ public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExploration | |||
266 | return trajectory.contains(model.getState()); | 282 | return trajectory.contains(model.getState()); |
267 | } | 283 | } |
268 | 284 | ||
269 | public LinkedHashSet<Activation> getAllActivations() { | 285 | public List<Activation> getAllActivations() { |
270 | LinkedHashSet<Activation> result = new LinkedHashSet<>(); | 286 | List<Activation> result = new LinkedList<>(); |
271 | for (var rule : transformationRules) { | 287 | for (var rule : transformationRules) { |
272 | result.addAll(rule.getAllActivations()); | 288 | result.addAll(rule.getAllActivationsAsList()); |
273 | } | 289 | } |
274 | return result; | 290 | return result; |
275 | } | 291 | } |
@@ -279,10 +295,6 @@ public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExploration | |||
279 | return !isNewState; | 295 | return !isNewState; |
280 | } | 296 | } |
281 | 297 | ||
282 | public Fitness getLastFitness() { | ||
283 | return lastFitness; | ||
284 | } | ||
285 | |||
286 | public ObjectiveComparatorHelper getObjectiveComparatorHelper() { | 298 | public ObjectiveComparatorHelper getObjectiveComparatorHelper() { |
287 | if (objectiveComparatorHelper == null) { | 299 | if (objectiveComparatorHelper == null) { |
288 | objectiveComparatorHelper = new ObjectiveComparatorHelper(objectives); | 300 | objectiveComparatorHelper = new ObjectiveComparatorHelper(objectives); |
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationStoreAdapterImpl.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationStoreAdapterImpl.java index 09925ae7..fea39886 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationStoreAdapterImpl.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationStoreAdapterImpl.java | |||
@@ -5,27 +5,26 @@ | |||
5 | */ | 5 | */ |
6 | package tools.refinery.store.dse.internal; | 6 | package tools.refinery.store.dse.internal; |
7 | 7 | ||
8 | import tools.refinery.store.adapter.ModelAdapter; | ||
9 | import tools.refinery.store.model.Model; | ||
10 | import tools.refinery.store.model.ModelStore; | ||
11 | import tools.refinery.store.query.dnf.RelationalQuery; | ||
12 | import tools.refinery.store.dse.DesignSpaceExplorationStoreAdapter; | 8 | import tools.refinery.store.dse.DesignSpaceExplorationStoreAdapter; |
13 | import tools.refinery.store.dse.Strategy; | 9 | import tools.refinery.store.dse.Strategy; |
14 | import tools.refinery.store.dse.objectives.Objective; | 10 | import tools.refinery.store.dse.objectives.Objective; |
11 | import tools.refinery.store.model.Model; | ||
12 | import tools.refinery.store.model.ModelStore; | ||
13 | import tools.refinery.store.query.dnf.RelationalQuery; | ||
15 | 14 | ||
16 | import java.util.LinkedHashSet; | ||
17 | import java.util.List; | 15 | import java.util.List; |
16 | import java.util.Set; | ||
18 | 17 | ||
19 | public class DesignSpaceExplorationStoreAdapterImpl implements DesignSpaceExplorationStoreAdapter { | 18 | public class DesignSpaceExplorationStoreAdapterImpl implements DesignSpaceExplorationStoreAdapter { |
20 | private final ModelStore store; | 19 | private final ModelStore store; |
21 | private final LinkedHashSet<TransformationRule> transformationSpecifications; | 20 | private final Set<TransformationRule> transformationSpecifications; |
22 | private final LinkedHashSet<RelationalQuery> globalConstraints; | 21 | private final Set<RelationalQuery> globalConstraints; |
23 | private final List<Objective> objectives; | 22 | private final List<Objective> objectives; |
24 | private final Strategy strategy; | 23 | private final Strategy strategy; |
25 | 24 | ||
26 | public DesignSpaceExplorationStoreAdapterImpl(ModelStore store, | 25 | public DesignSpaceExplorationStoreAdapterImpl(ModelStore store, |
27 | LinkedHashSet<TransformationRule> transformationSpecifications, | 26 | Set<TransformationRule> transformationSpecifications, |
28 | LinkedHashSet<RelationalQuery> globalConstraints, | 27 | Set<RelationalQuery> globalConstraints, |
29 | List<Objective> objectives, Strategy strategy) { | 28 | List<Objective> objectives, Strategy strategy) { |
30 | this.store = store; | 29 | this.store = store; |
31 | this.transformationSpecifications = transformationSpecifications; | 30 | this.transformationSpecifications = transformationSpecifications; |
@@ -40,22 +39,26 @@ public class DesignSpaceExplorationStoreAdapterImpl implements DesignSpaceExplor | |||
40 | } | 39 | } |
41 | 40 | ||
42 | @Override | 41 | @Override |
43 | public ModelAdapter createModelAdapter(Model model) { | 42 | public DesignSpaceExplorationAdapterImpl createModelAdapter(Model model) { |
44 | return new DesignSpaceExplorationAdapterImpl(model, this); | 43 | return new DesignSpaceExplorationAdapterImpl(model, this); |
45 | } | 44 | } |
46 | 45 | ||
47 | public LinkedHashSet<TransformationRule> getTransformationSpecifications() { | 46 | @Override |
47 | public Set<TransformationRule> getTransformationSpecifications() { | ||
48 | return transformationSpecifications; | 48 | return transformationSpecifications; |
49 | } | 49 | } |
50 | 50 | ||
51 | public LinkedHashSet<RelationalQuery> getGlobalConstraints() { | 51 | @Override |
52 | public Set<RelationalQuery> getGlobalConstraints() { | ||
52 | return globalConstraints; | 53 | return globalConstraints; |
53 | } | 54 | } |
54 | 55 | ||
56 | @Override | ||
55 | public List<Objective> getObjectives() { | 57 | public List<Objective> getObjectives() { |
56 | return objectives; | 58 | return objectives; |
57 | } | 59 | } |
58 | 60 | ||
61 | @Override | ||
59 | public Strategy getStrategy() { | 62 | public Strategy getStrategy() { |
60 | return strategy; | 63 | return strategy; |
61 | } | 64 | } |
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/TransformationRule.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/TransformationRule.java index 015d4815..8123c0d6 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/TransformationRule.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/TransformationRule.java | |||
@@ -14,8 +14,7 @@ import tools.refinery.store.query.resultset.OrderedResultSet; | |||
14 | import tools.refinery.store.query.resultset.ResultSet; | 14 | import tools.refinery.store.query.resultset.ResultSet; |
15 | import tools.refinery.store.tuple.Tuple; | 15 | import tools.refinery.store.tuple.Tuple; |
16 | 16 | ||
17 | import java.util.LinkedHashSet; | 17 | import java.util.*; |
18 | import java.util.Random; | ||
19 | 18 | ||
20 | public class TransformationRule { | 19 | public class TransformationRule { |
21 | 20 | ||
@@ -66,11 +65,11 @@ public class TransformationRule { | |||
66 | return precondition; | 65 | return precondition; |
67 | } | 66 | } |
68 | 67 | ||
69 | public ResultSet<Boolean> getAllActivationsAsSets() { | 68 | public ResultSet<Boolean> getAllActivationsAsResultSet() { |
70 | return activations; | 69 | return activations; |
71 | } | 70 | } |
72 | 71 | ||
73 | public LinkedHashSet<Activation> getAllActivations() { | 72 | public Set<Activation> getAllActivations() { |
74 | var result = new LinkedHashSet<Activation>(); | 73 | var result = new LinkedHashSet<Activation>(); |
75 | var cursor = activations.getAll(); | 74 | var cursor = activations.getAll(); |
76 | while (cursor.move()) { | 75 | while (cursor.move()) { |
@@ -79,6 +78,15 @@ public class TransformationRule { | |||
79 | return result; | 78 | return result; |
80 | } | 79 | } |
81 | 80 | ||
81 | public List<Activation> getAllActivationsAsList() { | ||
82 | var result = new ArrayList<Activation>(); | ||
83 | var cursor = activations.getAll(); | ||
84 | while (cursor.move()) { | ||
85 | result.add(new Activation(this, cursor.getKey())); | ||
86 | } | ||
87 | return result; | ||
88 | } | ||
89 | |||
82 | public Activation getRandomActivation() { | 90 | public Activation getRandomActivation() { |
83 | return new Activation(this, activations.getKey(random.nextInt(activations.size()))); | 91 | return new Activation(this, activations.getKey(random.nextInt(activations.size()))); |
84 | } | 92 | } |
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstStrategy.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstStrategy.java index 8648864c..57f86401 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstStrategy.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstStrategy.java | |||
@@ -26,6 +26,7 @@ public class BestFirstStrategy implements Strategy { | |||
26 | private DesignSpaceExplorationAdapter dseAdapter; | 26 | private DesignSpaceExplorationAdapter dseAdapter; |
27 | 27 | ||
28 | private int maxDepth; | 28 | private int maxDepth; |
29 | private int maxSolutions; | ||
29 | private boolean backTrackIfSolution = true; | 30 | private boolean backTrackIfSolution = true; |
30 | private boolean onlyBetterFirst = false; | 31 | private boolean onlyBetterFirst = false; |
31 | 32 | ||
@@ -54,11 +55,20 @@ public class BestFirstStrategy implements Strategy { | |||
54 | } | 55 | } |
55 | 56 | ||
56 | public BestFirstStrategy(int maxDepth) { | 57 | public BestFirstStrategy(int maxDepth) { |
58 | this(maxDepth, -1); | ||
59 | } | ||
60 | |||
61 | public BestFirstStrategy(int maxDepth, int maxSolutions) { | ||
57 | if (maxDepth < 0) { | 62 | if (maxDepth < 0) { |
58 | this.maxDepth = Integer.MAX_VALUE; | 63 | this.maxDepth = Integer.MAX_VALUE; |
59 | } else { | 64 | } else { |
60 | this.maxDepth = maxDepth; | 65 | this.maxDepth = maxDepth; |
61 | } | 66 | } |
67 | if (maxSolutions < 0) { | ||
68 | this.maxSolutions = Integer.MAX_VALUE; | ||
69 | } else { | ||
70 | this.maxSolutions = maxSolutions; | ||
71 | } | ||
62 | } | 72 | } |
63 | 73 | ||
64 | public BestFirstStrategy continueIfHardObjectivesFulfilled() { | 74 | public BestFirstStrategy continueIfHardObjectivesFulfilled() { |
@@ -76,12 +86,15 @@ public class BestFirstStrategy implements Strategy { | |||
76 | this.dseAdapter = designSpaceExplorationAdapter; | 86 | this.dseAdapter = designSpaceExplorationAdapter; |
77 | final ObjectiveComparatorHelper objectiveComparatorHelper = dseAdapter.getObjectiveComparatorHelper(); | 87 | final ObjectiveComparatorHelper objectiveComparatorHelper = dseAdapter.getObjectiveComparatorHelper(); |
78 | 88 | ||
79 | trajectoriesToExplore = new PriorityQueue<TrajectoryWithFitness>(11, | 89 | trajectoriesToExplore = new PriorityQueue<>(11, |
80 | (o1, o2) -> objectiveComparatorHelper.compare(o2.fitness, o1.fitness)); | 90 | (o1, o2) -> objectiveComparatorHelper.compare(o2.fitness, o1.fitness)); |
81 | } | 91 | } |
82 | 92 | ||
83 | @Override | 93 | @Override |
84 | public void explore() { | 94 | public void explore() { |
95 | if (maxSolutions == 0) { | ||
96 | return; | ||
97 | } | ||
85 | final ObjectiveComparatorHelper objectiveComparatorHelper = dseAdapter.getObjectiveComparatorHelper(); | 98 | final ObjectiveComparatorHelper objectiveComparatorHelper = dseAdapter.getObjectiveComparatorHelper(); |
86 | 99 | ||
87 | boolean globalConstraintsAreSatisfied = dseAdapter.checkGlobalConstraints(); | 100 | boolean globalConstraintsAreSatisfied = dseAdapter.checkGlobalConstraints(); |
@@ -90,7 +103,7 @@ public class BestFirstStrategy implements Strategy { | |||
90 | return; | 103 | return; |
91 | } | 104 | } |
92 | 105 | ||
93 | final Fitness firstFitness = dseAdapter.calculateFitness(); | 106 | final Fitness firstFitness = dseAdapter.getFitness(); |
94 | if (firstFitness.isSatisfiesHardObjectives()) { | 107 | if (firstFitness.isSatisfiesHardObjectives()) { |
95 | dseAdapter.newSolution(); | 108 | dseAdapter.newSolution(); |
96 | // "First state is a solution. Terminate."); | 109 | // "First state is a solution. Terminate."); |
@@ -103,9 +116,16 @@ public class BestFirstStrategy implements Strategy { | |||
103 | return; | 116 | return; |
104 | } | 117 | } |
105 | 118 | ||
106 | final List<Version> firstTrajectory = dseAdapter.getTrajectory(); | 119 | // final List<Version> firstTrajectory = dseAdapter.getTrajectory(); |
107 | TrajectoryWithFitness currentTrajectoryWithFitness = new TrajectoryWithFitness(firstTrajectory, firstFitness); | 120 | |
108 | trajectoriesToExplore.add(currentTrajectoryWithFitness); | 121 | // TrajectoryWithFitness currentTrajectoryWithFitness = new TrajectoryWithFitness(dseAdapter.getTrajectory(), |
122 | // firstFitness); | ||
123 | // trajectoriesToExplore.add(currentTrajectoryWithFitness); | ||
124 | |||
125 | |||
126 | var firstTrajectoryWithFitness = new TrajectoryWithFitness(dseAdapter.getTrajectory(), firstFitness); | ||
127 | trajectoriesToExplore.add(firstTrajectoryWithFitness); | ||
128 | TrajectoryWithFitness currentTrajectoryWithFitness = null; | ||
109 | 129 | ||
110 | mainLoop: while (true) { | 130 | mainLoop: while (true) { |
111 | 131 | ||
@@ -145,9 +165,13 @@ public class BestFirstStrategy implements Strategy { | |||
145 | // "Global constraint is not satisfied."); | 165 | // "Global constraint is not satisfied."); |
146 | dseAdapter.backtrack(); | 166 | dseAdapter.backtrack(); |
147 | } else { | 167 | } else { |
148 | final Fitness nextFitness = dseAdapter.calculateFitness(); | 168 | final Fitness nextFitness = dseAdapter.getFitness(); |
149 | if (nextFitness.isSatisfiesHardObjectives()) { | 169 | if (nextFitness.isSatisfiesHardObjectives()) { |
150 | dseAdapter.newSolution(); | 170 | dseAdapter.newSolution(); |
171 | var solutions = dseAdapter.getSolutions().size(); | ||
172 | if (solutions >= maxSolutions) { | ||
173 | return; | ||
174 | } | ||
151 | // "Found a solution."); | 175 | // "Found a solution."); |
152 | if (backTrackIfSolution) { | 176 | if (backTrackIfSolution) { |
153 | dseAdapter.backtrack(); | 177 | dseAdapter.backtrack(); |
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/DepthFirstStrategy.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/DepthFirstStrategy.java index 1405789b..f4a0747a 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/DepthFirstStrategy.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/DepthFirstStrategy.java | |||
@@ -21,6 +21,7 @@ public class DepthFirstStrategy implements Strategy { | |||
21 | private DesignSpaceExplorationAdapter dseAdapter; | 21 | private DesignSpaceExplorationAdapter dseAdapter; |
22 | 22 | ||
23 | private int maxDepth; | 23 | private int maxDepth; |
24 | private int maxSolutions; | ||
24 | private boolean backTrackIfSolution = true; | 25 | private boolean backTrackIfSolution = true; |
25 | 26 | ||
26 | public DepthFirstStrategy() { | 27 | public DepthFirstStrategy() { |
@@ -28,11 +29,20 @@ public class DepthFirstStrategy implements Strategy { | |||
28 | } | 29 | } |
29 | 30 | ||
30 | public DepthFirstStrategy(int maxDepth) { | 31 | public DepthFirstStrategy(int maxDepth) { |
32 | this(maxDepth, -1); | ||
33 | } | ||
34 | |||
35 | public DepthFirstStrategy(int maxDepth, int maxSolutions) { | ||
31 | if (maxDepth < 0) { | 36 | if (maxDepth < 0) { |
32 | this.maxDepth = Integer.MAX_VALUE; | 37 | this.maxDepth = Integer.MAX_VALUE; |
33 | } else { | 38 | } else { |
34 | this.maxDepth = maxDepth; | 39 | this.maxDepth = maxDepth; |
35 | } | 40 | } |
41 | if (maxSolutions < 0) { | ||
42 | this.maxSolutions = Integer.MAX_VALUE; | ||
43 | } else { | ||
44 | this.maxSolutions = maxSolutions; | ||
45 | } | ||
36 | } | 46 | } |
37 | 47 | ||
38 | public DepthFirstStrategy continueIfHardObjectivesFulfilled() { | 48 | public DepthFirstStrategy continueIfHardObjectivesFulfilled() { |
@@ -47,6 +57,9 @@ public class DepthFirstStrategy implements Strategy { | |||
47 | 57 | ||
48 | @Override | 58 | @Override |
49 | public void explore() { | 59 | public void explore() { |
60 | if (maxSolutions == 0) { | ||
61 | return; | ||
62 | } | ||
50 | mainloop: while (true) { | 63 | mainloop: while (true) { |
51 | var globalConstraintsAreSatisfied = dseAdapter.checkGlobalConstraints(); | 64 | var globalConstraintsAreSatisfied = dseAdapter.checkGlobalConstraints(); |
52 | if (!globalConstraintsAreSatisfied) { | 65 | if (!globalConstraintsAreSatisfied) { |
@@ -61,9 +74,13 @@ public class DepthFirstStrategy implements Strategy { | |||
61 | } | 74 | } |
62 | } | 75 | } |
63 | 76 | ||
64 | Fitness fitness = dseAdapter.calculateFitness(); | 77 | Fitness fitness = dseAdapter.getFitness(); |
65 | if (fitness.isSatisfiesHardObjectives()) { | 78 | if (fitness.isSatisfiesHardObjectives()) { |
66 | dseAdapter.newSolution(); | 79 | dseAdapter.newSolution(); |
80 | var solutions = dseAdapter.getSolutions().size(); | ||
81 | if (solutions >= maxSolutions) { | ||
82 | return; | ||
83 | } | ||
67 | if (backTrackIfSolution) { | 84 | if (backTrackIfSolution) { |
68 | var isSuccessfulUndo = dseAdapter.backtrack(); | 85 | var isSuccessfulUndo = dseAdapter.backtrack(); |
69 | if (!isSuccessfulUndo) { | 86 | if (!isSuccessfulUndo) { |
@@ -76,7 +93,6 @@ public class DepthFirstStrategy implements Strategy { | |||
76 | } | 93 | } |
77 | } | 94 | } |
78 | 95 | ||
79 | var depth = dseAdapter.getDepth(); | ||
80 | if (dseAdapter.getDepth() >= maxDepth) { | 96 | if (dseAdapter.getDepth() >= maxDepth) { |
81 | var isSuccessfulUndo = dseAdapter.backtrack(); | 97 | var isSuccessfulUndo = dseAdapter.backtrack(); |
82 | if (!isSuccessfulUndo) { | 98 | if (!isSuccessfulUndo) { |
diff --git a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/TransformationRuleTest.java b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/TransformationRuleTest.java index 312bcebd..f57f68ef 100644 --- a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/TransformationRuleTest.java +++ b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/TransformationRuleTest.java | |||
@@ -137,8 +137,8 @@ public class TransformationRuleTest { | |||
137 | 137 | ||
138 | queryEngine.flushChanges(); | 138 | queryEngine.flushChanges(); |
139 | 139 | ||
140 | var assignFeatureRuleActivations = assignFeatureRule.getAllActivationsAsSets(); | 140 | var assignFeatureRuleActivations = assignFeatureRule.getAllActivationsAsResultSet(); |
141 | var deleteEmptyClassRuleActivations = deleteEmptyClassRule.getAllActivationsAsSets(); | 141 | var deleteEmptyClassRuleActivations = deleteEmptyClassRule.getAllActivationsAsResultSet(); |
142 | 142 | ||
143 | assertResults(Map.of( | 143 | assertResults(Map.of( |
144 | Tuple.of(newClass1Id, newFieldId), true, | 144 | Tuple.of(newClass1Id, newFieldId), true, |
@@ -236,12 +236,12 @@ public class TransformationRuleTest { | |||
236 | assertResults(Map.of( | 236 | assertResults(Map.of( |
237 | Tuple.of(newModelId, newClass1Id), true, | 237 | Tuple.of(newModelId, newClass1Id), true, |
238 | Tuple.of(newModelId, newClass2Id), true | 238 | Tuple.of(newModelId, newClass2Id), true |
239 | ), deleteEmptyClassRule0.getAllActivationsAsSets()); | 239 | ), deleteEmptyClassRule0.getAllActivationsAsResultSet()); |
240 | 240 | ||
241 | assertResults(Map.of( | 241 | assertResults(Map.of( |
242 | Tuple.of(newModelId, newClass1Id), true, | 242 | Tuple.of(newModelId, newClass1Id), true, |
243 | Tuple.of(newModelId, newClass2Id), true | 243 | Tuple.of(newModelId, newClass2Id), true |
244 | ), deleteEmptyClassRule1.getAllActivationsAsSets()); | 244 | ), deleteEmptyClassRule1.getAllActivationsAsResultSet()); |
245 | 245 | ||
246 | assertEquals(Tuple.of(newModelId, newClass2Id), activation0); | 246 | assertEquals(Tuple.of(newModelId, newClass2Id), activation0); |
247 | assertEquals(Tuple.of(newModelId, newClass1Id), activation1); | 247 | assertEquals(Tuple.of(newModelId, newClass1Id), activation1); |
@@ -312,7 +312,7 @@ public class TransformationRuleTest { | |||
312 | assertResults(Map.of( | 312 | assertResults(Map.of( |
313 | Tuple.of(newModelId, newClass1Id), true, | 313 | Tuple.of(newModelId, newClass1Id), true, |
314 | Tuple.of(newModelId, newClass2Id), true | 314 | Tuple.of(newModelId, newClass2Id), true |
315 | ), deleteEmptyClassRule.getAllActivationsAsSets()); | 315 | ), deleteEmptyClassRule.getAllActivationsAsResultSet()); |
316 | 316 | ||
317 | 317 | ||
318 | deleteEmptyClassRule.fireActivation(Tuple.of(0, 1)); | 318 | deleteEmptyClassRule.fireActivation(Tuple.of(0, 1)); |
@@ -320,7 +320,7 @@ public class TransformationRuleTest { | |||
320 | assertResults(Map.of( | 320 | assertResults(Map.of( |
321 | Tuple.of(newModelId, newClass1Id), false, | 321 | Tuple.of(newModelId, newClass1Id), false, |
322 | Tuple.of(newModelId, newClass2Id), true | 322 | Tuple.of(newModelId, newClass2Id), true |
323 | ), deleteEmptyClassRule.getAllActivationsAsSets()); | 323 | ), deleteEmptyClassRule.getAllActivationsAsResultSet()); |
324 | } | 324 | } |
325 | 325 | ||
326 | @Test | 326 | @Test |
@@ -388,21 +388,21 @@ public class TransformationRuleTest { | |||
388 | assertResults(Map.of( | 388 | assertResults(Map.of( |
389 | Tuple.of(newModelId, newClass1Id), true, | 389 | Tuple.of(newModelId, newClass1Id), true, |
390 | Tuple.of(newModelId, newClass2Id), true | 390 | Tuple.of(newModelId, newClass2Id), true |
391 | ), deleteEmptyClassRule.getAllActivationsAsSets()); | 391 | ), deleteEmptyClassRule.getAllActivationsAsResultSet()); |
392 | 392 | ||
393 | deleteEmptyClassRule.fireRandomActivation(); | 393 | deleteEmptyClassRule.fireRandomActivation(); |
394 | 394 | ||
395 | assertResults(Map.of( | 395 | assertResults(Map.of( |
396 | Tuple.of(newModelId, newClass1Id), true, | 396 | Tuple.of(newModelId, newClass1Id), true, |
397 | Tuple.of(newModelId, newClass2Id), false | 397 | Tuple.of(newModelId, newClass2Id), false |
398 | ), deleteEmptyClassRule.getAllActivationsAsSets()); | 398 | ), deleteEmptyClassRule.getAllActivationsAsResultSet()); |
399 | 399 | ||
400 | deleteEmptyClassRule.fireRandomActivation(); | 400 | deleteEmptyClassRule.fireRandomActivation(); |
401 | 401 | ||
402 | assertResults(Map.of( | 402 | assertResults(Map.of( |
403 | Tuple.of(newModelId, newClass1Id), false, | 403 | Tuple.of(newModelId, newClass1Id), false, |
404 | Tuple.of(newModelId, newClass2Id), false | 404 | Tuple.of(newModelId, newClass2Id), false |
405 | ), deleteEmptyClassRule.getAllActivationsAsSets()); | 405 | ), deleteEmptyClassRule.getAllActivationsAsResultSet()); |
406 | 406 | ||
407 | } | 407 | } |
408 | } | 408 | } |