aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal')
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/Activation.java14
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationAdapterImpl.java303
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationBuilderImpl.java67
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationStoreAdapterImpl.java65
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/TransformationRule.java99
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/ActionVariable.java12
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/ActivationVariable.java54
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/AtomicAction.java18
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/DeleteAction.java40
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/InsertAction.java94
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/NewItemVariable.java45
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/TransformationAction.java129
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 */
6package tools.refinery.store.dse.internal;
7
8import tools.refinery.store.tuple.Tuple;
9
10public 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 *******************************************************************************/
10package tools.refinery.store.dse.internal;
11
12import tools.refinery.store.map.Version;
13import tools.refinery.store.model.Interpretation;
14import tools.refinery.store.model.Model;
15import tools.refinery.store.query.ModelQueryAdapter;
16import tools.refinery.store.query.dnf.Query;
17import tools.refinery.store.query.dnf.RelationalQuery;
18import tools.refinery.store.dse.DesignSpaceExplorationAdapter;
19import tools.refinery.store.dse.DesignSpaceExplorationStoreAdapter;
20import tools.refinery.store.dse.Strategy;
21import tools.refinery.store.dse.objectives.Fitness;
22import tools.refinery.store.dse.objectives.Objective;
23import tools.refinery.store.dse.objectives.ObjectiveComparatorHelper;
24import tools.refinery.store.query.resultset.ResultSet;
25import tools.refinery.store.representation.Symbol;
26import tools.refinery.store.tuple.Tuple;
27import tools.refinery.store.tuple.Tuple1;
28import tools.refinery.visualization.ModelVisualizerAdapter;
29
30import java.util.*;
31
32public 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 */
6package tools.refinery.store.dse.internal;
7
8import tools.refinery.store.adapter.AbstractModelAdapterBuilder;
9import tools.refinery.store.model.ModelStore;
10import tools.refinery.store.model.ModelStoreBuilder;
11import tools.refinery.store.query.dnf.RelationalQuery;
12import tools.refinery.store.dse.DesignSpaceExplorationBuilder;
13import tools.refinery.store.dse.Strategy;
14import tools.refinery.store.dse.objectives.Objective;
15
16import java.util.LinkedHashSet;
17import java.util.LinkedList;
18import java.util.List;
19
20public 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 */
6package tools.refinery.store.dse.internal;
7
8import tools.refinery.store.dse.DesignSpaceExplorationStoreAdapter;
9import tools.refinery.store.dse.Strategy;
10import tools.refinery.store.dse.objectives.Objective;
11import tools.refinery.store.model.Model;
12import tools.refinery.store.model.ModelStore;
13import tools.refinery.store.query.dnf.RelationalQuery;
14
15import java.util.List;
16import java.util.Set;
17
18public 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 */
6package tools.refinery.store.dse.internal;
7
8import org.eclipse.collections.api.block.procedure.Procedure;
9import tools.refinery.store.model.Model;
10import tools.refinery.store.query.ModelQueryAdapter;
11import tools.refinery.store.query.dnf.RelationalQuery;
12import tools.refinery.store.dse.ActionFactory;
13import tools.refinery.store.query.resultset.OrderedResultSet;
14import tools.refinery.store.query.resultset.ResultSet;
15import tools.refinery.store.tuple.Tuple;
16
17import java.util.*;
18
19public 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 */
6package tools.refinery.store.dse.internal.action;
7
8import tools.refinery.store.tuple.Tuple;
9
10public 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 */
6package tools.refinery.store.dse.internal.action;
7
8import tools.refinery.store.model.Model;
9import tools.refinery.store.tuple.Tuple;
10
11public 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 */
6package tools.refinery.store.dse.internal.action;
7
8import tools.refinery.store.model.Model;
9import tools.refinery.store.tuple.Tuple;
10
11public 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 */
6package tools.refinery.store.dse.internal.action;
7
8import tools.refinery.store.dse.DesignSpaceExplorationAdapter;
9import tools.refinery.store.model.Model;
10import tools.refinery.store.tuple.Tuple;
11
12public 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 */
6package tools.refinery.store.dse.internal.action;
7
8import tools.refinery.store.model.Interpretation;
9import tools.refinery.store.model.Model;
10import tools.refinery.store.tuple.Tuple;
11import tools.refinery.store.tuple.Tuple0;
12
13import java.util.Arrays;
14
15public 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 */
6package tools.refinery.store.dse.internal.action;
7
8import tools.refinery.store.dse.DesignSpaceExplorationAdapter;
9import tools.refinery.store.model.Model;
10import tools.refinery.store.tuple.Tuple;
11import tools.refinery.store.tuple.Tuple1;
12
13public 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 */
6package tools.refinery.store.dse.internal.action;
7
8import tools.refinery.store.model.Model;
9import tools.refinery.store.tuple.Tuple;
10import tools.refinery.store.tuple.Tuple2;
11
12import java.util.*;
13
14public 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}