diff options
Diffstat (limited to 'subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal')
12 files changed, 0 insertions, 940 deletions
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/Activation.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/Activation.java deleted file mode 100644 index 1893ce2e..00000000 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/Activation.java +++ /dev/null | |||
@@ -1,14 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.dse.internal; | ||
7 | |||
8 | import tools.refinery.store.tuple.Tuple; | ||
9 | |||
10 | public record Activation(TransformationRule transformationRule, Tuple activation) { | ||
11 | public boolean fire() { | ||
12 | return transformationRule.fireActivation(activation); | ||
13 | } | ||
14 | } | ||
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 deleted file mode 100644 index 1ae09916..00000000 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationAdapterImpl.java +++ /dev/null | |||
@@ -1,303 +0,0 @@ | |||
1 | /******************************************************************************* | ||
2 | * Copyright (c) 2010-2014, Miklos Foldenyi, Andras Szabolcs Nagy, Abel Hegedus, Akos Horvath, Zoltan Ujhelyi and Daniel Varro | ||
3 | * Copyright (c) 2023 The Refinery Authors <https://refinery.tools/> | ||
4 | * This program and the accompanying materials are made available under the | ||
5 | * terms of the Eclipse Public License v. 2.0 which is available at | ||
6 | * http://www.eclipse.org/legal/epl-v20.html. | ||
7 | * | ||
8 | * SPDX-License-Identifier: EPL-2.0 | ||
9 | *******************************************************************************/ | ||
10 | package tools.refinery.store.dse.internal; | ||
11 | |||
12 | import tools.refinery.store.map.Version; | ||
13 | import tools.refinery.store.model.Interpretation; | ||
14 | import tools.refinery.store.model.Model; | ||
15 | import tools.refinery.store.query.ModelQueryAdapter; | ||
16 | import tools.refinery.store.query.dnf.Query; | ||
17 | import tools.refinery.store.query.dnf.RelationalQuery; | ||
18 | import tools.refinery.store.dse.DesignSpaceExplorationAdapter; | ||
19 | import tools.refinery.store.dse.DesignSpaceExplorationStoreAdapter; | ||
20 | import tools.refinery.store.dse.Strategy; | ||
21 | import tools.refinery.store.dse.objectives.Fitness; | ||
22 | import tools.refinery.store.dse.objectives.Objective; | ||
23 | import tools.refinery.store.dse.objectives.ObjectiveComparatorHelper; | ||
24 | import tools.refinery.store.query.resultset.ResultSet; | ||
25 | import tools.refinery.store.representation.Symbol; | ||
26 | import tools.refinery.store.tuple.Tuple; | ||
27 | import tools.refinery.store.tuple.Tuple1; | ||
28 | import tools.refinery.visualization.ModelVisualizerAdapter; | ||
29 | |||
30 | import java.util.*; | ||
31 | |||
32 | public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExplorationAdapter { | ||
33 | static final Symbol<Integer> NODE_COUNT_SYMBOL = Symbol.of("MODEL_SIZE", 0, Integer.class, 0); | ||
34 | private final Model model; | ||
35 | private final ModelQueryAdapter queryEngine; | ||
36 | private final DesignSpaceExplorationStoreAdapterImpl storeAdapter; | ||
37 | private final Set<TransformationRule> transformationRules; | ||
38 | private final Set<RelationalQuery> globalConstraints; | ||
39 | private final List<Objective> objectives; | ||
40 | private final LinkedHashSet<ResultSet<Boolean>> globalConstraintResultSets = new LinkedHashSet<>(); | ||
41 | private final Interpretation<Integer> sizeInterpretation; | ||
42 | private final Strategy strategy; | ||
43 | |||
44 | private ObjectiveComparatorHelper objectiveComparatorHelper; | ||
45 | private List<Version> trajectory = new ArrayList<>(); | ||
46 | private Map<Version, Version> parents = new HashMap<>(); | ||
47 | private final List<Version> solutions = new ArrayList<>(); | ||
48 | private Map<Version, List<Activation>> statesAndTraversedActivations; | ||
49 | @SuppressWarnings("squid:S2245") | ||
50 | private Random random = new Random(); | ||
51 | private boolean isNewState = false; | ||
52 | private final boolean isVisualizationEnabled; | ||
53 | private final ModelVisualizerAdapter modelVisualizerAdapter; | ||
54 | |||
55 | private final Map<Version, Fitness> fitnessCache = new HashMap<>(); | ||
56 | |||
57 | public DesignSpaceExplorationAdapterImpl(Model model, DesignSpaceExplorationStoreAdapterImpl storeAdapter) { | ||
58 | this.model = model; | ||
59 | this.storeAdapter = storeAdapter; | ||
60 | this.sizeInterpretation = model.getInterpretation(NODE_COUNT_SYMBOL); | ||
61 | queryEngine = model.getAdapter(ModelQueryAdapter.class); | ||
62 | |||
63 | globalConstraints = storeAdapter.getGlobalConstraints(); | ||
64 | for (var constraint : globalConstraints) { | ||
65 | globalConstraintResultSets.add(queryEngine.getResultSet(constraint)); | ||
66 | } | ||
67 | |||
68 | transformationRules = storeAdapter.getTransformationSpecifications(); | ||
69 | for (var rule : transformationRules) { | ||
70 | rule.prepare(model, queryEngine); | ||
71 | } | ||
72 | |||
73 | objectives = storeAdapter.getObjectives(); | ||
74 | statesAndTraversedActivations = new HashMap<>(); | ||
75 | strategy = storeAdapter.getStrategy(); | ||
76 | strategy.initialize(this); | ||
77 | modelVisualizerAdapter = model.tryGetAdapter(ModelVisualizerAdapter.class).orElse(null); | ||
78 | isVisualizationEnabled = modelVisualizerAdapter != null; | ||
79 | |||
80 | } | ||
81 | |||
82 | @Override | ||
83 | public void addTransformationRule(TransformationRule rule) { | ||
84 | transformationRules.add(rule); | ||
85 | rule.prepare(model, queryEngine); | ||
86 | } | ||
87 | |||
88 | public List<Version> getTrajectory() { | ||
89 | return new ArrayList<>(trajectory); | ||
90 | } | ||
91 | |||
92 | @Override | ||
93 | public Model getModel() { | ||
94 | return model; | ||
95 | } | ||
96 | |||
97 | @Override | ||
98 | public DesignSpaceExplorationStoreAdapter getStoreAdapter() { | ||
99 | return storeAdapter; | ||
100 | } | ||
101 | |||
102 | @Override | ||
103 | public List<Version> explore() { | ||
104 | var state = model.commit(); | ||
105 | trajectory.add(state); | ||
106 | strategy.explore(); | ||
107 | if (isVisualizationEnabled) { | ||
108 | modelVisualizerAdapter.visualize(); | ||
109 | } | ||
110 | return solutions; | ||
111 | } | ||
112 | |||
113 | @Override | ||
114 | public int getModelSize() { | ||
115 | return sizeInterpretation.get(Tuple.of()); | ||
116 | } | ||
117 | |||
118 | @Override | ||
119 | public Tuple1 createObject() { | ||
120 | var newNodeId = getModelSize(); | ||
121 | sizeInterpretation.put(Tuple.of(), newNodeId + 1); | ||
122 | return Tuple.of(newNodeId); | ||
123 | } | ||
124 | |||
125 | @Override | ||
126 | public Tuple deleteObject(Tuple tuple) { | ||
127 | if (tuple.getSize() != 1) { | ||
128 | throw new IllegalArgumentException("Tuple size must be 1"); | ||
129 | } | ||
130 | // TODO: implement more efficient deletion | ||
131 | // if (tuple.get(0) == getModelSize() - 1) { | ||
132 | // sizeInterpretation.put(Tuple.of(), getModelSize() - 1); | ||
133 | // } | ||
134 | return tuple; | ||
135 | } | ||
136 | |||
137 | @Override | ||
138 | public boolean checkGlobalConstraints() { | ||
139 | for (var resultSet : globalConstraintResultSets) { | ||
140 | if (resultSet.size() > 0) { | ||
141 | return false; | ||
142 | } | ||
143 | } | ||
144 | return true; | ||
145 | } | ||
146 | |||
147 | @Override | ||
148 | public boolean backtrack() { | ||
149 | return backtrack(""); | ||
150 | } | ||
151 | @Override | ||
152 | public boolean backtrack(String reason) { | ||
153 | if (trajectory.size() < 2) { | ||
154 | return false; | ||
155 | } | ||
156 | var currentState = model.getState(); | ||
157 | if (!parents.containsKey(currentState)) { | ||
158 | return false; | ||
159 | } | ||
160 | if (isVisualizationEnabled) { | ||
161 | modelVisualizerAdapter.addTransition(trajectory.get(trajectory.size() - 1), | ||
162 | trajectory.get(trajectory.size() - 2), "backtrack(" + reason + ")"); | ||
163 | } | ||
164 | model.restore(parents.get(model.getState())); | ||
165 | trajectory.remove(trajectory.size() - 1); | ||
166 | return true; | ||
167 | } | ||
168 | |||
169 | @Override | ||
170 | public void restoreTrajectory(List<Version> trajectory) { | ||
171 | model.restore(trajectory.get(trajectory.size() - 1)); | ||
172 | // if (isVisualizationEnabled) { | ||
173 | // modelVisualizerAdapter.addTransition(this.trajectory.get(trajectory.size() - 1), | ||
174 | // trajectory.get(trajectory.size() - 1), "restore"); | ||
175 | // } | ||
176 | this.trajectory = new ArrayList<>(trajectory); | ||
177 | |||
178 | } | ||
179 | |||
180 | @Override | ||
181 | public void setRandom(Random random) { | ||
182 | this.random = random; | ||
183 | } | ||
184 | |||
185 | @Override | ||
186 | @SuppressWarnings("squid:S2245") | ||
187 | public void setRandom(long seed) { | ||
188 | this.random = new Random(seed); | ||
189 | } | ||
190 | |||
191 | @Override | ||
192 | public List<Version> getSolutions() { | ||
193 | return solutions; | ||
194 | } | ||
195 | |||
196 | @Override | ||
197 | public Fitness getFitness() { | ||
198 | return fitnessCache.computeIfAbsent(model.getState(), s -> calculateFitness()); | ||
199 | } | ||
200 | |||
201 | private Fitness calculateFitness() { | ||
202 | Fitness result = new Fitness(); | ||
203 | boolean satisfiesHardObjectives = true; | ||
204 | for (Objective objective : objectives) { | ||
205 | var fitness = objective.getFitness(this); | ||
206 | result.put(objective.getName(), fitness); | ||
207 | if (objective.isHardObjective() && !objective.satisfiesHardObjective(fitness)) { | ||
208 | satisfiesHardObjectives = false; | ||
209 | } | ||
210 | } | ||
211 | result.setSatisfiesHardObjectives(satisfiesHardObjectives); | ||
212 | |||
213 | return result; | ||
214 | } | ||
215 | |||
216 | @Override | ||
217 | public void newSolution() { | ||
218 | var state = model.getState(); | ||
219 | solutions.add(state); | ||
220 | if (isVisualizationEnabled) { | ||
221 | modelVisualizerAdapter.addSolution(state); | ||
222 | } | ||
223 | } | ||
224 | |||
225 | @Override | ||
226 | public int getDepth() { | ||
227 | return trajectory.size() - 1; | ||
228 | } | ||
229 | |||
230 | public LinkedHashSet<Activation> getUntraversedActivations() { | ||
231 | var traversedActivations = statesAndTraversedActivations.get(model.getState()); | ||
232 | if (traversedActivations == null) { | ||
233 | return new LinkedHashSet<>(getAllActivations()); | ||
234 | } | ||
235 | else { | ||
236 | LinkedHashSet<Activation> untraversedActivations = new LinkedHashSet<>(); | ||
237 | for (Activation activation : getAllActivations()) { | ||
238 | if (!traversedActivations.contains(activation)) { | ||
239 | untraversedActivations.add(activation); | ||
240 | } | ||
241 | } | ||
242 | return untraversedActivations; | ||
243 | } | ||
244 | } | ||
245 | |||
246 | @Override | ||
247 | public boolean fireActivation(Activation activation) { | ||
248 | if (activation == null) { | ||
249 | return false; | ||
250 | } | ||
251 | var previousState = model.getState(); | ||
252 | if (!activation.fire()) { | ||
253 | return false; | ||
254 | } | ||
255 | statesAndTraversedActivations.computeIfAbsent(previousState, s -> new ArrayList<>()).add(activation); | ||
256 | var newState = model.commit(); | ||
257 | trajectory.add(newState); | ||
258 | parents.put(newState, previousState); | ||
259 | isNewState = !statesAndTraversedActivations.containsKey(newState); | ||
260 | if (isVisualizationEnabled) { | ||
261 | if (isNewState) { | ||
262 | modelVisualizerAdapter.addState(newState, getFitness().values()); | ||
263 | } | ||
264 | modelVisualizerAdapter.addTransition(previousState, newState, activation.transformationRule().getName(), | ||
265 | activation.activation()); | ||
266 | } | ||
267 | return true; | ||
268 | } | ||
269 | |||
270 | @Override | ||
271 | public boolean fireRandomActivation() { | ||
272 | var activations = getUntraversedActivations(); | ||
273 | if (activations.isEmpty()) { | ||
274 | return false; | ||
275 | } | ||
276 | int index = random.nextInt(activations.size()); | ||
277 | var iterator = activations.iterator(); | ||
278 | while (index-- > 0) { | ||
279 | iterator.next(); | ||
280 | } | ||
281 | var activationId = iterator.next(); | ||
282 | return fireActivation(activationId); | ||
283 | } | ||
284 | |||
285 | public List<Activation> getAllActivations() { | ||
286 | List<Activation> result = new LinkedList<>(); | ||
287 | for (var rule : transformationRules) { | ||
288 | result.addAll(rule.getAllActivationsAsList()); | ||
289 | } | ||
290 | return result; | ||
291 | } | ||
292 | |||
293 | public boolean isCurrentStateAlreadyTraversed() { | ||
294 | return !isNewState; | ||
295 | } | ||
296 | |||
297 | public ObjectiveComparatorHelper getObjectiveComparatorHelper() { | ||
298 | if (objectiveComparatorHelper == null) { | ||
299 | objectiveComparatorHelper = new ObjectiveComparatorHelper(objectives); | ||
300 | } | ||
301 | return objectiveComparatorHelper; | ||
302 | } | ||
303 | } | ||
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationBuilderImpl.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationBuilderImpl.java deleted file mode 100644 index 8f7056f2..00000000 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationBuilderImpl.java +++ /dev/null | |||
@@ -1,67 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.dse.internal; | ||
7 | |||
8 | import tools.refinery.store.adapter.AbstractModelAdapterBuilder; | ||
9 | import tools.refinery.store.model.ModelStore; | ||
10 | import tools.refinery.store.model.ModelStoreBuilder; | ||
11 | import tools.refinery.store.query.dnf.RelationalQuery; | ||
12 | import tools.refinery.store.dse.DesignSpaceExplorationBuilder; | ||
13 | import tools.refinery.store.dse.Strategy; | ||
14 | import tools.refinery.store.dse.objectives.Objective; | ||
15 | |||
16 | import java.util.LinkedHashSet; | ||
17 | import java.util.LinkedList; | ||
18 | import java.util.List; | ||
19 | |||
20 | public class DesignSpaceExplorationBuilderImpl | ||
21 | extends AbstractModelAdapterBuilder<DesignSpaceExplorationStoreAdapterImpl> | ||
22 | implements DesignSpaceExplorationBuilder { | ||
23 | private final LinkedHashSet<TransformationRule> transformationSpecifications = new LinkedHashSet<>(); | ||
24 | private final LinkedHashSet<RelationalQuery> globalConstraints = new LinkedHashSet<>(); | ||
25 | private final List<Objective> objectives = new LinkedList<>(); | ||
26 | private Strategy strategy; | ||
27 | |||
28 | @Override | ||
29 | protected DesignSpaceExplorationStoreAdapterImpl doBuild(ModelStore store) { | ||
30 | return new DesignSpaceExplorationStoreAdapterImpl(store, transformationSpecifications, globalConstraints, | ||
31 | objectives, strategy); | ||
32 | } | ||
33 | |||
34 | @Override | ||
35 | public DesignSpaceExplorationBuilder transformation(TransformationRule transformationRule) { | ||
36 | checkNotConfigured(); | ||
37 | transformationSpecifications.add(transformationRule); | ||
38 | return this; | ||
39 | } | ||
40 | |||
41 | @Override | ||
42 | public DesignSpaceExplorationBuilder globalConstraint(RelationalQuery globalConstraint) { | ||
43 | checkNotConfigured(); | ||
44 | globalConstraints.add(globalConstraint); | ||
45 | return this; | ||
46 | } | ||
47 | |||
48 | @Override | ||
49 | public DesignSpaceExplorationBuilder objective(Objective objective) { | ||
50 | checkNotConfigured(); | ||
51 | objectives.add(objective); | ||
52 | return this; | ||
53 | } | ||
54 | |||
55 | @Override | ||
56 | public DesignSpaceExplorationBuilder strategy(Strategy strategy) { | ||
57 | checkNotConfigured(); | ||
58 | this.strategy = strategy; | ||
59 | return this; | ||
60 | } | ||
61 | |||
62 | @Override | ||
63 | protected void doConfigure(ModelStoreBuilder storeBuilder) { | ||
64 | storeBuilder.symbols(DesignSpaceExplorationAdapterImpl.NODE_COUNT_SYMBOL); | ||
65 | super.doConfigure(storeBuilder); | ||
66 | } | ||
67 | } | ||
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 deleted file mode 100644 index fea39886..00000000 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationStoreAdapterImpl.java +++ /dev/null | |||
@@ -1,65 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.dse.internal; | ||
7 | |||
8 | import tools.refinery.store.dse.DesignSpaceExplorationStoreAdapter; | ||
9 | import tools.refinery.store.dse.Strategy; | ||
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; | ||
14 | |||
15 | import java.util.List; | ||
16 | import java.util.Set; | ||
17 | |||
18 | public class DesignSpaceExplorationStoreAdapterImpl implements DesignSpaceExplorationStoreAdapter { | ||
19 | private final ModelStore store; | ||
20 | private final Set<TransformationRule> transformationSpecifications; | ||
21 | private final Set<RelationalQuery> globalConstraints; | ||
22 | private final List<Objective> objectives; | ||
23 | private final Strategy strategy; | ||
24 | |||
25 | public DesignSpaceExplorationStoreAdapterImpl(ModelStore store, | ||
26 | Set<TransformationRule> transformationSpecifications, | ||
27 | Set<RelationalQuery> globalConstraints, | ||
28 | List<Objective> objectives, Strategy strategy) { | ||
29 | this.store = store; | ||
30 | this.transformationSpecifications = transformationSpecifications; | ||
31 | this.globalConstraints = globalConstraints; | ||
32 | this.objectives = objectives; | ||
33 | this.strategy = strategy; | ||
34 | } | ||
35 | |||
36 | @Override | ||
37 | public ModelStore getStore() { | ||
38 | return store; | ||
39 | } | ||
40 | |||
41 | @Override | ||
42 | public DesignSpaceExplorationAdapterImpl createModelAdapter(Model model) { | ||
43 | return new DesignSpaceExplorationAdapterImpl(model, this); | ||
44 | } | ||
45 | |||
46 | @Override | ||
47 | public Set<TransformationRule> getTransformationSpecifications() { | ||
48 | return transformationSpecifications; | ||
49 | } | ||
50 | |||
51 | @Override | ||
52 | public Set<RelationalQuery> getGlobalConstraints() { | ||
53 | return globalConstraints; | ||
54 | } | ||
55 | |||
56 | @Override | ||
57 | public List<Objective> getObjectives() { | ||
58 | return objectives; | ||
59 | } | ||
60 | |||
61 | @Override | ||
62 | public Strategy getStrategy() { | ||
63 | return strategy; | ||
64 | } | ||
65 | } | ||
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 deleted file mode 100644 index 37117164..00000000 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/TransformationRule.java +++ /dev/null | |||
@@ -1,99 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.dse.internal; | ||
7 | |||
8 | import org.eclipse.collections.api.block.procedure.Procedure; | ||
9 | import tools.refinery.store.model.Model; | ||
10 | import tools.refinery.store.query.ModelQueryAdapter; | ||
11 | import tools.refinery.store.query.dnf.RelationalQuery; | ||
12 | import tools.refinery.store.dse.ActionFactory; | ||
13 | import tools.refinery.store.query.resultset.OrderedResultSet; | ||
14 | import tools.refinery.store.query.resultset.ResultSet; | ||
15 | import tools.refinery.store.tuple.Tuple; | ||
16 | |||
17 | import java.util.*; | ||
18 | |||
19 | public class TransformationRule { | ||
20 | |||
21 | private final String name; | ||
22 | private final RelationalQuery precondition; | ||
23 | private final ActionFactory actionFactory; | ||
24 | private Procedure<Tuple> action; | ||
25 | private OrderedResultSet<Boolean> activations; | ||
26 | private Random random; | ||
27 | private ModelQueryAdapter queryEngine; | ||
28 | |||
29 | @SuppressWarnings("squid:S2245") | ||
30 | public TransformationRule(String name, RelationalQuery precondition, ActionFactory actionFactory) { | ||
31 | this(name, precondition, actionFactory, new Random()); | ||
32 | } | ||
33 | |||
34 | @SuppressWarnings("squid:S2245") | ||
35 | public TransformationRule(String name, RelationalQuery precondition, ActionFactory actionFactory, long seed) { | ||
36 | this(name, precondition, actionFactory, new Random(seed)); | ||
37 | } | ||
38 | |||
39 | public TransformationRule(String name, RelationalQuery precondition, ActionFactory actionFactory, Random random) { | ||
40 | this.name = name; | ||
41 | this.precondition = precondition; | ||
42 | this.actionFactory = actionFactory; | ||
43 | this.random = random; | ||
44 | } | ||
45 | public boolean prepare(Model model, ModelQueryAdapter queryEngine) { | ||
46 | action = actionFactory.prepare(model); | ||
47 | this.queryEngine = queryEngine; | ||
48 | activations = new OrderedResultSet<>(queryEngine.getResultSet(precondition)); | ||
49 | return true; | ||
50 | } | ||
51 | |||
52 | public boolean fireActivation(Tuple activation) { | ||
53 | action.accept(activation); | ||
54 | queryEngine.flushChanges(); | ||
55 | return true; | ||
56 | } | ||
57 | |||
58 | public boolean fireRandomActivation() { | ||
59 | return getRandomActivation().fire(); | ||
60 | } | ||
61 | |||
62 | public String getName() { | ||
63 | return name; | ||
64 | } | ||
65 | |||
66 | public RelationalQuery getPrecondition() { | ||
67 | return precondition; | ||
68 | } | ||
69 | |||
70 | public ResultSet<Boolean> getAllActivationsAsResultSet() { | ||
71 | return activations; | ||
72 | } | ||
73 | |||
74 | public Set<Activation> getAllActivations() { | ||
75 | var result = new LinkedHashSet<Activation>(); | ||
76 | var cursor = activations.getAll(); | ||
77 | while (cursor.move()) { | ||
78 | result.add(new Activation(this, cursor.getKey())); | ||
79 | } | ||
80 | return result; | ||
81 | } | ||
82 | |||
83 | public List<Activation> getAllActivationsAsList() { | ||
84 | var result = new ArrayList<Activation>(); | ||
85 | var cursor = activations.getAll(); | ||
86 | while (cursor.move()) { | ||
87 | result.add(new Activation(this, cursor.getKey())); | ||
88 | } | ||
89 | return result; | ||
90 | } | ||
91 | |||
92 | public Activation getRandomActivation() { | ||
93 | return new Activation(this, activations.getKey(random.nextInt(activations.size()))); | ||
94 | } | ||
95 | |||
96 | public Activation getActivation(int index) { | ||
97 | return new Activation(this, activations.getKey(index)); | ||
98 | } | ||
99 | } | ||
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/ActionVariable.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/ActionVariable.java deleted file mode 100644 index 92de565d..00000000 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/ActionVariable.java +++ /dev/null | |||
@@ -1,12 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.dse.internal.action; | ||
7 | |||
8 | import tools.refinery.store.tuple.Tuple; | ||
9 | |||
10 | public interface ActionVariable extends AtomicAction { | ||
11 | Tuple getValue(); | ||
12 | } | ||
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/ActivationVariable.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/ActivationVariable.java deleted file mode 100644 index 6b4c6340..00000000 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/ActivationVariable.java +++ /dev/null | |||
@@ -1,54 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.dse.internal.action; | ||
7 | |||
8 | import tools.refinery.store.model.Model; | ||
9 | import tools.refinery.store.tuple.Tuple; | ||
10 | |||
11 | public class ActivationVariable implements ActionVariable { | ||
12 | |||
13 | private final int index; | ||
14 | private Tuple value; | ||
15 | |||
16 | public ActivationVariable() { | ||
17 | this(0); | ||
18 | } | ||
19 | |||
20 | public ActivationVariable(int index) { | ||
21 | this.index = index; | ||
22 | } | ||
23 | |||
24 | @Override | ||
25 | public void fire(Tuple activation) { | ||
26 | value = Tuple.of(activation.get(index)); | ||
27 | } | ||
28 | |||
29 | @Override | ||
30 | public ActivationVariable prepare(Model model) { | ||
31 | return this; | ||
32 | } | ||
33 | |||
34 | @Override | ||
35 | public Tuple getValue() { | ||
36 | return value; | ||
37 | } | ||
38 | |||
39 | @Override | ||
40 | public boolean equalsWithSubstitution(AtomicAction other) { | ||
41 | if (other == null || getClass() != other.getClass()) { | ||
42 | return false; | ||
43 | } | ||
44 | var otherAction = (ActivationVariable) other; | ||
45 | |||
46 | if (index != otherAction.index) { | ||
47 | return false; | ||
48 | } | ||
49 | if (value == null) { | ||
50 | return otherAction.value == null; | ||
51 | } | ||
52 | return value.equals(otherAction.value); | ||
53 | } | ||
54 | } | ||
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/AtomicAction.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/AtomicAction.java deleted file mode 100644 index a8f10bca..00000000 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/AtomicAction.java +++ /dev/null | |||
@@ -1,18 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.dse.internal.action; | ||
7 | |||
8 | import tools.refinery.store.model.Model; | ||
9 | import tools.refinery.store.tuple.Tuple; | ||
10 | |||
11 | public interface AtomicAction { | ||
12 | |||
13 | void fire(Tuple activation); | ||
14 | |||
15 | AtomicAction prepare(Model model); | ||
16 | |||
17 | boolean equalsWithSubstitution(AtomicAction other); | ||
18 | } | ||
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/DeleteAction.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/DeleteAction.java deleted file mode 100644 index 9900390f..00000000 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/DeleteAction.java +++ /dev/null | |||
@@ -1,40 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.dse.internal.action; | ||
7 | |||
8 | import tools.refinery.store.dse.DesignSpaceExplorationAdapter; | ||
9 | import tools.refinery.store.model.Model; | ||
10 | import tools.refinery.store.tuple.Tuple; | ||
11 | |||
12 | public class DeleteAction implements AtomicAction { | ||
13 | |||
14 | private final ActionVariable variable; | ||
15 | private DesignSpaceExplorationAdapter dseAdapter; | ||
16 | |||
17 | public DeleteAction(ActionVariable variable) { | ||
18 | this.variable = variable; | ||
19 | } | ||
20 | |||
21 | @Override | ||
22 | public void fire(Tuple activation) { | ||
23 | dseAdapter.deleteObject(variable.getValue()); | ||
24 | } | ||
25 | |||
26 | @Override | ||
27 | public DeleteAction prepare(Model model) { | ||
28 | dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class); | ||
29 | return this; | ||
30 | } | ||
31 | |||
32 | @Override | ||
33 | public boolean equalsWithSubstitution(AtomicAction other) { | ||
34 | if (other == null || getClass() != other.getClass()) { | ||
35 | return false; | ||
36 | } | ||
37 | var otherAction = (DeleteAction) other; | ||
38 | return this.variable.getClass() == otherAction.variable.getClass(); | ||
39 | } | ||
40 | } | ||
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/InsertAction.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/InsertAction.java deleted file mode 100644 index 90fcc5ac..00000000 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/InsertAction.java +++ /dev/null | |||
@@ -1,94 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.dse.internal.action; | ||
7 | |||
8 | import tools.refinery.store.model.Interpretation; | ||
9 | import tools.refinery.store.model.Model; | ||
10 | import tools.refinery.store.tuple.Tuple; | ||
11 | import tools.refinery.store.tuple.Tuple0; | ||
12 | |||
13 | import java.util.Arrays; | ||
14 | |||
15 | public class InsertAction<T> implements AtomicAction { | ||
16 | |||
17 | private final Interpretation<T> interpretation; | ||
18 | private final T value; | ||
19 | private final int arity; | ||
20 | private final ActionVariable[] variables; | ||
21 | |||
22 | public InsertAction(Interpretation<T> interpretation, T value, ActionVariable... variables) { | ||
23 | this.interpretation = interpretation; | ||
24 | this.value = value; | ||
25 | this.variables = variables; | ||
26 | this.arity = interpretation.getSymbol().arity(); | ||
27 | if (variables.length != arity) { | ||
28 | throw new IllegalArgumentException("Expected " + arity + " variables, but got " + variables.length); | ||
29 | } | ||
30 | } | ||
31 | |||
32 | @Override | ||
33 | public void fire(Tuple activation) { | ||
34 | Tuple tuple; | ||
35 | if (arity == 0) { | ||
36 | tuple = Tuple0.INSTANCE; | ||
37 | } | ||
38 | else if (arity == 1) { | ||
39 | tuple = variables[0].getValue(); | ||
40 | } | ||
41 | else if (arity == 2) { | ||
42 | tuple = Tuple.of(variables[0].getValue().get(0), variables[1].getValue().get(0)); | ||
43 | } | ||
44 | else if (arity == 3) { | ||
45 | tuple = Tuple.of(variables[0].getValue().get(0), variables[1].getValue().get(0), variables[2].getValue().get(0)); | ||
46 | } | ||
47 | else { | ||
48 | tuple = Tuple.of(Arrays.stream(variables).map(variable -> variable.getValue().get(0)) | ||
49 | .mapToInt(Integer::intValue).toArray()); | ||
50 | } | ||
51 | interpretation.put(tuple, value); | ||
52 | } | ||
53 | |||
54 | public void put(Tuple tuple) { | ||
55 | interpretation.put(tuple, value); | ||
56 | } | ||
57 | |||
58 | @Override | ||
59 | public InsertAction<T> prepare(Model model) { | ||
60 | return this; | ||
61 | } | ||
62 | |||
63 | public ActionVariable[] getVariables() { | ||
64 | return variables; | ||
65 | } | ||
66 | |||
67 | @Override | ||
68 | public boolean equalsWithSubstitution(AtomicAction other) { | ||
69 | if (other == null || getClass() != other.getClass()) { | ||
70 | return false; | ||
71 | } | ||
72 | var otherAction = (InsertAction<?>) other; | ||
73 | if (variables.length != otherAction.variables.length) { | ||
74 | return false; | ||
75 | } | ||
76 | if (!interpretation.equals(otherAction.interpretation)) { | ||
77 | return false; | ||
78 | } | ||
79 | if (value == null) { | ||
80 | if (otherAction.value != null) { | ||
81 | return false; | ||
82 | } | ||
83 | } | ||
84 | else if (!value.equals(otherAction.value)) { | ||
85 | return false; | ||
86 | } | ||
87 | for (var i = 0; i < variables.length; i++) { | ||
88 | if (!variables[i].equalsWithSubstitution(otherAction.variables[i])) { | ||
89 | return false; | ||
90 | } | ||
91 | } | ||
92 | return true; | ||
93 | } | ||
94 | } | ||
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/NewItemVariable.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/NewItemVariable.java deleted file mode 100644 index cbb9697e..00000000 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/NewItemVariable.java +++ /dev/null | |||
@@ -1,45 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.dse.internal.action; | ||
7 | |||
8 | import tools.refinery.store.dse.DesignSpaceExplorationAdapter; | ||
9 | import tools.refinery.store.model.Model; | ||
10 | import tools.refinery.store.tuple.Tuple; | ||
11 | import tools.refinery.store.tuple.Tuple1; | ||
12 | |||
13 | public class NewItemVariable implements ActionVariable { | ||
14 | private DesignSpaceExplorationAdapter dseAdapter; | ||
15 | private Tuple1 value; | ||
16 | |||
17 | @Override | ||
18 | public void fire(Tuple activation) { | ||
19 | value = dseAdapter.createObject(); | ||
20 | } | ||
21 | |||
22 | @Override | ||
23 | public NewItemVariable prepare(Model model) { | ||
24 | dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class); | ||
25 | return this; | ||
26 | } | ||
27 | |||
28 | @Override | ||
29 | public Tuple1 getValue() { | ||
30 | return value; | ||
31 | } | ||
32 | |||
33 | @Override | ||
34 | public boolean equalsWithSubstitution(AtomicAction other) { | ||
35 | if (other == null || getClass() != other.getClass()) { | ||
36 | return false; | ||
37 | } | ||
38 | var otherAction = (NewItemVariable) other; | ||
39 | if (value == null) { | ||
40 | return otherAction.value == null; | ||
41 | } | ||
42 | return value.equals(otherAction.value); | ||
43 | |||
44 | } | ||
45 | } | ||
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/TransformationAction.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/TransformationAction.java deleted file mode 100644 index adc4df9e..00000000 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/TransformationAction.java +++ /dev/null | |||
@@ -1,129 +0,0 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.dse.internal.action; | ||
7 | |||
8 | import tools.refinery.store.model.Model; | ||
9 | import tools.refinery.store.tuple.Tuple; | ||
10 | import tools.refinery.store.tuple.Tuple2; | ||
11 | |||
12 | import java.util.*; | ||
13 | |||
14 | public class TransformationAction { | ||
15 | private final List<ActionVariable> actionVariables = new ArrayList<>(); | ||
16 | private final List<InsertAction<?>> insertActions = new ArrayList<>(); | ||
17 | private final List<DeleteAction> deleteActions = new ArrayList<>(); | ||
18 | private boolean configured = false; | ||
19 | private final Map<Integer, List<Tuple2>> actionVariableUsageMap = new LinkedHashMap<>(); | ||
20 | |||
21 | public TransformationAction add(ActionVariable action) { | ||
22 | checkConfigured(); | ||
23 | actionVariables.add(action); | ||
24 | return this; | ||
25 | } | ||
26 | |||
27 | public TransformationAction add(InsertAction<?> action) { | ||
28 | checkConfigured(); | ||
29 | insertActions.add(action); | ||
30 | return this; | ||
31 | } | ||
32 | |||
33 | public TransformationAction add(DeleteAction action) { | ||
34 | checkConfigured(); | ||
35 | deleteActions.add(action); | ||
36 | return this; | ||
37 | } | ||
38 | |||
39 | private void checkConfigured() { | ||
40 | if (configured) { | ||
41 | throw new IllegalStateException("Action already configured."); | ||
42 | } | ||
43 | } | ||
44 | |||
45 | public TransformationAction prepare(Model model) { | ||
46 | for (ActionVariable action : actionVariables) { | ||
47 | action.prepare(model); | ||
48 | } | ||
49 | for (InsertAction<?> action : insertActions) { | ||
50 | action.prepare(model); | ||
51 | } | ||
52 | for (DeleteAction action : deleteActions) { | ||
53 | action.prepare(model); | ||
54 | } | ||
55 | |||
56 | for (var insertAction : insertActions) { | ||
57 | var actionIndex = insertActions.indexOf(insertAction); | ||
58 | var variables = insertAction.getVariables(); | ||
59 | for (var i = 0; i < variables.length; i++) { | ||
60 | var variablelGlobalIndex = actionVariables.indexOf(variables[i]); | ||
61 | actionVariableUsageMap.computeIfAbsent(variablelGlobalIndex, k -> new ArrayList<>()); | ||
62 | actionVariableUsageMap.get(variablelGlobalIndex).add(Tuple.of(actionIndex, i)); | ||
63 | } | ||
64 | } | ||
65 | |||
66 | configured = true; | ||
67 | return this; | ||
68 | } | ||
69 | |||
70 | public boolean fire(Tuple activation) { | ||
71 | for (ActionVariable action : actionVariables) { | ||
72 | action.fire(activation); | ||
73 | } | ||
74 | for (InsertAction<?> action : insertActions) { | ||
75 | action.fire(activation); | ||
76 | } | ||
77 | for (DeleteAction action : deleteActions) { | ||
78 | action.fire(activation); | ||
79 | } | ||
80 | return true; | ||
81 | } | ||
82 | |||
83 | // Returns true if ActionVariables and InsertActions are inserted in same order, ActionVariables are equal (they | ||
84 | // have the same index for getting the value from the activation Tuple) and InsertActions are equal (they have | ||
85 | // the same arity and value to be set). | ||
86 | public boolean equalsWithSubstitution(TransformationAction other) { | ||
87 | if (other == this) { | ||
88 | return true; | ||
89 | } | ||
90 | |||
91 | if (actionVariables.size() != other.actionVariables.size()) { | ||
92 | return false; | ||
93 | } | ||
94 | |||
95 | if (insertActions.size() != other.insertActions.size()) { | ||
96 | return false; | ||
97 | } | ||
98 | |||
99 | if (deleteActions.size() != other.deleteActions.size()) { | ||
100 | return false; | ||
101 | } | ||
102 | |||
103 | for (var i = 0; i < actionVariables.size(); i++) { | ||
104 | var variable = actionVariables.get(i); | ||
105 | var otherVariable = other.actionVariables.get(i); | ||
106 | if (!variable.equalsWithSubstitution(otherVariable)) { | ||
107 | return false; | ||
108 | } | ||
109 | } | ||
110 | |||
111 | for (var i = 0; i < insertActions.size(); i++) { | ||
112 | var insertAction = insertActions.get(i); | ||
113 | var otherInsertAction = other.insertActions.get(i); | ||
114 | if (!insertAction.equalsWithSubstitution(otherInsertAction)) { | ||
115 | return false; | ||
116 | } | ||
117 | } | ||
118 | |||
119 | for (var i = 0; i < deleteActions.size(); i++) { | ||
120 | var deleteAction = deleteActions.get(i); | ||
121 | var otherDeleteAction = other.deleteActions.get(i); | ||
122 | if (!deleteAction.equalsWithSubstitution(otherDeleteAction)) { | ||
123 | return false; | ||
124 | } | ||
125 | } | ||
126 | return this.actionVariableUsageMap.equals(other.actionVariableUsageMap); | ||
127 | |||
128 | } | ||
129 | } | ||