aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store-dse/src/main/java/tools/refinery/store/dse
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/store-dse/src/main/java/tools/refinery/store/dse')
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/ActionFactory.java14
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/DanglingEdges.java12
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/ModificationAdapter.java2
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/actions/CreateActionLiteral.java43
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/actions/DeleteActionLiteral.java51
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/actions/ModificationActionLiterals.java23
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/internal/ModificationAdapterImpl.java55
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstStoreManager.java5
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/DesignSpaceExplorationAdapter.java11
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/DesignSpaceExplorationBuilder.java8
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/DesignSpaceExplorationStoreAdapter.java2
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/Rule.java99
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/RuleBuilder.java71
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/Transformation.java24
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/TransformationRule.java63
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/AbstractActionLiteral.java9
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/Action.java132
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/ActionLiteral.java19
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/ActionLiterals.java33
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/BoundAction.java109
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/BoundActionLiteral.java16
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/PutActionLiteral.java64
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback0.java15
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback1.java16
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback2.java16
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback3.java16
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback4.java16
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback0.java13
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback1.java14
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback2.java14
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback3.java14
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback4.java14
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/internal/DesignSpaceExplorationBuilderImpl.java30
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/internal/DesignSpaceExplorationStoreAdapterImpl.java32
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/AndCriterion.java53
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/CompositeCriterion.java43
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/CompositeObjective.java69
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/CountObjective.java47
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/Criteria.java47
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/Criterion.java9
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/Objective.java10
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/Objectives.java41
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/OrCriterion.java53
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/QueryCriterion.java (renamed from subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/QueryCriteria.java)29
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/QueryObjective.java17
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/ActivationStoreImpl.java6
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/ActivationStoreListEntry.java6
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/CompleteEquivalenceClassStore.java6
-rw-r--r--subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/FastEquivalenceClassStore.java6
49 files changed, 1349 insertions, 168 deletions
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/ActionFactory.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/ActionFactory.java
deleted file mode 100644
index 524c2f55..00000000
--- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/ActionFactory.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;
7
8import org.eclipse.collections.api.block.procedure.Procedure;
9import tools.refinery.store.model.Model;
10import tools.refinery.store.tuple.Tuple;
11
12public interface ActionFactory {
13 Procedure<Tuple> prepare(Model model);
14}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/DanglingEdges.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/DanglingEdges.java
new file mode 100644
index 00000000..ac9d125b
--- /dev/null
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/DanglingEdges.java
@@ -0,0 +1,12 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse.modification;
7
8public enum DanglingEdges {
9 IGNORE,
10 DELETE,
11 FAIL
12}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/ModificationAdapter.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/ModificationAdapter.java
index f15c16e0..58b60499 100644
--- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/ModificationAdapter.java
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/ModificationAdapter.java
@@ -16,7 +16,7 @@ public interface ModificationAdapter extends ModelAdapter {
16 16
17 Tuple1 createObject(); 17 Tuple1 createObject();
18 18
19 Tuple deleteObject(Tuple tuple); 19 boolean deleteObject(Tuple tuple, DanglingEdges danglingEdges);
20 20
21 static ModificationBuilder builder() { 21 static ModificationBuilder builder() {
22 return new ModificationBuilderImpl(); 22 return new ModificationBuilderImpl();
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/actions/CreateActionLiteral.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/actions/CreateActionLiteral.java
new file mode 100644
index 00000000..5b86a5e1
--- /dev/null
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/actions/CreateActionLiteral.java
@@ -0,0 +1,43 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse.modification.actions;
7
8import tools.refinery.store.dse.modification.ModificationAdapter;
9import tools.refinery.store.dse.transition.actions.AbstractActionLiteral;
10import tools.refinery.store.dse.transition.actions.BoundActionLiteral;
11import tools.refinery.store.model.Model;
12import tools.refinery.store.query.term.NodeVariable;
13
14import java.util.List;
15
16public class CreateActionLiteral extends AbstractActionLiteral {
17 private final NodeVariable variable;
18
19 public CreateActionLiteral(NodeVariable variable) {
20
21 this.variable = variable;
22 }
23
24 public NodeVariable getVariable() {
25 return variable;
26 }
27
28 @Override
29 public List<NodeVariable> getInputVariables() {
30 return List.of();
31 }
32
33 @Override
34 public List<NodeVariable> getOutputVariables() {
35 return List.of(variable);
36 }
37
38 @Override
39 public BoundActionLiteral bindToModel(Model model) {
40 var adapter = model.getAdapter(ModificationAdapter.class);
41 return ignoredTuple -> adapter.createObject();
42 }
43}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/actions/DeleteActionLiteral.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/actions/DeleteActionLiteral.java
new file mode 100644
index 00000000..18ad2b9d
--- /dev/null
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/actions/DeleteActionLiteral.java
@@ -0,0 +1,51 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse.modification.actions;
7
8import tools.refinery.store.dse.modification.DanglingEdges;
9import tools.refinery.store.dse.modification.ModificationAdapter;
10import tools.refinery.store.dse.transition.actions.AbstractActionLiteral;
11import tools.refinery.store.dse.transition.actions.BoundActionLiteral;
12import tools.refinery.store.model.Model;
13import tools.refinery.store.query.term.NodeVariable;
14import tools.refinery.store.tuple.Tuple;
15
16import java.util.List;
17
18public class DeleteActionLiteral extends AbstractActionLiteral {
19 private final NodeVariable variable;
20 private final DanglingEdges danglingEdges;
21
22 public DeleteActionLiteral(NodeVariable variable, DanglingEdges danglingEdges) {
23
24 this.variable = variable;
25 this.danglingEdges = danglingEdges;
26 }
27
28 public NodeVariable getVariable() {
29 return variable;
30 }
31
32 public DanglingEdges getDanglingEdges() {
33 return danglingEdges;
34 }
35
36 @Override
37 public List<NodeVariable> getInputVariables() {
38 return List.of(variable);
39 }
40
41 @Override
42 public List<NodeVariable> getOutputVariables() {
43 return List.of();
44 }
45
46 @Override
47 public BoundActionLiteral bindToModel(Model model) {
48 var adapter = model.getAdapter(ModificationAdapter.class);
49 return tuple -> adapter.deleteObject(tuple, danglingEdges) ? Tuple.of() : null;
50 }
51}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/actions/ModificationActionLiterals.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/actions/ModificationActionLiterals.java
new file mode 100644
index 00000000..31f50ac7
--- /dev/null
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/actions/ModificationActionLiterals.java
@@ -0,0 +1,23 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse.modification.actions;
7
8import tools.refinery.store.dse.modification.DanglingEdges;
9import tools.refinery.store.query.term.NodeVariable;
10
11public class ModificationActionLiterals {
12 private ModificationActionLiterals() {
13 throw new IllegalArgumentException("This is a static utility class and should not be instantiated directly");
14 }
15
16 public static CreateActionLiteral create(NodeVariable variable) {
17 return new CreateActionLiteral(variable);
18 }
19
20 public static DeleteActionLiteral delete(NodeVariable variable, DanglingEdges danglingEdges) {
21 return new DeleteActionLiteral(variable, danglingEdges);
22 }
23}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/internal/ModificationAdapterImpl.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/internal/ModificationAdapterImpl.java
index b2a80d71..4e77c462 100644
--- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/internal/ModificationAdapterImpl.java
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/modification/internal/ModificationAdapterImpl.java
@@ -6,6 +6,7 @@
6package tools.refinery.store.dse.modification.internal; 6package tools.refinery.store.dse.modification.internal;
7 7
8import tools.refinery.store.adapter.ModelStoreAdapter; 8import tools.refinery.store.adapter.ModelStoreAdapter;
9import tools.refinery.store.dse.modification.DanglingEdges;
9import tools.refinery.store.dse.modification.ModificationAdapter; 10import tools.refinery.store.dse.modification.ModificationAdapter;
10import tools.refinery.store.model.Interpretation; 11import tools.refinery.store.model.Interpretation;
11import tools.refinery.store.model.Model; 12import tools.refinery.store.model.Model;
@@ -13,6 +14,8 @@ import tools.refinery.store.representation.Symbol;
13import tools.refinery.store.tuple.Tuple; 14import tools.refinery.store.tuple.Tuple;
14import tools.refinery.store.tuple.Tuple1; 15import tools.refinery.store.tuple.Tuple1;
15 16
17import java.util.HashSet;
18
16public class ModificationAdapterImpl implements ModificationAdapter { 19public class ModificationAdapterImpl implements ModificationAdapter {
17 static final Symbol<Integer> NEXT_ID = Symbol.of("NEXT_ID", 0, Integer.class, 0); 20 static final Symbol<Integer> NEXT_ID = Symbol.of("NEXT_ID", 0, Integer.class, 0);
18 21
@@ -49,14 +52,56 @@ public class ModificationAdapterImpl implements ModificationAdapter {
49 } 52 }
50 53
51 @Override 54 @Override
52 public Tuple deleteObject(Tuple tuple) { 55 public boolean deleteObject(Tuple tuple, DanglingEdges danglingEdges) {
53 if (tuple.getSize() != 1) { 56 if (tuple.getSize() != 1) {
54 throw new IllegalArgumentException("Tuple size must be 1"); 57 throw new IllegalArgumentException("Tuple size must be 1");
55 } 58 }
56// TODO: implement more efficient deletion 59 int objectId = tuple.get(0);
57 if (tuple.get(0) == getModelSize() - 1) { 60 if (danglingEdges == DanglingEdges.DELETE) {
58 nodeCountInterpretation.put(Tuple.of(), getModelSize() - 1); 61 deleteDanglingEdges(objectId);
62 } else if (danglingEdges == DanglingEdges.FAIL && hasDanglingEdges(objectId)) {
63 return false;
64
65 }
66 int modelSize = getModelSize();
67 if (objectId == modelSize - 1) {
68 nodeCountInterpretation.put(Tuple.of(), modelSize - 1);
69 }
70 return true;
71 }
72
73 private void deleteDanglingEdges(int objectId) {
74 for (var symbol : model.getStore().getSymbols()) {
75 deleteDanglingEdges(objectId, (Symbol<?>) symbol);
76 }
77 }
78
79 private <T> void deleteDanglingEdges(int objectId, Symbol<T> symbol) {
80 var interpretation = model.getInterpretation(symbol);
81 var toDelete = new HashSet<Tuple>();
82 int arity = symbol.arity();
83 for (int i = 0; i < arity; i++) {
84 var cursor = interpretation.getAdjacent(i, objectId);
85 while (cursor.move()) {
86 toDelete.add(cursor.getKey());
87 }
88 }
89 var defaultValue = symbol.defaultValue();
90 for (var tuple : toDelete) {
91 interpretation.put(tuple, defaultValue);
92 }
93 }
94
95 private boolean hasDanglingEdges(int objectId) {
96 for (var symbol : model.getStore().getSymbols()) {
97 var interpretation = model.getInterpretation(symbol);
98 int arity = symbol.arity();
99 for (int i = 0; i < arity; i++) {
100 if (interpretation.getAdjacentSize(i, objectId) > 0) {
101 return true;
102 }
103 }
59 } 104 }
60 return tuple; 105 return false;
61 } 106 }
62} 107}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstStoreManager.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstStoreManager.java
index 0b9aae9c..4ccba6f7 100644
--- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstStoreManager.java
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/strategy/BestFirstStoreManager.java
@@ -5,7 +5,6 @@
5 */ 5 */
6package tools.refinery.store.dse.strategy; 6package tools.refinery.store.dse.strategy;
7 7
8import org.eclipse.collections.api.block.procedure.Procedure;
9import tools.refinery.store.dse.transition.DesignSpaceExplorationStoreAdapter; 8import tools.refinery.store.dse.transition.DesignSpaceExplorationStoreAdapter;
10import tools.refinery.store.dse.transition.VersionWithObjectiveValue; 9import tools.refinery.store.dse.transition.VersionWithObjectiveValue;
11import tools.refinery.store.dse.transition.statespace.ActivationStore; 10import tools.refinery.store.dse.transition.statespace.ActivationStore;
@@ -24,6 +23,8 @@ import tools.refinery.visualization.ModelVisualizerStoreAdapter;
24import tools.refinery.visualization.statespace.VisualizationStore; 23import tools.refinery.visualization.statespace.VisualizationStore;
25import tools.refinery.visualization.statespace.internal.VisualizationStoreImpl; 24import tools.refinery.visualization.statespace.internal.VisualizationStoreImpl;
26 25
26import java.util.function.Consumer;
27
27public class BestFirstStoreManager { 28public class BestFirstStoreManager {
28 29
29 ModelStore modelStore; 30 ModelStore modelStore;
@@ -39,7 +40,7 @@ public class BestFirstStoreManager {
39 modelStore.getAdapter(DesignSpaceExplorationStoreAdapter.class); 40 modelStore.getAdapter(DesignSpaceExplorationStoreAdapter.class);
40 41
41 objectiveStore = new ObjectivePriorityQueueImpl(storeAdapter.getObjectives()); 42 objectiveStore = new ObjectivePriorityQueueImpl(storeAdapter.getObjectives());
42 Procedure<VersionWithObjectiveValue> whenAllActivationsVisited = x -> objectiveStore.remove(x); 43 Consumer<VersionWithObjectiveValue> whenAllActivationsVisited = x -> objectiveStore.remove(x);
43 activationStore = new ActivationStoreImpl(storeAdapter.getTransformations().size(), whenAllActivationsVisited); 44 activationStore = new ActivationStoreImpl(storeAdapter.getTransformations().size(), whenAllActivationsVisited);
44 solutionStore = new SolutionStoreImpl(50); 45 solutionStore = new SolutionStoreImpl(50);
45 equivalenceClassStore = new FastEquivalenceClassStore(modelStore.getAdapter(StateCoderStoreAdapter.class)) { 46 equivalenceClassStore = new FastEquivalenceClassStore(modelStore.getAdapter(StateCoderStoreAdapter.class)) {
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/DesignSpaceExplorationAdapter.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/DesignSpaceExplorationAdapter.java
index 37448309..d326f1dd 100644
--- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/DesignSpaceExplorationAdapter.java
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/DesignSpaceExplorationAdapter.java
@@ -7,25 +7,22 @@ package tools.refinery.store.dse.transition;
7 7
8import tools.refinery.store.adapter.ModelAdapter; 8import tools.refinery.store.adapter.ModelAdapter;
9import tools.refinery.store.dse.transition.internal.DesignSpaceExplorationBuilderImpl; 9import tools.refinery.store.dse.transition.internal.DesignSpaceExplorationBuilderImpl;
10import tools.refinery.store.map.Version;
11import tools.refinery.store.tuple.Tuple;
12import tools.refinery.store.tuple.Tuple1;
13 10
14import java.util.Collection;
15import java.util.List; 11import java.util.List;
16 12
17public interface DesignSpaceExplorationAdapter extends ModelAdapter { 13public interface DesignSpaceExplorationAdapter extends ModelAdapter {
18
19
20
21 @Override 14 @Override
22 DesignSpaceExplorationStoreAdapter getStoreAdapter(); 15 DesignSpaceExplorationStoreAdapter getStoreAdapter();
23 16
24 static DesignSpaceExplorationBuilder builder() { 17 static DesignSpaceExplorationBuilder builder() {
25 return new DesignSpaceExplorationBuilderImpl(); 18 return new DesignSpaceExplorationBuilderImpl();
26 } 19 }
20
27 List<Transformation> getTransformations(); 21 List<Transformation> getTransformations();
22
28 boolean checkAccept(); 23 boolean checkAccept();
24
29 boolean checkExclude(); 25 boolean checkExclude();
26
30 ObjectiveValue getObjectiveValue(); 27 ObjectiveValue getObjectiveValue();
31} 28}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/DesignSpaceExplorationBuilder.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/DesignSpaceExplorationBuilder.java
index 3855a20a..800cf8f7 100644
--- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/DesignSpaceExplorationBuilder.java
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/DesignSpaceExplorationBuilder.java
@@ -12,14 +12,16 @@ import tools.refinery.store.dse.transition.objectives.Objective;
12import java.util.Collection; 12import java.util.Collection;
13import java.util.List; 13import java.util.List;
14 14
15// Builder pattern with methods returning {@code this} for convenience.
16@SuppressWarnings("UnusedReturnValue")
15public interface DesignSpaceExplorationBuilder extends ModelAdapterBuilder { 17public interface DesignSpaceExplorationBuilder extends ModelAdapterBuilder {
18 DesignSpaceExplorationBuilder transformation(Rule transformationRuleDefinition);
16 19
17 DesignSpaceExplorationBuilder transformation(TransformationRule transformationRuleDefinition); 20 default DesignSpaceExplorationBuilder transformations(Rule... transformationRuleDefinitions) {
18 default DesignSpaceExplorationBuilder transformations(TransformationRule... transformationRuleDefinitions) {
19 return transformations(List.of(transformationRuleDefinitions)); 21 return transformations(List.of(transformationRuleDefinitions));
20 } 22 }
21 23
22 default DesignSpaceExplorationBuilder transformations(Collection<? extends TransformationRule> transformationRules) { 24 default DesignSpaceExplorationBuilder transformations(Collection<? extends Rule> transformationRules) {
23 transformationRules.forEach(this::transformation); 25 transformationRules.forEach(this::transformation);
24 return this; 26 return this;
25 } 27 }
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/DesignSpaceExplorationStoreAdapter.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/DesignSpaceExplorationStoreAdapter.java
index 5c8c7a4d..fb082fae 100644
--- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/DesignSpaceExplorationStoreAdapter.java
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/DesignSpaceExplorationStoreAdapter.java
@@ -17,7 +17,7 @@ public interface DesignSpaceExplorationStoreAdapter extends ModelStoreAdapter
17 @Override 17 @Override
18 DesignSpaceExplorationAdapter createModelAdapter(Model model); 18 DesignSpaceExplorationAdapter createModelAdapter(Model model);
19 19
20 List<TransformationRule> getTransformations(); 20 List<Rule> getTransformations();
21 21
22 List<Criterion> getAccepts(); 22 List<Criterion> getAccepts();
23 23
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/Rule.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/Rule.java
new file mode 100644
index 00000000..ff45ed3e
--- /dev/null
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/Rule.java
@@ -0,0 +1,99 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse.transition;
7
8import tools.refinery.store.dse.transition.actions.Action;
9import tools.refinery.store.dse.transition.actions.BoundAction;
10import tools.refinery.store.dse.transition.callback.*;
11import tools.refinery.store.model.Model;
12import tools.refinery.store.query.dnf.RelationalQuery;
13
14public class Rule {
15 private final String name;
16 private final RelationalQuery precondition;
17 private final Action action;
18
19 public Rule(String name, RelationalQuery precondition, Action action) {
20 if (precondition.arity() != action.getArity()) {
21 throw new IllegalArgumentException("Expected an action clause with %d parameters, got %d instead"
22 .formatted(precondition.arity(), action.getArity()));
23 }
24 this.name = name;
25 this.precondition = precondition;
26 this.action = action;
27 }
28
29 public String getName() {
30 return name;
31 }
32
33 public RelationalQuery getPrecondition() {
34 return precondition;
35 }
36
37 public BoundAction createAction(Model model) {
38 return action.bindToModel(model);
39 }
40
41 public static RuleBuilder builder(String name) {
42 return new RuleBuilder(name);
43 }
44
45 public static RuleBuilder builder() {
46 return builder(null);
47 }
48
49 public static Rule of(String name, RuleCallback0 callback) {
50 var builder = builder(name);
51 callback.accept(builder);
52 return builder.build();
53 }
54
55 public static Rule of(RuleCallback0 callback) {
56 return of(null, callback);
57 }
58
59 public static Rule of(String name, RuleCallback1 callback) {
60 var builder = builder(name);
61 callback.accept(builder, builder.parameter("p1"));
62 return builder.build();
63 }
64
65 public static Rule of(RuleCallback1 callback) {
66 return of(null, callback);
67 }
68
69 public static Rule of(String name, RuleCallback2 callback) {
70 var builder = builder(name);
71 callback.accept(builder, builder.parameter("p1"), builder.parameter("p2"));
72 return builder.build();
73 }
74
75 public static Rule of(RuleCallback2 callback) {
76 return of(null, callback);
77 }
78
79 public static Rule of(String name, RuleCallback3 callback) {
80 var builder = builder(name);
81 callback.accept(builder, builder.parameter("p1"), builder.parameter("p2"), builder.parameter("p3"));
82 return builder.build();
83 }
84
85 public static Rule of(RuleCallback3 callback) {
86 return of(null, callback);
87 }
88
89 public static Rule of(String name, RuleCallback4 callback) {
90 var builder = builder(name);
91 callback.accept(builder, builder.parameter("p1"), builder.parameter("p2"), builder.parameter("p3"),
92 builder.parameter("p4"));
93 return builder.build();
94 }
95
96 public static Rule of(RuleCallback4 callback) {
97 return of(null, callback);
98 }
99}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/RuleBuilder.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/RuleBuilder.java
new file mode 100644
index 00000000..865ac369
--- /dev/null
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/RuleBuilder.java
@@ -0,0 +1,71 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse.transition;
7
8import tools.refinery.store.dse.transition.actions.Action;
9import tools.refinery.store.dse.transition.actions.ActionLiteral;
10import tools.refinery.store.dse.transition.callback.*;
11import tools.refinery.store.query.dnf.AbstractQueryBuilder;
12import tools.refinery.store.query.dnf.Dnf;
13import tools.refinery.store.query.term.Variable;
14
15import java.util.List;
16
17public class RuleBuilder extends AbstractQueryBuilder<RuleBuilder> {
18 private final String name;
19 private List<ActionLiteral> action;
20
21 RuleBuilder(String name) {
22 super(Dnf.builder(name == null ? null : name + "#precondition"));
23 this.name = name;
24 }
25
26 @Override
27 protected RuleBuilder self() {
28 return this;
29 }
30
31 public RuleBuilder action(ActionLiteral... literals) {
32 return action(List.of(literals));
33 }
34
35 public RuleBuilder action(List<? extends ActionLiteral> literals) {
36 if (this.action != null) {
37 throw new IllegalStateException("Actions have already been set");
38 }
39 this.action = List.copyOf(literals);
40 return this;
41 }
42
43 public RuleBuilder action(Action action) {
44 return action(action.getActionLiterals());
45 }
46
47 public RuleBuilder action(ActionCallback0 callback) {
48 return action(callback.toLiterals());
49 }
50
51 public RuleBuilder action(ActionCallback1 callback) {
52 return action(callback.toLiterals(Variable.of("v1")));
53 }
54
55 public RuleBuilder action(ActionCallback2 callback) {
56 return action(callback.toLiterals(Variable.of("v1"), Variable.of("v2")));
57 }
58
59 public RuleBuilder action(ActionCallback3 callback) {
60 return action(callback.toLiterals(Variable.of("v1"), Variable.of("v2"), Variable.of("v3")));
61 }
62
63 public RuleBuilder action(ActionCallback4 callback) {
64 return action(callback.toLiterals(Variable.of("v1"), Variable.of("v2"), Variable.of("v3"), Variable.of("v4")));
65 }
66
67 public Rule build() {
68 var precondition = dnfBuilder.build().asRelation();
69 return new Rule(name, precondition, Action.ofPrecondition(precondition, action));
70 }
71}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/Transformation.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/Transformation.java
index 2cce738f..0eeccbdf 100644
--- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/Transformation.java
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/Transformation.java
@@ -5,25 +5,27 @@
5 */ 5 */
6package tools.refinery.store.dse.transition; 6package tools.refinery.store.dse.transition;
7 7
8import org.eclipse.collections.api.block.procedure.Procedure; 8import tools.refinery.store.dse.transition.actions.BoundAction;
9import tools.refinery.store.model.Model;
10import tools.refinery.store.query.ModelQueryAdapter;
9import tools.refinery.store.query.resultset.OrderedResultSet; 11import tools.refinery.store.query.resultset.OrderedResultSet;
10import tools.refinery.store.query.resultset.ResultSet; 12import tools.refinery.store.query.resultset.ResultSet;
11import tools.refinery.store.tuple.Tuple; 13import tools.refinery.store.tuple.Tuple;
12 14
13public class Transformation { 15public class Transformation {
14 private final TransformationRule definition; 16 private final Rule definition;
15
16 private final OrderedResultSet<Boolean> activations; 17 private final OrderedResultSet<Boolean> activations;
18 private final BoundAction action;
17 19
18 private final Procedure<Tuple> action; 20 public Transformation(Model model, Rule definition) {
19
20 public Transformation(TransformationRule definition, OrderedResultSet<Boolean> activations, Procedure<Tuple> action) {
21 this.definition = definition; 21 this.definition = definition;
22 this.activations = activations; 22 var precondition = definition.getPrecondition();
23 this.action = action; 23 var queryEngine = model.getAdapter(ModelQueryAdapter.class);
24 activations = new OrderedResultSet<>(queryEngine.getResultSet(precondition));
25 action = definition.createAction(model);
24 } 26 }
25 27
26 public TransformationRule getDefinition() { 28 public Rule getDefinition() {
27 return definition; 29 return definition;
28 } 30 }
29 31
@@ -36,8 +38,6 @@ public class Transformation {
36 } 38 }
37 39
38 public boolean fireActivation(Tuple activation) { 40 public boolean fireActivation(Tuple activation) {
39 action.accept(activation); 41 return action.fire(activation);
40 //queryEngine.flushChanges();
41 return true;
42 } 42 }
43} 43}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/TransformationRule.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/TransformationRule.java
deleted file mode 100644
index d64a3db1..00000000
--- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/TransformationRule.java
+++ /dev/null
@@ -1,63 +0,0 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse.transition;
7
8import tools.refinery.store.model.Model;
9import tools.refinery.store.model.ModelStoreBuilder;
10import tools.refinery.store.query.ModelQueryAdapter;
11import tools.refinery.store.query.ModelQueryBuilder;
12import tools.refinery.store.query.dnf.RelationalQuery;
13import tools.refinery.store.dse.ActionFactory;
14import tools.refinery.store.query.resultset.OrderedResultSet;
15import tools.refinery.store.query.resultset.ResultSet;
16import tools.refinery.store.tuple.Tuple;
17
18import java.util.*;
19
20public class TransformationRule {
21
22 private final String name;
23 private final RelationalQuery precondition;
24 private final ActionFactory actionFactory;
25
26 private Random random;
27 private ModelQueryAdapter queryEngine;
28
29 public TransformationRule(String name, RelationalQuery precondition, ActionFactory actionFactory) {
30 this(name, precondition, actionFactory, new Random());
31 }
32
33 public TransformationRule(String name, RelationalQuery precondition, ActionFactory actionFactory, long seed) {
34 this(name, precondition, actionFactory, new Random(seed));
35 }
36
37 public TransformationRule(String name, RelationalQuery precondition, ActionFactory actionFactory, Random random) {
38 this.name = name;
39 this.precondition = precondition;
40 this.actionFactory = actionFactory;
41 this.random = random;
42 }
43 public void doConfigure(ModelStoreBuilder storeBuilder) {
44 var queryBuilder = storeBuilder.getAdapter(ModelQueryBuilder.class);
45 queryBuilder.query(this.precondition);
46 }
47
48 public Transformation prepare(Model model) {
49 var queryEngine = model.getAdapter(ModelQueryAdapter.class);
50 var activations = new OrderedResultSet<>(queryEngine.getResultSet(precondition));
51 var action = actionFactory.prepare(model);
52 return new Transformation(this,activations,action);
53 }
54
55 public String getName() {
56 return name;
57 }
58
59 public RelationalQuery getPrecondition() {
60 return precondition;
61 }
62
63}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/AbstractActionLiteral.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/AbstractActionLiteral.java
new file mode 100644
index 00000000..e30f06bb
--- /dev/null
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/AbstractActionLiteral.java
@@ -0,0 +1,9 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse.transition.actions;
7
8public abstract class AbstractActionLiteral implements ActionLiteral {
9}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/Action.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/Action.java
new file mode 100644
index 00000000..d63ddfdd
--- /dev/null
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/Action.java
@@ -0,0 +1,132 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse.transition.actions;
7
8import org.eclipse.collections.api.factory.primitive.ObjectIntMaps;
9import org.eclipse.collections.api.map.primitive.MutableObjectIntMap;
10import org.jetbrains.annotations.Nullable;
11import tools.refinery.store.model.Model;
12import tools.refinery.store.query.dnf.RelationalQuery;
13import tools.refinery.store.query.dnf.SymbolicParameter;
14import tools.refinery.store.query.term.NodeVariable;
15
16import java.util.*;
17
18public class Action {
19 private final List<NodeVariable> parameters;
20 private final Set<NodeVariable> localVariables;
21 private final List<ActionLiteral> actionLiterals;
22 private final int[] @Nullable [] inputAllocations;
23 private final int[] @Nullable [] outputAllocations;
24
25 public Action(List<NodeVariable> parameters, List<? extends ActionLiteral> actionLiterals) {
26 this.parameters = List.copyOf(parameters);
27 this.actionLiterals = List.copyOf(actionLiterals);
28 var allocation = ObjectIntMaps.mutable.<NodeVariable>empty();
29 int arity = parameters.size();
30 for (int i = 0; i < arity; i++) {
31 allocation.put(parameters.get(i), i);
32 }
33 var mutableLocalVariables = new LinkedHashSet<NodeVariable>();
34 int size = actionLiterals.size();
35 inputAllocations = new int[size][];
36 outputAllocations = new int[size][];
37 for (int i = 0; i < size; i++) {
38 computeInputAllocation(i, parameters, allocation);
39 computeOutputAllocation(i, mutableLocalVariables, allocation);
40 }
41 this.localVariables = Collections.unmodifiableSet(mutableLocalVariables);
42 }
43
44 private void computeInputAllocation(int actionIndex, List<NodeVariable> parameters,
45 MutableObjectIntMap<NodeVariable> allocation) {
46 var actionLiteral = actionLiterals.get(actionIndex);
47 var inputVariables = actionLiteral.getInputVariables();
48 if (inputVariables.equals(parameters)) {
49 // Identity mappings use a {@code null} allocation to pass the activation tuple unchanged.
50 return;
51 }
52 var inputs = new int[inputVariables.size()];
53 for (int i = 0; i < inputs.length; i++) {
54 var variable = inputVariables.get(i);
55 if (!allocation.containsKey(variable)) {
56 throw new IllegalArgumentException("Unbound input variable %s of action literal %s"
57 .formatted(variable, actionLiteral));
58 }
59 inputs[i] = allocation.get(variable);
60 }
61 inputAllocations[actionIndex] = inputs;
62 }
63
64 private void computeOutputAllocation(int actionIndex, Set<NodeVariable> mutableLocalVariable,
65 MutableObjectIntMap<NodeVariable> allocation) {
66 var actionLiteral = actionLiterals.get(actionIndex);
67 var outputVariables = actionLiteral.getOutputVariables();
68 int size = outputVariables.size();
69 if (size == 0) {
70 // Identity mappings use a {@code null} allocation to avoid iterating over the output tuple.
71 return;
72 }
73 if (size >= 2 && new HashSet<>(outputVariables).size() != size) {
74 throw new IllegalArgumentException("Action literal %s has duplicate output variables %s"
75 .formatted(actionLiteral, outputVariables));
76 }
77 int arity = parameters.size();
78 var outputs = new int[size];
79 for (int i = 0; i < size; i++) {
80 var variable = outputVariables.get(i);
81 if (allocation.containsKey(variable)) {
82 throw new IllegalArgumentException("Output variable %s of action literal %s was already assigned"
83 .formatted(variable, actionLiteral));
84 }
85 int variableId = mutableLocalVariable.size();
86 allocation.put(variable, arity + variableId);
87 outputs[i] = variableId;
88 mutableLocalVariable.add(variable);
89 }
90 outputAllocations[actionIndex] = outputs;
91 }
92
93 public List<NodeVariable> getParameters() {
94 return parameters;
95 }
96
97 public int getArity() {
98 return parameters.size();
99 }
100
101 public Set<NodeVariable> getLocalVariables() {
102 return localVariables;
103 }
104
105 public List<ActionLiteral> getActionLiterals() {
106 return actionLiterals;
107 }
108
109 int @Nullable [] getInputAllocation(int actionIndex) {
110 return inputAllocations[actionIndex];
111 }
112
113 int @Nullable [] getOutputAllocation(int actionIndex) {
114 return outputAllocations[actionIndex];
115 }
116
117 public BoundAction bindToModel(Model model) {
118 return new BoundAction(this, model);
119 }
120
121 public static Action ofSymbolicParameters(List<SymbolicParameter> symbolicParameters,
122 List<? extends ActionLiteral> actionLiterals) {
123 var nodeVariables = symbolicParameters.stream()
124 .map(symbolicParameter -> symbolicParameter.getVariable().asNodeVariable())
125 .toList();
126 return new Action(nodeVariables, actionLiterals);
127 }
128
129 public static Action ofPrecondition(RelationalQuery precondition, List<? extends ActionLiteral> actionLiterals) {
130 return ofSymbolicParameters(precondition.getDnf().getSymbolicParameters(), actionLiterals);
131 }
132}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/ActionLiteral.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/ActionLiteral.java
new file mode 100644
index 00000000..a721ef73
--- /dev/null
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/ActionLiteral.java
@@ -0,0 +1,19 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse.transition.actions;
7
8import tools.refinery.store.model.Model;
9import tools.refinery.store.query.term.NodeVariable;
10
11import java.util.List;
12
13public interface ActionLiteral {
14 List<NodeVariable> getInputVariables();
15
16 List<NodeVariable> getOutputVariables();
17
18 BoundActionLiteral bindToModel(Model model);
19}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/ActionLiterals.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/ActionLiterals.java
new file mode 100644
index 00000000..275e1e25
--- /dev/null
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/ActionLiterals.java
@@ -0,0 +1,33 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse.transition.actions;
7
8import tools.refinery.store.query.term.NodeVariable;
9import tools.refinery.store.representation.Symbol;
10
11import java.util.List;
12import java.util.Objects;
13
14public final class ActionLiterals {
15 private ActionLiterals() {
16 throw new IllegalArgumentException("This is a static utility class and should not be instantiated directly");
17 }
18
19 public static <T> PutActionLiteral<T> put(Symbol<T> symbol, T value, NodeVariable... parameters) {
20 return new PutActionLiteral<>(symbol, value, List.of(parameters));
21 }
22
23 public static PutActionLiteral<Boolean> add(Symbol<Boolean> symbol, NodeVariable... parameters) {
24 if (!Objects.equals(symbol.defaultValue(), false)) {
25 throw new IllegalArgumentException("Use put to add a value to symbols other than two-valued logic");
26 }
27 return put(symbol, true, parameters);
28 }
29
30 public static <T> PutActionLiteral<T> remove(Symbol<T> symbol, NodeVariable... parameters) {
31 return put(symbol, symbol.defaultValue(), parameters);
32 }
33}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/BoundAction.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/BoundAction.java
new file mode 100644
index 00000000..55f43735
--- /dev/null
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/BoundAction.java
@@ -0,0 +1,109 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse.transition.actions;
7
8import org.jetbrains.annotations.Nullable;
9import tools.refinery.store.model.Model;
10import tools.refinery.store.tuple.Tuple;
11
12public class BoundAction {
13 private final Action action;
14 private final BoundActionLiteral[] boundLiterals;
15 private Tuple activation;
16 private final int[] localVariables;
17
18 BoundAction(Action action, Model model) {
19 this.action = action;
20 var actionLiterals = action.getActionLiterals();
21 int size = actionLiterals.size();
22 boundLiterals = new BoundActionLiteral[size];
23 for (int i = 0; i < size; i++) {
24 boundLiterals[i] = actionLiterals.get(i).bindToModel(model);
25 }
26 localVariables = new int[action.getLocalVariables().size()];
27 }
28
29 public boolean fire(Tuple activation) {
30 if (this.activation != null) {
31 throw new IllegalStateException("Reentrant firing is not allowed");
32 }
33 this.activation = activation;
34 try {
35 int size = boundLiterals.length;
36 for (int i = 0; i < size; i++) {
37 var inputAllocation = action.getInputAllocation(i);
38 var boundLiteral = boundLiterals[i];
39 var input = getInputTuple(inputAllocation);
40 var output = boundLiteral.fire(input);
41 if (output == null) {
42 return false;
43 }
44 var outputAllocation = this.action.getOutputAllocation(i);
45 setOutputTuple(outputAllocation, output);
46 }
47 } finally {
48 this.activation = null;
49 }
50 return true;
51 }
52
53 private Tuple getInputTuple(int @Nullable [] inputAllocation) {
54 if (inputAllocation == null) {
55 // Identity allocation.
56 return activation;
57 }
58 return switch (inputAllocation.length) {
59 case 0 -> Tuple.of();
60 case 1 -> Tuple.of(getInput(inputAllocation[0]));
61 case 2 -> Tuple.of(getInput(inputAllocation[0]), getInput(inputAllocation[1]));
62 case 3 -> Tuple.of(getInput(inputAllocation[0]), getInput(inputAllocation[1]),
63 getInput(inputAllocation[2]));
64 case 4 -> Tuple.of(getInput(inputAllocation[0]), getInput(inputAllocation[1]),
65 getInput(inputAllocation[2]), getInput(inputAllocation[3]));
66 default -> {
67 var elements = new int[inputAllocation.length];
68 for (var i = 0; i < inputAllocation.length; i++) {
69 elements[i] = getInput(inputAllocation[i]);
70 }
71 yield Tuple.of(elements);
72 }
73 };
74 }
75
76 private int getInput(int index) {
77 int arity = action.getArity();
78 return index < arity ? activation.get(index) : localVariables[index - arity];
79 }
80
81 private void setOutputTuple(int @Nullable [] outputAllocation, Tuple output) {
82 if (outputAllocation == null || outputAllocation.length == 0) {
83 return;
84 }
85 switch (outputAllocation.length) {
86 case 1 -> localVariables[outputAllocation[0]] = output.get(0);
87 case 2 -> {
88 localVariables[outputAllocation[0]] = output.get(0);
89 localVariables[outputAllocation[1]] = output.get(1);
90 }
91 case 3 -> {
92 localVariables[outputAllocation[0]] = output.get(0);
93 localVariables[outputAllocation[1]] = output.get(1);
94 localVariables[outputAllocation[2]] = output.get(2);
95 }
96 case 4 -> {
97 localVariables[outputAllocation[0]] = output.get(0);
98 localVariables[outputAllocation[1]] = output.get(1);
99 localVariables[outputAllocation[2]] = output.get(2);
100 localVariables[outputAllocation[3]] = output.get(3);
101 }
102 default -> {
103 for (int i = 0; i < outputAllocation.length; i++) {
104 localVariables[outputAllocation[i]] = output.get(i);
105 }
106 }
107 }
108 }
109}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/BoundActionLiteral.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/BoundActionLiteral.java
new file mode 100644
index 00000000..09c3c58c
--- /dev/null
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/BoundActionLiteral.java
@@ -0,0 +1,16 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse.transition.actions;
7
8import org.jetbrains.annotations.NotNull;
9import org.jetbrains.annotations.Nullable;
10import tools.refinery.store.tuple.Tuple;
11
12@FunctionalInterface
13public interface BoundActionLiteral {
14 @Nullable
15 Tuple fire(@NotNull Tuple tuple);
16}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/PutActionLiteral.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/PutActionLiteral.java
new file mode 100644
index 00000000..86288921
--- /dev/null
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/actions/PutActionLiteral.java
@@ -0,0 +1,64 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse.transition.actions;
7
8import tools.refinery.store.model.Model;
9import tools.refinery.store.query.term.NodeVariable;
10import tools.refinery.store.representation.Symbol;
11import tools.refinery.store.tuple.Tuple;
12
13import java.util.List;
14
15public class PutActionLiteral<T> extends AbstractActionLiteral {
16 private final Symbol<T> symbol;
17 private final List<NodeVariable> parameters;
18 private final T value;
19
20 public PutActionLiteral(Symbol<T> symbol, T value, List<NodeVariable> parameters) {
21 if (symbol.arity() != parameters.size()) {
22 throw new IllegalArgumentException("Expected %d parameters for symbol %s, got %d instead"
23 .formatted(symbol.arity(), symbol, parameters.size()));
24 }
25 if (value != null && !symbol.valueType().isInstance(value)) {
26 throw new IllegalArgumentException("Expected value of type %s for symbol %s, got %s of type %s instead"
27 .formatted(symbol.valueType().getName(), symbol, value, value.getClass().getName()));
28 }
29 this.symbol = symbol;
30 this.parameters = List.copyOf(parameters);
31 this.value = value;
32 }
33
34 public Symbol<T> getSymbol() {
35 return symbol;
36 }
37
38 public List<NodeVariable> getParameters() {
39 return parameters;
40 }
41
42 public T getValue() {
43 return value;
44 }
45
46 @Override
47 public List<NodeVariable> getInputVariables() {
48 return getParameters();
49 }
50
51 @Override
52 public List<NodeVariable> getOutputVariables() {
53 return List.of();
54 }
55
56 @Override
57 public BoundActionLiteral bindToModel(Model model) {
58 var interpretation = model.getInterpretation(symbol);
59 return tuple -> {
60 interpretation.put(tuple, value);
61 return Tuple.of();
62 };
63 }
64}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback0.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback0.java
new file mode 100644
index 00000000..1190fdeb
--- /dev/null
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback0.java
@@ -0,0 +1,15 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse.transition.callback;
7
8import tools.refinery.store.dse.transition.actions.ActionLiteral;
9
10import java.util.List;
11
12@FunctionalInterface
13public interface ActionCallback0 {
14 List<ActionLiteral> toLiterals();
15}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback1.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback1.java
new file mode 100644
index 00000000..869f1a96
--- /dev/null
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback1.java
@@ -0,0 +1,16 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse.transition.callback;
7
8import tools.refinery.store.dse.transition.actions.ActionLiteral;
9import tools.refinery.store.query.term.NodeVariable;
10
11import java.util.List;
12
13@FunctionalInterface
14public interface ActionCallback1 {
15 List<ActionLiteral> toLiterals(NodeVariable v1);
16}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback2.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback2.java
new file mode 100644
index 00000000..a648fc93
--- /dev/null
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback2.java
@@ -0,0 +1,16 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse.transition.callback;
7
8import tools.refinery.store.dse.transition.actions.ActionLiteral;
9import tools.refinery.store.query.term.NodeVariable;
10
11import java.util.List;
12
13@FunctionalInterface
14public interface ActionCallback2 {
15 List<ActionLiteral> toLiterals(NodeVariable v1, NodeVariable v2);
16}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback3.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback3.java
new file mode 100644
index 00000000..a9b1d334
--- /dev/null
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback3.java
@@ -0,0 +1,16 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse.transition.callback;
7
8import tools.refinery.store.dse.transition.actions.ActionLiteral;
9import tools.refinery.store.query.term.NodeVariable;
10
11import java.util.List;
12
13@FunctionalInterface
14public interface ActionCallback3 {
15 List<ActionLiteral> toLiterals(NodeVariable v1, NodeVariable v2, NodeVariable v3);
16}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback4.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback4.java
new file mode 100644
index 00000000..aef1351c
--- /dev/null
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/ActionCallback4.java
@@ -0,0 +1,16 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse.transition.callback;
7
8import tools.refinery.store.dse.transition.actions.ActionLiteral;
9import tools.refinery.store.query.term.NodeVariable;
10
11import java.util.List;
12
13@FunctionalInterface
14public interface ActionCallback4 {
15 List<ActionLiteral> toLiterals(NodeVariable v1, NodeVariable v2, NodeVariable v3, NodeVariable v4);
16}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback0.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback0.java
new file mode 100644
index 00000000..538c23ba
--- /dev/null
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback0.java
@@ -0,0 +1,13 @@
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.transition.callback;
7
8import tools.refinery.store.dse.transition.RuleBuilder;
9
10@FunctionalInterface
11public interface RuleCallback0 {
12 void accept(RuleBuilder builder);
13}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback1.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback1.java
new file mode 100644
index 00000000..bd7bf4f5
--- /dev/null
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback1.java
@@ -0,0 +1,14 @@
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.transition.callback;
7
8import tools.refinery.store.dse.transition.RuleBuilder;
9import tools.refinery.store.query.term.NodeVariable;
10
11@FunctionalInterface
12public interface RuleCallback1 {
13 void accept(RuleBuilder builder, NodeVariable p1);
14}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback2.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback2.java
new file mode 100644
index 00000000..7b02b68a
--- /dev/null
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback2.java
@@ -0,0 +1,14 @@
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.transition.callback;
7
8import tools.refinery.store.dse.transition.RuleBuilder;
9import tools.refinery.store.query.term.NodeVariable;
10
11@FunctionalInterface
12public interface RuleCallback2 {
13 void accept(RuleBuilder builder, NodeVariable p1, NodeVariable p2);
14}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback3.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback3.java
new file mode 100644
index 00000000..6f112d48
--- /dev/null
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback3.java
@@ -0,0 +1,14 @@
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.transition.callback;
7
8import tools.refinery.store.dse.transition.RuleBuilder;
9import tools.refinery.store.query.term.NodeVariable;
10
11@FunctionalInterface
12public interface RuleCallback3 {
13 void accept(RuleBuilder builder, NodeVariable p1, NodeVariable p2, NodeVariable p3);
14}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback4.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback4.java
new file mode 100644
index 00000000..dbcf8567
--- /dev/null
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/callback/RuleCallback4.java
@@ -0,0 +1,14 @@
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.transition.callback;
7
8import tools.refinery.store.dse.transition.RuleBuilder;
9import tools.refinery.store.query.term.NodeVariable;
10
11@FunctionalInterface
12public interface RuleCallback4 {
13 void accept(RuleBuilder builder, NodeVariable p1, NodeVariable p2, NodeVariable p3, NodeVariable p4);
14}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/internal/DesignSpaceExplorationBuilderImpl.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/internal/DesignSpaceExplorationBuilderImpl.java
index 4371cc03..a91f6870 100644
--- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/internal/DesignSpaceExplorationBuilderImpl.java
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/internal/DesignSpaceExplorationBuilderImpl.java
@@ -7,13 +7,13 @@ package tools.refinery.store.dse.transition.internal;
7 7
8import tools.refinery.store.adapter.AbstractModelAdapterBuilder; 8import tools.refinery.store.adapter.AbstractModelAdapterBuilder;
9import tools.refinery.store.dse.transition.DesignSpaceExplorationBuilder; 9import tools.refinery.store.dse.transition.DesignSpaceExplorationBuilder;
10import tools.refinery.store.dse.transition.TransformationRule; 10import tools.refinery.store.dse.transition.Rule;
11import tools.refinery.store.dse.transition.objectives.Criterion; 11import tools.refinery.store.dse.transition.objectives.Criterion;
12import tools.refinery.store.dse.transition.objectives.Objective; 12import tools.refinery.store.dse.transition.objectives.Objective;
13import tools.refinery.store.model.ModelStore; 13import tools.refinery.store.model.ModelStore;
14import tools.refinery.store.model.ModelStoreBuilder; 14import tools.refinery.store.model.ModelStoreBuilder;
15import tools.refinery.store.query.ModelQueryBuilder;
15 16
16import java.util.ArrayList;
17import java.util.LinkedHashSet; 17import java.util.LinkedHashSet;
18import java.util.List; 18import java.util.List;
19 19
@@ -21,13 +21,13 @@ public class DesignSpaceExplorationBuilderImpl
21 extends AbstractModelAdapterBuilder<DesignSpaceExplorationStoreAdapterImpl> 21 extends AbstractModelAdapterBuilder<DesignSpaceExplorationStoreAdapterImpl>
22 implements DesignSpaceExplorationBuilder { 22 implements DesignSpaceExplorationBuilder {
23 23
24 LinkedHashSet<TransformationRule> transformationRuleDefinitions = new LinkedHashSet<>(); 24 LinkedHashSet<Rule> transformationRuleDefinitions = new LinkedHashSet<>();
25 LinkedHashSet<Criterion> accepts = new LinkedHashSet<>(); 25 LinkedHashSet<Criterion> accepts = new LinkedHashSet<>();
26 LinkedHashSet<Criterion> excludes = new LinkedHashSet<>(); 26 LinkedHashSet<Criterion> excludes = new LinkedHashSet<>();
27 LinkedHashSet<Objective> objectives = new LinkedHashSet<>(); 27 LinkedHashSet<Objective> objectives = new LinkedHashSet<>();
28 28
29 @Override 29 @Override
30 public DesignSpaceExplorationBuilder transformation(TransformationRule transformationRuleDefinition) { 30 public DesignSpaceExplorationBuilder transformation(Rule transformationRuleDefinition) {
31 transformationRuleDefinitions.add(transformationRuleDefinition); 31 transformationRuleDefinitions.add(transformationRuleDefinition);
32 return this; 32 return this;
33 } 33 }
@@ -53,23 +53,23 @@ public class DesignSpaceExplorationBuilderImpl
53 53
54 @Override 54 @Override
55 protected void doConfigure(ModelStoreBuilder storeBuilder) { 55 protected void doConfigure(ModelStoreBuilder storeBuilder) {
56 transformationRuleDefinitions.forEach(x -> x.doConfigure(storeBuilder)); 56 var queryEngine = storeBuilder.getAdapter(ModelQueryBuilder.class);
57 accepts.forEach(x -> x.doConfigure(storeBuilder)); 57 transformationRuleDefinitions.forEach(x -> queryEngine.query(x.getPrecondition()));
58 excludes.forEach(x -> x.doConfigure(storeBuilder)); 58 accepts.forEach(x -> x.configure(storeBuilder));
59 objectives.forEach(x -> x.doConfigure(storeBuilder)); 59 excludes.forEach(x -> x.configure(storeBuilder));
60 objectives.forEach(x -> x.configure(storeBuilder));
60 61
61 super.doConfigure(storeBuilder); 62 super.doConfigure(storeBuilder);
62 } 63 }
63 64
64 @Override 65 @Override
65 protected DesignSpaceExplorationStoreAdapterImpl doBuild(ModelStore store) { 66 protected DesignSpaceExplorationStoreAdapterImpl doBuild(ModelStore store) {
66 List<TransformationRule> transformationRuleDefinitiions1 = new ArrayList<>(transformationRuleDefinitions); 67 List<Rule> transformationRuleDefinitionsList = List.copyOf(transformationRuleDefinitions);
67 List<Criterion> accepts1 = new ArrayList<>(accepts); 68 List<Criterion> acceptsList = List.copyOf(accepts);
68 List<Criterion> excludes1 = new ArrayList<>(excludes); 69 List<Criterion> excludesList = List.copyOf(excludes);
69 List<Objective> objectives1 = new ArrayList<>(objectives); 70 List<Objective> objectivesList = List.copyOf(objectives);
70 71
71 return new DesignSpaceExplorationStoreAdapterImpl(store, 72 return new DesignSpaceExplorationStoreAdapterImpl(store, transformationRuleDefinitionsList, acceptsList,
72 transformationRuleDefinitiions1, accepts1, 73 excludesList, objectivesList);
73 excludes1, objectives1);
74 } 74 }
75} 75}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/internal/DesignSpaceExplorationStoreAdapterImpl.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/internal/DesignSpaceExplorationStoreAdapterImpl.java
index 3319e148..bd85e7a6 100644
--- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/internal/DesignSpaceExplorationStoreAdapterImpl.java
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/internal/DesignSpaceExplorationStoreAdapterImpl.java
@@ -7,7 +7,7 @@ package tools.refinery.store.dse.transition.internal;
7 7
8import tools.refinery.store.dse.transition.DesignSpaceExplorationStoreAdapter; 8import tools.refinery.store.dse.transition.DesignSpaceExplorationStoreAdapter;
9import tools.refinery.store.dse.transition.Transformation; 9import tools.refinery.store.dse.transition.Transformation;
10import tools.refinery.store.dse.transition.TransformationRule; 10import tools.refinery.store.dse.transition.Rule;
11import tools.refinery.store.dse.transition.objectives.Criterion; 11import tools.refinery.store.dse.transition.objectives.Criterion;
12import tools.refinery.store.dse.transition.objectives.CriterionCalculator; 12import tools.refinery.store.dse.transition.objectives.CriterionCalculator;
13import tools.refinery.store.dse.transition.objectives.Objective; 13import tools.refinery.store.dse.transition.objectives.Objective;
@@ -20,18 +20,16 @@ import java.util.List;
20public class DesignSpaceExplorationStoreAdapterImpl implements DesignSpaceExplorationStoreAdapter { 20public class DesignSpaceExplorationStoreAdapterImpl implements DesignSpaceExplorationStoreAdapter {
21 protected final ModelStore store; 21 protected final ModelStore store;
22 22
23 protected final List<TransformationRule> transformationRuleDefinitions; 23 protected final List<Rule> ruleDefinitions;
24 protected final List<Criterion> accepts; 24 protected final List<Criterion> accepts;
25 protected final List<Criterion> excludes; 25 protected final List<Criterion> excludes;
26 protected final List<Objective> objectives; 26 protected final List<Objective> objectives;
27 27
28 public DesignSpaceExplorationStoreAdapterImpl(ModelStore store, 28 public DesignSpaceExplorationStoreAdapterImpl(
29 List<TransformationRule> transformationRuleDefinitions, 29 ModelStore store, List<Rule> ruleDefinitions, List<Criterion> accepts, List<Criterion> excludes,
30 List<Criterion> accepts, List<Criterion> excludes, 30 List<Objective> objectives) {
31 List<Objective> objectives) {
32 this.store = store; 31 this.store = store;
33 32 this.ruleDefinitions = ruleDefinitions;
34 this.transformationRuleDefinitions = transformationRuleDefinitions;
35 this.accepts = accepts; 33 this.accepts = accepts;
36 this.excludes = excludes; 34 this.excludes = excludes;
37 this.objectives = objectives; 35 this.objectives = objectives;
@@ -44,25 +42,31 @@ public class DesignSpaceExplorationStoreAdapterImpl implements DesignSpaceExplor
44 42
45 @Override 43 @Override
46 public DesignSpaceExplorationAdapterImpl createModelAdapter(Model model) { 44 public DesignSpaceExplorationAdapterImpl createModelAdapter(Model model) {
47 final List<Transformation> t = this.transformationRuleDefinitions.stream().map(x->x.prepare(model)).toList(); 45 final List<Transformation> t = this.ruleDefinitions.stream()
48 final List<CriterionCalculator> a = this.accepts.stream().map(x->x.createCalculator(model)).toList(); 46 .map(x -> new Transformation(model, x))
49 final List<CriterionCalculator> e = this.excludes.stream().map(x->x.createCalculator(model)).toList(); 47 .toList();
50 final List<ObjectiveCalculator> o = this.objectives.stream().map(x->x.createCalculator(model)).toList(); 48 final List<CriterionCalculator> a = this.accepts.stream().map(x -> x.createCalculator(model)).toList();
49 final List<CriterionCalculator> e = this.excludes.stream().map(x -> x.createCalculator(model)).toList();
50 final List<ObjectiveCalculator> o = this.objectives.stream().map(x -> x.createCalculator(model)).toList();
51 51
52 return new DesignSpaceExplorationAdapterImpl(model, this, t, a, e, o); 52 return new DesignSpaceExplorationAdapterImpl(model, this, t, a, e, o);
53 } 53 }
54
54 @Override 55 @Override
55 public List<TransformationRule> getTransformations() { 56 public List<Rule> getTransformations() {
56 return transformationRuleDefinitions; 57 return ruleDefinitions;
57 } 58 }
59
58 @Override 60 @Override
59 public List<Criterion> getAccepts() { 61 public List<Criterion> getAccepts() {
60 return accepts; 62 return accepts;
61 } 63 }
64
62 @Override 65 @Override
63 public List<Criterion> getExcludes() { 66 public List<Criterion> getExcludes() {
64 return excludes; 67 return excludes;
65 } 68 }
69
66 @Override 70 @Override
67 public List<Objective> getObjectives() { 71 public List<Objective> getObjectives() {
68 return objectives; 72 return objectives;
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/AndCriterion.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/AndCriterion.java
new file mode 100644
index 00000000..0ad2b7a4
--- /dev/null
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/AndCriterion.java
@@ -0,0 +1,53 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse.transition.objectives;
7
8import tools.refinery.store.model.Model;
9import tools.refinery.store.model.ModelStore;
10import tools.refinery.store.query.literal.Reduction;
11
12import java.util.ArrayList;
13import java.util.Collection;
14
15public final class AndCriterion extends CompositeCriterion {
16 AndCriterion(Collection<? extends Criterion> criteria) {
17 super(criteria);
18 }
19
20 @Override
21 public Reduction getReduction(ModelStore store) {
22 for (var criterion : getCriteria()) {
23 var reduction = criterion.getReduction(store);
24 if (reduction == Reduction.ALWAYS_FALSE) {
25 return Reduction.ALWAYS_FALSE;
26 } else if (reduction == Reduction.NOT_REDUCIBLE) {
27 return Reduction.NOT_REDUCIBLE;
28 }
29 }
30 return Reduction.ALWAYS_TRUE;
31 }
32
33 @Override
34 public CriterionCalculator createCalculator(Model model) {
35 var calculators = new ArrayList<CriterionCalculator>();
36 for (var criterion : getCriteria()) {
37 var reduction = criterion.getReduction(model.getStore());
38 if (reduction == Reduction.ALWAYS_FALSE) {
39 return () -> false;
40 } else if (reduction == Reduction.NOT_REDUCIBLE) {
41 calculators.add(criterion.createCalculator(model));
42 }
43 }
44 return () -> {
45 for (var calculator : calculators) {
46 if (!calculator.isSatisfied()) {
47 return false;
48 }
49 }
50 return true;
51 };
52 }
53}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/CompositeCriterion.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/CompositeCriterion.java
new file mode 100644
index 00000000..5746cc7e
--- /dev/null
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/CompositeCriterion.java
@@ -0,0 +1,43 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse.transition.objectives;
7
8import tools.refinery.store.model.ModelStore;
9import tools.refinery.store.model.ModelStoreBuilder;
10import tools.refinery.store.query.literal.Reduction;
11
12import java.util.*;
13
14public abstract sealed class CompositeCriterion implements Criterion permits AndCriterion, OrCriterion {
15 private final List<Criterion> criteria;
16
17 protected CompositeCriterion(Collection<? extends Criterion> criteria) {
18 var deDuplicatedCriteria = new LinkedHashSet<Criterion>();
19 for (var criterion : criteria) {
20 if (criterion.getClass() == this.getClass()) {
21 var childCriteria = ((CompositeCriterion) criterion).getCriteria();
22 deDuplicatedCriteria.addAll(childCriteria);
23 } else {
24 deDuplicatedCriteria.add(criterion);
25 }
26 }
27 this.criteria = List.copyOf(deDuplicatedCriteria);
28 }
29
30 public List<Criterion> getCriteria() {
31 return criteria;
32 }
33
34 @Override
35 public abstract Reduction getReduction(ModelStore store);
36
37 @Override
38 public void configure(ModelStoreBuilder storeBuilder) {
39 for (var criterion : criteria) {
40 criterion.configure(storeBuilder);
41 }
42 }
43}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/CompositeObjective.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/CompositeObjective.java
new file mode 100644
index 00000000..192a824b
--- /dev/null
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/CompositeObjective.java
@@ -0,0 +1,69 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse.transition.objectives;
7
8import tools.refinery.store.model.Model;
9import tools.refinery.store.model.ModelStore;
10import tools.refinery.store.model.ModelStoreBuilder;
11
12import java.util.ArrayList;
13import java.util.Collection;
14import java.util.Collections;
15import java.util.List;
16
17public class CompositeObjective implements Objective {
18 private final List<Objective> objectives;
19
20 CompositeObjective(Collection<? extends Objective> objectives) {
21 var unwrappedObjectives = new ArrayList<Objective>();
22 for (var objective : objectives) {
23 if (objective instanceof CompositeObjective compositeObjective) {
24 unwrappedObjectives.addAll(compositeObjective.getObjectives());
25 } else {
26 unwrappedObjectives.add(objective);
27 }
28 }
29 this.objectives = Collections.unmodifiableList(unwrappedObjectives);
30 }
31
32 public List<Objective> getObjectives() {
33 return objectives;
34 }
35
36 @Override
37 public boolean isAlwaysZero(ModelStore store) {
38 for (var objective : objectives) {
39 if (!objective.isAlwaysZero(store)) {
40 return false;
41 }
42 }
43 return true;
44 }
45
46 @Override
47 public ObjectiveCalculator createCalculator(Model model) {
48 var calculators = new ArrayList<ObjectiveCalculator>();
49 for (var objective : objectives) {
50 if (!objective.isAlwaysZero(model.getStore())) {
51 calculators.add(objective.createCalculator(model));
52 }
53 }
54 return () -> {
55 double value = 0;
56 for (var calculator : calculators) {
57 value += calculator.getValue();
58 }
59 return value;
60 };
61 }
62
63 @Override
64 public void configure(ModelStoreBuilder storeBuilder) {
65 for (var objective : objectives) {
66 objective.configure(storeBuilder);
67 }
68 }
69}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/CountObjective.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/CountObjective.java
new file mode 100644
index 00000000..fbd05ded
--- /dev/null
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/CountObjective.java
@@ -0,0 +1,47 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse.transition.objectives;
7
8import tools.refinery.store.model.Model;
9import tools.refinery.store.model.ModelStore;
10import tools.refinery.store.model.ModelStoreBuilder;
11import tools.refinery.store.query.ModelQueryAdapter;
12import tools.refinery.store.query.ModelQueryBuilder;
13import tools.refinery.store.query.ModelQueryStoreAdapter;
14import tools.refinery.store.query.dnf.RelationalQuery;
15import tools.refinery.store.query.literal.Reduction;
16
17public class CountObjective implements Objective {
18 private final RelationalQuery query;
19 private final double weight;
20
21 public CountObjective(RelationalQuery query) {
22 this(query, 1);
23 }
24
25 public CountObjective(RelationalQuery query, double weight) {
26 this.query = query;
27 this.weight = weight;
28 }
29
30 @Override
31 public boolean isAlwaysZero(ModelStore store) {
32 var queryStore = store.getAdapter(ModelQueryStoreAdapter.class);
33 var canonicalQuery = queryStore.getCanonicalQuery(query);
34 return canonicalQuery.getDnf().getReduction() == Reduction.ALWAYS_FALSE;
35 }
36
37 @Override
38 public ObjectiveCalculator createCalculator(Model model) {
39 var resultSet = model.getAdapter(ModelQueryAdapter.class).getResultSet(query);
40 return () -> resultSet.size() * weight;
41 }
42
43 @Override
44 public void configure(ModelStoreBuilder storeBuilder) {
45 storeBuilder.getAdapter(ModelQueryBuilder.class).query(query);
46 }
47}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/Criteria.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/Criteria.java
new file mode 100644
index 00000000..0e4ec5c9
--- /dev/null
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/Criteria.java
@@ -0,0 +1,47 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse.transition.objectives;
7
8import tools.refinery.store.query.dnf.AnyQuery;
9
10import java.util.Collection;
11import java.util.List;
12
13public final class Criteria {
14 private Criteria() {
15 throw new IllegalStateException("This is a static utility class and should not be instantiated directly");
16 }
17
18 public static QueryCriterion whenHasMatch(AnyQuery query) {
19 return new QueryCriterion(query, true);
20 }
21
22 public static QueryCriterion whenNoMatch(AnyQuery query) {
23 return new QueryCriterion(query, false);
24 }
25
26 public static Criterion and(Criterion... criteria) {
27 return and(List.of(criteria));
28 }
29
30 public static Criterion and(Collection<? extends Criterion> criteria) {
31 if (criteria.size() == 1) {
32 return criteria.iterator().next();
33 }
34 return new AndCriterion(criteria);
35 }
36
37 public static Criterion or(Criterion... criteria) {
38 return or(List.of(criteria));
39 }
40
41 public static Criterion or(Collection<? extends Criterion> criteria) {
42 if (criteria.size() == 1) {
43 return criteria.iterator().next();
44 }
45 return new OrCriterion(criteria);
46 }
47}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/Criterion.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/Criterion.java
index 66ca6f5e..c827f20e 100644
--- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/Criterion.java
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/Criterion.java
@@ -6,10 +6,17 @@
6package tools.refinery.store.dse.transition.objectives; 6package tools.refinery.store.dse.transition.objectives;
7 7
8import tools.refinery.store.model.Model; 8import tools.refinery.store.model.Model;
9import tools.refinery.store.model.ModelStore;
9import tools.refinery.store.model.ModelStoreBuilder; 10import tools.refinery.store.model.ModelStoreBuilder;
11import tools.refinery.store.query.literal.Reduction;
10 12
11public interface Criterion { 13public interface Criterion {
12 default void doConfigure(ModelStoreBuilder storeBuilder) { 14 default void configure(ModelStoreBuilder storeBuilder) {
13 } 15 }
16
17 default Reduction getReduction(ModelStore store) {
18 return Reduction.NOT_REDUCIBLE;
19 }
20
14 CriterionCalculator createCalculator(Model model); 21 CriterionCalculator createCalculator(Model model);
15} 22}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/Objective.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/Objective.java
index b5924455..49c34d87 100644
--- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/Objective.java
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/Objective.java
@@ -6,10 +6,18 @@
6package tools.refinery.store.dse.transition.objectives; 6package tools.refinery.store.dse.transition.objectives;
7 7
8import tools.refinery.store.model.Model; 8import tools.refinery.store.model.Model;
9import tools.refinery.store.model.ModelStore;
9import tools.refinery.store.model.ModelStoreBuilder; 10import tools.refinery.store.model.ModelStoreBuilder;
10 11
11public interface Objective { 12public interface Objective {
12 default void doConfigure(ModelStoreBuilder storeBuilder) { 13 default void configure(ModelStoreBuilder storeBuilder) {
13 } 14 }
15
16 // The name {@code isAlwaysZero} is more straightforward than something like {@code canBeNonZero}.
17 @SuppressWarnings("BooleanMethodIsAlwaysInverted")
18 default boolean isAlwaysZero(ModelStore store) {
19 return false;
20 }
21
14 ObjectiveCalculator createCalculator(Model model); 22 ObjectiveCalculator createCalculator(Model model);
15} 23}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/Objectives.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/Objectives.java
new file mode 100644
index 00000000..e552d14c
--- /dev/null
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/Objectives.java
@@ -0,0 +1,41 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse.transition.objectives;
7
8import tools.refinery.store.query.dnf.FunctionalQuery;
9import tools.refinery.store.query.dnf.RelationalQuery;
10
11import java.util.Collection;
12import java.util.List;
13
14public final class Objectives {
15 private Objectives() {
16 throw new IllegalStateException("This is a static utility class and should not be instantiated directly");
17 }
18
19 public static CountObjective count(RelationalQuery query, double weight) {
20 return new CountObjective(query, weight);
21 }
22
23 public static CountObjective count(RelationalQuery query) {
24 return new CountObjective(query);
25 }
26
27 public static QueryObjective value(FunctionalQuery<? extends Number> query) {
28 return new QueryObjective(query);
29 }
30
31 public static Objective sum(Objective... objectives) {
32 return sum(List.of(objectives));
33 }
34
35 public static Objective sum(Collection<? extends Objective> objectives) {
36 if (objectives.size() == 1) {
37 return objectives.iterator().next();
38 }
39 return new CompositeObjective(objectives);
40 }
41}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/OrCriterion.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/OrCriterion.java
new file mode 100644
index 00000000..7a8d7778
--- /dev/null
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/OrCriterion.java
@@ -0,0 +1,53 @@
1/*
2 * SPDX-FileCopyrightText: 2023 The Refinery Authors <https://refinery.tools/>
3 *
4 * SPDX-License-Identifier: EPL-2.0
5 */
6package tools.refinery.store.dse.transition.objectives;
7
8import tools.refinery.store.model.Model;
9import tools.refinery.store.model.ModelStore;
10import tools.refinery.store.query.literal.Reduction;
11
12import java.util.ArrayList;
13import java.util.Collection;
14
15public final class OrCriterion extends CompositeCriterion {
16 OrCriterion(Collection<? extends Criterion> criteria) {
17 super(criteria);
18 }
19
20 @Override
21 public Reduction getReduction(ModelStore store) {
22 for (var criterion : getCriteria()) {
23 var reduction = criterion.getReduction(store);
24 if (reduction == Reduction.ALWAYS_TRUE) {
25 return Reduction.ALWAYS_TRUE;
26 } else if (reduction == Reduction.NOT_REDUCIBLE) {
27 return Reduction.NOT_REDUCIBLE;
28 }
29 }
30 return Reduction.ALWAYS_FALSE;
31 }
32
33 @Override
34 public CriterionCalculator createCalculator(Model model) {
35 var calculators = new ArrayList<CriterionCalculator>();
36 for (var criterion : getCriteria()) {
37 var reduction = criterion.getReduction(model.getStore());
38 if (reduction == Reduction.ALWAYS_TRUE) {
39 return () -> true;
40 } else if (reduction == Reduction.NOT_REDUCIBLE) {
41 calculators.add(criterion.createCalculator(model));
42 }
43 }
44 return () -> {
45 for (var calculator : calculators) {
46 if (calculator.isSatisfied()) {
47 return true;
48 }
49 }
50 return false;
51 };
52 }
53}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/QueryCriteria.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/QueryCriterion.java
index e6dddd53..e15e4e41 100644
--- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/QueryCriteria.java
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/QueryCriterion.java
@@ -6,39 +6,54 @@
6package tools.refinery.store.dse.transition.objectives; 6package tools.refinery.store.dse.transition.objectives;
7 7
8import tools.refinery.store.model.Model; 8import tools.refinery.store.model.Model;
9import tools.refinery.store.model.ModelStore;
9import tools.refinery.store.model.ModelStoreBuilder; 10import tools.refinery.store.model.ModelStoreBuilder;
10import tools.refinery.store.query.ModelQueryAdapter; 11import tools.refinery.store.query.ModelQueryAdapter;
11import tools.refinery.store.query.ModelQueryBuilder; 12import tools.refinery.store.query.ModelQueryBuilder;
13import tools.refinery.store.query.ModelQueryStoreAdapter;
12import tools.refinery.store.query.dnf.AnyQuery; 14import tools.refinery.store.query.dnf.AnyQuery;
15import tools.refinery.store.query.literal.Reduction;
13 16
14public class QueryCriteria implements Criterion { 17public class QueryCriterion implements Criterion {
15 protected final boolean satisfiedIfHasMatch; 18 protected final boolean satisfiedIfHasMatch;
16 protected final AnyQuery query; 19 protected final AnyQuery query;
17 20
18 /** 21 /**
19 * Criteria based on the existence of matches evaluated on the model. 22 * Criteria based on the existence of matches evaluated on the model.
20 * @param query The query evaluated on the model. 23 *
24 * @param query The query evaluated on the model.
21 * @param satisfiedIfHasMatch If true, the criteria satisfied if the query has any match on the model. Otherwise, 25 * @param satisfiedIfHasMatch If true, the criteria satisfied if the query has any match on the model. Otherwise,
22 * the criteria satisfied if the query has no match on the model. 26 * the criteria satisfied if the query has no match on the model.
23 */ 27 */
24 public QueryCriteria(AnyQuery query, boolean satisfiedIfHasMatch) { 28 public QueryCriterion(AnyQuery query, boolean satisfiedIfHasMatch) {
25 this.query = query; 29 this.query = query;
26 this.satisfiedIfHasMatch = satisfiedIfHasMatch; 30 this.satisfiedIfHasMatch = satisfiedIfHasMatch;
27 } 31 }
28 32
29 @Override 33 @Override
34 public Reduction getReduction(ModelStore store) {
35 var queryStore = store.getAdapter(ModelQueryStoreAdapter.class);
36 var canonicalQuery = queryStore.getCanonicalQuery(query);
37 var reduction = canonicalQuery.getDnf().getReduction();
38 if (satisfiedIfHasMatch) {
39 return reduction;
40 }
41 return reduction.negate();
42 }
43
44 @Override
30 public CriterionCalculator createCalculator(Model model) { 45 public CriterionCalculator createCalculator(Model model) {
31 var resultSet = model.getAdapter(ModelQueryAdapter.class).getResultSet(query); 46 var resultSet = model.getAdapter(ModelQueryAdapter.class).getResultSet(query);
32 if(satisfiedIfHasMatch) { 47 if (satisfiedIfHasMatch) {
33 return () -> resultSet.size() > 0; 48 return () -> resultSet.size() > 0;
34 } else { 49 } else {
35 return () -> resultSet.size() == 0; 50 return () -> resultSet.size() == 0;
36 } 51 }
37 } 52 }
38 53
39 @Override 54 @Override
40 public void doConfigure(ModelStoreBuilder storeBuilder) { 55 public void configure(ModelStoreBuilder storeBuilder) {
41 Criterion.super.doConfigure(storeBuilder); 56 Criterion.super.configure(storeBuilder);
42 storeBuilder.getAdapter(ModelQueryBuilder.class).query(query); 57 storeBuilder.getAdapter(ModelQueryBuilder.class).query(query);
43 } 58 }
44} 59}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/QueryObjective.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/QueryObjective.java
index dfddccfc..9f4bb536 100644
--- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/QueryObjective.java
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/objectives/QueryObjective.java
@@ -15,6 +15,10 @@ public class QueryObjective implements Objective {
15 protected final FunctionalQuery<? extends Number> objectiveFunction; 15 protected final FunctionalQuery<? extends Number> objectiveFunction;
16 16
17 public QueryObjective(FunctionalQuery<? extends Number> objectiveFunction) { 17 public QueryObjective(FunctionalQuery<? extends Number> objectiveFunction) {
18 if (objectiveFunction.arity() != 0) {
19 throw new IllegalArgumentException("Objective functions must have 0 parameters, got %d instead"
20 .formatted(objectiveFunction.arity()));
21 }
18 this.objectiveFunction = objectiveFunction; 22 this.objectiveFunction = objectiveFunction;
19 } 23 }
20 24
@@ -23,22 +27,15 @@ public class QueryObjective implements Objective {
23 var resultSet = model.getAdapter(ModelQueryAdapter.class).getResultSet(objectiveFunction); 27 var resultSet = model.getAdapter(ModelQueryAdapter.class).getResultSet(objectiveFunction);
24 return () -> { 28 return () -> {
25 var cursor = resultSet.getAll(); 29 var cursor = resultSet.getAll();
26 boolean hasElement = cursor.move(); 30 if (!cursor.move()) {
27 if(hasElement) {
28 double result = cursor.getValue().doubleValue();
29 if(cursor.move()) {
30 throw new IllegalStateException("Query providing the objective function has multiple values!");
31 }
32 return result;
33 } else {
34 throw new IllegalStateException("Query providing the objective function has no values!"); 31 throw new IllegalStateException("Query providing the objective function has no values!");
35 } 32 }
33 return cursor.getValue().doubleValue();
36 }; 34 };
37 } 35 }
38 36
39 @Override 37 @Override
40 public void doConfigure(ModelStoreBuilder storeBuilder) { 38 public void configure(ModelStoreBuilder storeBuilder) {
41 Objective.super.doConfigure(storeBuilder);
42 storeBuilder.getAdapter(ModelQueryBuilder.class).query(objectiveFunction); 39 storeBuilder.getAdapter(ModelQueryBuilder.class).query(objectiveFunction);
43 } 40 }
44} 41}
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/ActivationStoreImpl.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/ActivationStoreImpl.java
index 9186741f..4d775b5a 100644
--- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/ActivationStoreImpl.java
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/ActivationStoreImpl.java
@@ -5,19 +5,19 @@
5 */ 5 */
6package tools.refinery.store.dse.transition.statespace.internal; 6package tools.refinery.store.dse.transition.statespace.internal;
7 7
8import org.eclipse.collections.api.block.procedure.Procedure;
9import tools.refinery.store.dse.transition.VersionWithObjectiveValue; 8import tools.refinery.store.dse.transition.VersionWithObjectiveValue;
10import tools.refinery.store.dse.transition.statespace.ActivationStore; 9import tools.refinery.store.dse.transition.statespace.ActivationStore;
11 10
12import java.util.*; 11import java.util.*;
12import java.util.function.Consumer;
13 13
14public class ActivationStoreImpl implements ActivationStore { 14public class ActivationStoreImpl implements ActivationStore {
15 final int numberOfTransformations; 15 final int numberOfTransformations;
16 final Procedure<VersionWithObjectiveValue> actionWhenAllActivationVisited; 16 final Consumer<VersionWithObjectiveValue> actionWhenAllActivationVisited;
17 final Map<VersionWithObjectiveValue, List<ActivationStoreEntry>> versionToActivations; 17 final Map<VersionWithObjectiveValue, List<ActivationStoreEntry>> versionToActivations;
18 18
19 public ActivationStoreImpl(final int numberOfTransformations, 19 public ActivationStoreImpl(final int numberOfTransformations,
20 Procedure<VersionWithObjectiveValue> actionWhenAllActivationVisited) { 20 Consumer<VersionWithObjectiveValue> actionWhenAllActivationVisited) {
21 this.numberOfTransformations = numberOfTransformations; 21 this.numberOfTransformations = numberOfTransformations;
22 this.actionWhenAllActivationVisited = actionWhenAllActivationVisited; 22 this.actionWhenAllActivationVisited = actionWhenAllActivationVisited;
23 versionToActivations = new HashMap<>(); 23 versionToActivations = new HashMap<>();
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/ActivationStoreListEntry.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/ActivationStoreListEntry.java
index 3d4cbfdc..14298bee 100644
--- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/ActivationStoreListEntry.java
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/ActivationStoreListEntry.java
@@ -5,14 +5,14 @@
5 */ 5 */
6package tools.refinery.store.dse.transition.statespace.internal; 6package tools.refinery.store.dse.transition.statespace.internal;
7 7
8import org.eclipse.collections.impl.list.mutable.primitive.IntArrayList; 8import org.eclipse.collections.api.factory.primitive.IntLists;
9import org.eclipse.collections.api.list.primitive.MutableIntList;
9 10
10public class ActivationStoreListEntry extends ActivationStoreEntry { 11public class ActivationStoreListEntry extends ActivationStoreEntry {
11 IntArrayList visitedActivations; 12 private final MutableIntList visitedActivations = IntLists.mutable.empty();
12 13
13 ActivationStoreListEntry(int numberOfActivations) { 14 ActivationStoreListEntry(int numberOfActivations) {
14 super(numberOfActivations); 15 super(numberOfActivations);
15 visitedActivations = new IntArrayList();
16 } 16 }
17 17
18 @Override 18 @Override
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/CompleteEquivalenceClassStore.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/CompleteEquivalenceClassStore.java
index 925e09a3..20a026b6 100644
--- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/CompleteEquivalenceClassStore.java
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/CompleteEquivalenceClassStore.java
@@ -5,7 +5,8 @@
5 */ 5 */
6package tools.refinery.store.dse.transition.statespace.internal; 6package tools.refinery.store.dse.transition.statespace.internal;
7 7
8import org.eclipse.collections.impl.map.mutable.primitive.IntObjectHashMap; 8import org.eclipse.collections.api.factory.primitive.IntObjectMaps;
9import org.eclipse.collections.api.map.primitive.MutableIntObjectMap;
9import tools.refinery.store.dse.transition.VersionWithObjectiveValue; 10import tools.refinery.store.dse.transition.VersionWithObjectiveValue;
10import tools.refinery.store.dse.transition.statespace.EquivalenceClassStore; 11import tools.refinery.store.dse.transition.statespace.EquivalenceClassStore;
11import tools.refinery.store.statecoding.StateCoderResult; 12import tools.refinery.store.statecoding.StateCoderResult;
@@ -27,11 +28,10 @@ public abstract class CompleteEquivalenceClassStore extends AbstractEquivalenceC
27 } 28 }
28 } 29 }
29 30
30 final IntObjectHashMap<Object> modelCode2Versions; 31 private final MutableIntObjectMap<Object> modelCode2Versions = IntObjectMaps.mutable.empty();
31 32
32 protected CompleteEquivalenceClassStore(StateCoderStoreAdapter stateCoderStoreAdapter) { 33 protected CompleteEquivalenceClassStore(StateCoderStoreAdapter stateCoderStoreAdapter) {
33 super(stateCoderStoreAdapter); 34 super(stateCoderStoreAdapter);
34 this.modelCode2Versions = new IntObjectHashMap<>();
35 } 35 }
36 36
37 @Override 37 @Override
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/FastEquivalenceClassStore.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/FastEquivalenceClassStore.java
index 6eba87d4..6d028124 100644
--- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/FastEquivalenceClassStore.java
+++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/transition/statespace/internal/FastEquivalenceClassStore.java
@@ -5,7 +5,8 @@
5 */ 5 */
6package tools.refinery.store.dse.transition.statespace.internal; 6package tools.refinery.store.dse.transition.statespace.internal;
7 7
8import org.eclipse.collections.impl.set.mutable.primitive.IntHashSet; 8import org.eclipse.collections.api.factory.primitive.IntSets;
9import org.eclipse.collections.api.set.primitive.MutableIntSet;
9import tools.refinery.store.dse.transition.VersionWithObjectiveValue; 10import tools.refinery.store.dse.transition.VersionWithObjectiveValue;
10import tools.refinery.store.dse.transition.statespace.EquivalenceClassStore; 11import tools.refinery.store.dse.transition.statespace.EquivalenceClassStore;
11import tools.refinery.store.statecoding.StateCoderResult; 12import tools.refinery.store.statecoding.StateCoderResult;
@@ -13,11 +14,10 @@ import tools.refinery.store.statecoding.StateCoderStoreAdapter;
13 14
14public abstract class FastEquivalenceClassStore extends AbstractEquivalenceClassStore implements EquivalenceClassStore { 15public abstract class FastEquivalenceClassStore extends AbstractEquivalenceClassStore implements EquivalenceClassStore {
15 16
16 final IntHashSet codes; 17 private final MutableIntSet codes = IntSets.mutable.empty();
17 18
18 protected FastEquivalenceClassStore(StateCoderStoreAdapter stateCoderStoreAdapter) { 19 protected FastEquivalenceClassStore(StateCoderStoreAdapter stateCoderStoreAdapter) {
19 super(stateCoderStoreAdapter); 20 super(stateCoderStoreAdapter);
20 this.codes = new IntHashSet();
21 } 21 }
22 22
23 @Override 23 @Override