aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store-dse/src
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/store-dse/src')
-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
-rw-r--r--subprojects/store-dse/src/test/java/tools/refinery/store/dse/CRAExamplesTest.java184
-rw-r--r--subprojects/store-dse/src/test/java/tools/refinery/store/dse/DebugTest.java93
-rw-r--r--subprojects/store-dse/src/test/java/tools/refinery/store/dse/DesignSpaceExplorationTest.java596
-rw-r--r--subprojects/store-dse/src/test/java/tools/refinery/store/dse/TransformationRuleTest.java414
-rw-r--r--subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/QueryAssertions.java2
-rw-r--r--subprojects/store-dse/src/test/java/tools/refinery/store/dse/transition/TransitionTests.java40
55 files changed, 1439 insertions, 1407 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
diff --git a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/CRAExamplesTest.java b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/CRAExamplesTest.java
index 831b9ff0..685b88bd 100644
--- a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/CRAExamplesTest.java
+++ b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/CRAExamplesTest.java
@@ -7,19 +7,18 @@ package tools.refinery.store.dse;
7 7
8import org.junit.jupiter.api.Disabled; 8import org.junit.jupiter.api.Disabled;
9import org.junit.jupiter.api.Test; 9import org.junit.jupiter.api.Test;
10import tools.refinery.store.dse.modification.DanglingEdges;
10import tools.refinery.store.dse.modification.ModificationAdapter; 11import tools.refinery.store.dse.modification.ModificationAdapter;
11import tools.refinery.store.dse.strategy.BestFirstStoreManager; 12import tools.refinery.store.dse.strategy.BestFirstStoreManager;
13import tools.refinery.store.dse.tests.DummyCriterion;
12import tools.refinery.store.dse.tests.DummyRandomCriterion; 14import tools.refinery.store.dse.tests.DummyRandomCriterion;
13import tools.refinery.store.dse.tests.DummyRandomObjective; 15import tools.refinery.store.dse.tests.DummyRandomObjective;
14import tools.refinery.store.dse.transition.DesignSpaceExplorationAdapter; 16import tools.refinery.store.dse.transition.DesignSpaceExplorationAdapter;
15import tools.refinery.store.dse.tests.DummyCriterion; 17import tools.refinery.store.dse.transition.Rule;
16import tools.refinery.store.dse.tests.DummyObjective;
17import tools.refinery.store.model.ModelStore; 18import tools.refinery.store.model.ModelStore;
18import tools.refinery.store.query.ModelQueryAdapter; 19import tools.refinery.store.query.ModelQueryAdapter;
19import tools.refinery.store.query.dnf.FunctionalQuery;
20import tools.refinery.store.query.dnf.Query; 20import tools.refinery.store.query.dnf.Query;
21import tools.refinery.store.query.dnf.RelationalQuery; 21import tools.refinery.store.query.dnf.RelationalQuery;
22import tools.refinery.store.dse.transition.TransformationRule;
23import tools.refinery.store.query.term.Variable; 22import tools.refinery.store.query.term.Variable;
24import tools.refinery.store.query.viatra.ViatraModelQueryAdapter; 23import tools.refinery.store.query.viatra.ViatraModelQueryAdapter;
25import tools.refinery.store.query.view.AnySymbolView; 24import tools.refinery.store.query.view.AnySymbolView;
@@ -32,195 +31,102 @@ import tools.refinery.visualization.internal.FileFormat;
32 31
33import java.util.List; 32import java.util.List;
34 33
34import static tools.refinery.store.dse.modification.actions.ModificationActionLiterals.create;
35import static tools.refinery.store.dse.modification.actions.ModificationActionLiterals.delete;
36import static tools.refinery.store.dse.transition.actions.ActionLiterals.add;
37import static tools.refinery.store.dse.transition.actions.ActionLiterals.remove;
35import static tools.refinery.store.query.literal.Literals.not; 38import static tools.refinery.store.query.literal.Literals.not;
36 39
37class CRAExamplesTest { 40class CRAExamplesTest {
38
39 private static final Symbol<String> name = Symbol.of("Name", 1, String.class); 41 private static final Symbol<String> name = Symbol.of("Name", 1, String.class);
40
41// private static final Symbol<Boolean> classModel = Symbol.of("ClassModel", 1);
42 private static final Symbol<Boolean> classElement = Symbol.of("ClassElement", 1); 42 private static final Symbol<Boolean> classElement = Symbol.of("ClassElement", 1);
43// private static final Symbol<Boolean> feature = Symbol.of("Feature", 1);
44 private static final Symbol<Boolean> attribute = Symbol.of("Attribute", 1); 43 private static final Symbol<Boolean> attribute = Symbol.of("Attribute", 1);
45 private static final Symbol<Boolean> method = Symbol.of("Method", 1); 44 private static final Symbol<Boolean> method = Symbol.of("Method", 1);
46
47// private static final Symbol<Boolean> isEncapsulatedBy = Symbol.of("IsEncapsulatedBy", 2);
48 private static final Symbol<Boolean> encapsulates = Symbol.of("Encapsulates", 2); 45 private static final Symbol<Boolean> encapsulates = Symbol.of("Encapsulates", 2);
49 private static final Symbol<Boolean> dataDependency = Symbol.of("DataDependency", 2); 46 private static final Symbol<Boolean> dataDependency = Symbol.of("DataDependency", 2);
50 private static final Symbol<Boolean> functionalDependency = Symbol.of("FunctionalDependency", 2); 47 private static final Symbol<Boolean> functionalDependency = Symbol.of("FunctionalDependency", 2);
51 48
52 private static final Symbol<Boolean> features = Symbol.of("Features", 2);
53 private static final Symbol<Boolean> classes = Symbol.of("Classes", 2);
54
55// private static final AnySymbolView classModelView = new KeyOnlyView<>(classModel);
56 private static final AnySymbolView classElementView = new KeyOnlyView<>(classElement); 49 private static final AnySymbolView classElementView = new KeyOnlyView<>(classElement);
57// private static final AnySymbolView featureView = new KeyOnlyView<>(feature);
58 private static final AnySymbolView attributeView = new KeyOnlyView<>(attribute); 50 private static final AnySymbolView attributeView = new KeyOnlyView<>(attribute);
59 private static final AnySymbolView methodView = new KeyOnlyView<>(method); 51 private static final AnySymbolView methodView = new KeyOnlyView<>(method);
60// private static final AnySymbolView isEncapsulatedByView = new KeyOnlyView<>(isEncapsulatedBy);
61 private static final AnySymbolView encapsulatesView = new KeyOnlyView<>(encapsulates); 52 private static final AnySymbolView encapsulatesView = new KeyOnlyView<>(encapsulates);
62 private static final AnySymbolView dataDependencyView = new KeyOnlyView<>(dataDependency);
63 private static final AnySymbolView functionalDependencyView = new KeyOnlyView<>(functionalDependency);
64 private static final AnySymbolView featuresView = new KeyOnlyView<>(features);
65 private static final AnySymbolView classesView = new KeyOnlyView<>(classes);
66 53
67 /*Example Transformation rules*/ 54 private static final RelationalQuery feature = Query.of("Feature", (builder, f) -> builder
68 private static final RelationalQuery feature = Query.of("Feature",
69 (builder, f) -> builder.clause(
70 attributeView.call(f))
71 .clause( 55 .clause(
72 methodView.call(f)) 56 attributeView.call(f)
73 ); 57 )
74 58 .clause(
75 private static final RelationalQuery assignFeaturePreconditionHelper = Query.of("AssignFeaturePreconditionHelper", 59 methodView.call(f)
76 (builder, c, f) -> builder.clause(
77 classElementView.call(c),
78// classesView.call(model, c),
79 encapsulatesView.call(c, f)
80 )); 60 ));
81 61
82 private static final RelationalQuery assignFeaturePrecondition = Query.of("AssignFeaturePrecondition", 62 private static final Rule assignFeatureRule = Rule.of("AssignFeature", (builder, f, c1) -> builder
83 (builder, f, c1) -> builder.clause((c2) -> List.of( 63 .clause(
84// classModelView.call(model),
85 feature.call(f), 64 feature.call(f),
86 classElementView.call(c1), 65 classElementView.call(c1),
87// featuresView.call(model, f), 66 not(encapsulatesView.call(Variable.of(), f))
88 not(assignFeaturePreconditionHelper.call(c2, f)), 67 )
89 not(encapsulatesView.call(c1, f)) 68 .action(
90 ))); 69 add(encapsulates, f, c1)
70 ));
91 71
92 private static final RelationalQuery deleteEmptyClassPrecondition = Query.of("DeleteEmptyClassPrecondition", 72 private static final Rule deleteEmptyClassRule = Rule.of("DeleteEmptyClass", (builder, c) -> builder
93 (builder, c) -> builder.clause((f) -> List.of( 73 .clause((f) -> List.of(
94// classModelView.call(model),
95 classElementView.call(c), 74 classElementView.call(c),
96// featuresView.call(model, f),
97 not(encapsulatesView.call(c, f)) 75 not(encapsulatesView.call(c, f))
98 ))); 76 ))
99 77 .action(
100 private static final RelationalQuery createClassPreconditionHelper = Query.of("CreateClassPreconditionHelper", 78 remove(classElement, c),
101 (builder, f, c) -> builder.clause( 79 delete(c, DanglingEdges.IGNORE)
102 classElementView.call(c),
103// classesView.call(model, c),
104 encapsulatesView.call(c, f)
105 )); 80 ));
106 81
107 private static final RelationalQuery createClassPrecondition = Query.of("CreateClassPrecondition", 82 private static final Rule createClassRule = Rule.of("CreateClass", (builder, f) -> builder
108 (builder, f) -> builder.clause((c) -> List.of( 83 .clause((c) -> List.of(
109// classModelView.call(model),
110 feature.call(f), 84 feature.call(f),
111 not(createClassPreconditionHelper.call(f, c)) 85 not(encapsulatesView.call(f, c))
86 ))
87 .action((newClass) -> List.of(
88 create(newClass),
89 add(classElement, newClass),
90 add(encapsulates, newClass, f)
112 ))); 91 )));
113 92
114 private static final RelationalQuery moveFeaturePrecondition = Query.of("MoveFeature", 93 private static final Rule moveFeatureRule = Rule.of("MoveFeature", (builder, c1, c2, f) -> builder
115 (builder, c1, c2, f) -> builder.clause( 94 .clause(
116// classModelView.call(model),
117 classElementView.call(c1), 95 classElementView.call(c1),
118 classElementView.call(c2), 96 classElementView.call(c2),
119 c1.notEquivalent(c2), 97 c1.notEquivalent(c2),
120 feature.call(f), 98 feature.call(f),
121// classesView.call(model, c1),
122// classesView.call(model, c2),
123// featuresView.call(model, f),
124 encapsulatesView.call(c1, f) 99 encapsulatesView.call(c1, f)
100 )
101 .action(
102 remove(encapsulates, c1, f),
103 add(encapsulates, c2, f)
125 )); 104 ));
126 105
127 private static final TransformationRule assignFeatureRule = new TransformationRule("AssignFeature",
128 assignFeaturePrecondition,
129 (model) -> {
130// var isEncapsulatedByInterpretation = model.getInterpretation(isEncapsulatedBy);
131 var encapsulatesInterpretation = model.getInterpretation(encapsulates);
132 return ((Tuple activation) -> {
133 var feature = activation.get(0);
134 var classElement = activation.get(1);
135
136// isEncapsulatedByInterpretation.put(Tuple.of(feature, classElement), true);
137 encapsulatesInterpretation.put(Tuple.of(classElement, feature), true);
138 });
139 });
140
141 private static final TransformationRule deleteEmptyClassRule = new TransformationRule("DeleteEmptyClass",
142 deleteEmptyClassPrecondition,
143 (model) -> {
144// var classesInterpretation = model.getInterpretation(classes);
145 var classElementInterpretation = model.getInterpretation(classElement);
146 return ((Tuple activation) -> {
147 // TODO: can we move modificationAdapter outside?
148 var modificationAdapter = model.getAdapter(ModificationAdapter.class);
149// var modelElement = activation.get(0);
150 var classElement = activation.get(0);
151
152// classesInterpretation.put(Tuple.of(modelElement, classElement), false);
153 classElementInterpretation.put(Tuple.of(classElement), false);
154 modificationAdapter.deleteObject(Tuple.of(classElement));
155 });
156 });
157
158 private static final TransformationRule createClassRule = new TransformationRule("CreateClass",
159 createClassPrecondition,
160 (model) -> {
161 var classElementInterpretation = model.getInterpretation(classElement);
162// var classesInterpretation = model.getInterpretation(classes);
163 var encapsulatesInterpretation = model.getInterpretation(encapsulates);
164 return ((Tuple activation) -> {
165 // TODO: can we move modificationAdapter outside?
166 var modificationAdapter = model.getAdapter(ModificationAdapter.class);
167// var modelElement = activation.get(0);
168 var feature = activation.get(0);
169
170 var newClassElement = modificationAdapter.createObject();
171 var newClassElementId = newClassElement.get(0);
172 classElementInterpretation.put(newClassElement, true);
173// classesInterpretation.put(Tuple.of(modelElement, newClassElementId), true);
174 encapsulatesInterpretation.put(Tuple.of(newClassElementId, feature), true);
175 });
176 });
177
178 private static final TransformationRule moveFeatureRule = new TransformationRule("MoveFeature",
179 moveFeaturePrecondition,
180 (model) -> {
181 var encapsulatesInterpretation = model.getInterpretation(encapsulates);
182 return ((Tuple activation) -> {
183 var classElement1 = activation.get(0);
184 var classElement2 = activation.get(1);
185 var feature = activation.get(2);
186
187 encapsulatesInterpretation.put(Tuple.of(classElement1, feature), false);
188 encapsulatesInterpretation.put(Tuple.of(classElement2, feature), true);
189 });
190 });
191
192 @Test 106 @Test
193 @Disabled("This test is only for debugging purposes") 107 @Disabled("This test is only for debugging purposes")
194 void craTest() { 108 void craTest() {
195 var store = ModelStore.builder() 109 var store = ModelStore.builder()
196 .symbols(classElement, encapsulates, classes, features, attribute, method, dataDependency, 110 .symbols(classElement, encapsulates, attribute, method, dataDependency, functionalDependency, name)
197 functionalDependency, name) 111 .with(ViatraModelQueryAdapter.builder())
198 .with(ViatraModelQueryAdapter.builder()
199 .queries(feature, assignFeaturePreconditionHelper, assignFeaturePrecondition,
200 deleteEmptyClassPrecondition, createClassPreconditionHelper, createClassPrecondition,
201 moveFeaturePrecondition))
202 .with(ModelVisualizerAdapter.builder() 112 .with(ModelVisualizerAdapter.builder()
203 .withOutputpath("test_output") 113 .withOutputpath("test_output")
204 .withFormat(FileFormat.DOT) 114 .withFormat(FileFormat.DOT)
205 .withFormat(FileFormat.SVG) 115 .withFormat(FileFormat.SVG)
206 .saveStates() 116 .saveStates()
207 .saveDesignSpace() 117 .saveDesignSpace())
208 )
209 .with(StateCoderAdapter.builder()) 118 .with(StateCoderAdapter.builder())
210 .with(ModificationAdapter.builder()) 119 .with(ModificationAdapter.builder())
211 .with(DesignSpaceExplorationAdapter.builder() 120 .with(DesignSpaceExplorationAdapter.builder()
212 .transformations(assignFeatureRule, deleteEmptyClassRule, createClassRule, moveFeatureRule) 121 .transformations(assignFeatureRule, deleteEmptyClassRule, createClassRule, moveFeatureRule)
213 .objectives(new DummyRandomObjective()) 122 .objectives(new DummyRandomObjective())
214 .accept(new DummyRandomCriterion()) 123 .accept(new DummyRandomCriterion())
215 .exclude(new DummyCriterion(false)) 124 .exclude(new DummyCriterion(false)))
216 )
217 .build(); 125 .build();
218 126
219 var model = store.createEmptyModel(); 127 var model = store.createEmptyModel();
220// modificationAdapter.setRandom(1);
221 var queryEngine = model.getAdapter(ModelQueryAdapter.class); 128 var queryEngine = model.getAdapter(ModelQueryAdapter.class);
222 129
223// var modelInterpretation = model.getInterpretation(classModel);
224 var nameInterpretation = model.getInterpretation(name); 130 var nameInterpretation = model.getInterpretation(name);
225 var methodInterpretation = model.getInterpretation(method); 131 var methodInterpretation = model.getInterpretation(method);
226 var attributeInterpretation = model.getInterpretation(attribute); 132 var attributeInterpretation = model.getInterpretation(attribute);
@@ -229,7 +135,6 @@ class CRAExamplesTest {
229 135
230 var modificationAdapter = model.getAdapter(ModificationAdapter.class); 136 var modificationAdapter = model.getAdapter(ModificationAdapter.class);
231 137
232// var modelElement = modificationAdapter.createObject();
233 var method1 = modificationAdapter.createObject(); 138 var method1 = modificationAdapter.createObject();
234 var method1Id = method1.get(0); 139 var method1Id = method1.get(0);
235 var method2 = modificationAdapter.createObject(); 140 var method2 = modificationAdapter.createObject();
@@ -259,9 +164,6 @@ class CRAExamplesTest {
259 nameInterpretation.put(attribute4, "A4"); 164 nameInterpretation.put(attribute4, "A4");
260 nameInterpretation.put(attribute5, "A5"); 165 nameInterpretation.put(attribute5, "A5");
261 166
262
263
264// modelInterpretation.put(modelElement, true);
265 methodInterpretation.put(method1, true); 167 methodInterpretation.put(method1, true);
266 methodInterpretation.put(method2, true); 168 methodInterpretation.put(method2, true);
267 methodInterpretation.put(method3, true); 169 methodInterpretation.put(method3, true);
diff --git a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/DebugTest.java b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/DebugTest.java
index 87c3892a..baa7c8a4 100644
--- a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/DebugTest.java
+++ b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/DebugTest.java
@@ -9,110 +9,73 @@ import org.junit.jupiter.api.Disabled;
9import org.junit.jupiter.api.Test; 9import org.junit.jupiter.api.Test;
10import tools.refinery.store.dse.modification.ModificationAdapter; 10import tools.refinery.store.dse.modification.ModificationAdapter;
11import tools.refinery.store.dse.strategy.BestFirstStoreManager; 11import tools.refinery.store.dse.strategy.BestFirstStoreManager;
12import tools.refinery.store.dse.tests.DummyCriterion;
13import tools.refinery.store.dse.tests.DummyObjective;
14import tools.refinery.store.dse.tests.DummyRandomCriterion; 12import tools.refinery.store.dse.tests.DummyRandomCriterion;
15import tools.refinery.store.dse.tests.DummyRandomObjective; 13import tools.refinery.store.dse.tests.DummyRandomObjective;
16import tools.refinery.store.dse.transition.DesignSpaceExplorationAdapter; 14import tools.refinery.store.dse.transition.DesignSpaceExplorationAdapter;
17import tools.refinery.store.dse.transition.TransformationRule; 15import tools.refinery.store.dse.transition.Rule;
18import tools.refinery.store.model.ModelStore; 16import tools.refinery.store.model.ModelStore;
19import tools.refinery.store.query.ModelQueryAdapter; 17import tools.refinery.store.query.ModelQueryAdapter;
20import tools.refinery.store.query.dnf.Query;
21import tools.refinery.store.query.viatra.ViatraModelQueryAdapter; 18import tools.refinery.store.query.viatra.ViatraModelQueryAdapter;
22import tools.refinery.store.query.view.AnySymbolView; 19import tools.refinery.store.query.view.AnySymbolView;
23import tools.refinery.store.query.view.KeyOnlyView; 20import tools.refinery.store.query.view.KeyOnlyView;
24import tools.refinery.store.representation.Symbol; 21import tools.refinery.store.representation.Symbol;
25import tools.refinery.store.statecoding.StateCoderAdapter; 22import tools.refinery.store.statecoding.StateCoderAdapter;
26import tools.refinery.store.tuple.Tuple;
27import tools.refinery.visualization.ModelVisualizerAdapter; 23import tools.refinery.visualization.ModelVisualizerAdapter;
28import tools.refinery.visualization.internal.FileFormat; 24import tools.refinery.visualization.internal.FileFormat;
29 25
26import java.util.List;
27
28import static tools.refinery.store.dse.modification.actions.ModificationActionLiterals.create;
29import static tools.refinery.store.dse.transition.actions.ActionLiterals.add;
30
30class DebugTest { 31class DebugTest {
31 private static final Symbol<Boolean> classModel = Symbol.of("ClassModel", 1); 32 private static final Symbol<Boolean> classModel = Symbol.of("ClassModel", 1);
32 private static final Symbol<Boolean> classElement = Symbol.of("ClassElement", 1); 33 private static final Symbol<Boolean> classElement = Symbol.of("ClassElement", 1);
33 private static final Symbol<Boolean> feature = Symbol.of("Feature", 1); 34 private static final Symbol<Boolean> feature = Symbol.of("Feature", 1);
34
35 private static final Symbol<Boolean> isEncapsulatedBy = Symbol.of("IsEncapsulatedBy", 2);
36 private static final Symbol<Boolean> encapsulates = Symbol.of("Encapsulates", 2);
37
38 private static final Symbol<Boolean> features = Symbol.of("Features", 2); 35 private static final Symbol<Boolean> features = Symbol.of("Features", 2);
39 private static final Symbol<Boolean> classes = Symbol.of("Classes", 2); 36 private static final Symbol<Boolean> classes = Symbol.of("Classes", 2);
40 37
41 private static final AnySymbolView classModelView = new KeyOnlyView<>(classModel); 38 private static final AnySymbolView classModelView = new KeyOnlyView<>(classModel);
42 private static final AnySymbolView classElementView = new KeyOnlyView<>(classElement);
43 private static final AnySymbolView featureView = new KeyOnlyView<>(feature);
44 private static final AnySymbolView isEncapsulatedByView = new KeyOnlyView<>(isEncapsulatedBy);
45 private static final AnySymbolView encapsulatesView = new KeyOnlyView<>(encapsulates);
46 private static final AnySymbolView featuresView = new KeyOnlyView<>(features);
47 private static final AnySymbolView classesView = new KeyOnlyView<>(classes);
48
49 39
50 @Test 40 @Test
51 @Disabled("This test is only for debugging purposes") 41 @Disabled("This test is only for debugging purposes")
52 void BFSTest() { 42 void BFSTest() {
53 var createClassPrecondition = Query.of("CreateClassPrecondition", 43 var createClassRule = Rule.of("CreateClass", (builder, model) -> builder
54 (builder, model) -> builder.clause( 44 .clause(
55 classModelView.call(model) 45 classModelView.call(model)
56 )); 46 )
57 47 .action((newClassElement) -> List.of(
58 var createClassRule = new TransformationRule("CreateClass", 48 create(newClassElement),
59 createClassPrecondition, 49 add(classElement, newClassElement),
60 (model) -> { 50 add(classes, model, newClassElement)
61 var classesInterpretation = model.getInterpretation(classes); 51 )));
62 var classElementInterpretation = model.getInterpretation(classElement); 52
63 return ((Tuple activation) -> { 53 var createFeatureRule = Rule.of("CreateFeature", (builder, model) -> builder
64 var dseAdapter = model.getAdapter(ModificationAdapter.class); 54 .clause(
65 var modelElement = activation.get(0);
66
67 var newClassElement = dseAdapter.createObject();
68 var newClassElementId = newClassElement.get(0);
69
70 classesInterpretation.put(Tuple.of(modelElement, newClassElementId), true);
71 classElementInterpretation.put(Tuple.of(newClassElementId), true);
72 });
73 });
74
75 var createFeaturePrecondition = Query.of("CreateFeaturePrecondition",
76 (builder, model) -> builder.clause(
77 classModelView.call(model) 55 classModelView.call(model)
78 )); 56 )
79 57 .action((newFeature) -> List.of(
80 var createFeatureRule = new TransformationRule("CreateFeature", 58 create(newFeature),
81 createFeaturePrecondition, 59 add(feature, newFeature),
82 (model) -> { 60 add(features, model, newFeature)
83 var featuresInterpretation = model.getInterpretation(features); 61 )));
84 var featureInterpretation = model.getInterpretation(feature);
85 return ((Tuple activation) -> {
86 var dseAdapter = model.getAdapter(ModificationAdapter.class);
87 var modelElement = activation.get(0);
88
89 var newClassElement = dseAdapter.createObject();
90 var newClassElementId = newClassElement.get(0);
91
92 featuresInterpretation.put(Tuple.of(modelElement, newClassElementId), true);
93 featureInterpretation.put(Tuple.of(newClassElementId), true);
94 });
95 });
96 62
97 var store = ModelStore.builder() 63 var store = ModelStore.builder()
98 .symbols(classModel, classElement, feature, isEncapsulatedBy, encapsulates, classes, features) 64 .symbols(classModel, classElement, feature, classes, features)
99 .with(ViatraModelQueryAdapter.builder() 65 .with(ViatraModelQueryAdapter.builder())
100 .queries(createClassPrecondition, createFeaturePrecondition))
101 .with(ModelVisualizerAdapter.builder() 66 .with(ModelVisualizerAdapter.builder()
102 .withOutputpath("test_output") 67 .withOutputpath("test_output")
103 .withFormat(FileFormat.DOT) 68 .withFormat(FileFormat.DOT)
104 .withFormat(FileFormat.SVG) 69 .withFormat(FileFormat.SVG)
105 .saveStates() 70 .saveStates()
106 .saveDesignSpace() 71 .saveDesignSpace())
107 )
108 .with(StateCoderAdapter.builder()) 72 .with(StateCoderAdapter.builder())
109 .with(ModificationAdapter.builder()) 73 .with(ModificationAdapter.builder())
110 .with(DesignSpaceExplorationAdapter.builder() 74 .with(DesignSpaceExplorationAdapter.builder()
111 .transformations(createClassRule, createFeatureRule) 75 .transformations(createClassRule, createFeatureRule)
112 .objectives(new DummyRandomObjective()) 76 .objectives(new DummyRandomObjective())
113 .accept(new DummyRandomCriterion()) 77 .accept(new DummyRandomCriterion())
114 .exclude(new DummyRandomCriterion()) 78 .exclude(new DummyRandomCriterion()))
115 )
116 .build(); 79 .build();
117 80
118 var model = store.createEmptyModel(); 81 var model = store.createEmptyModel();
@@ -128,11 +91,9 @@ class DebugTest {
128 var initialVersion = model.commit(); 91 var initialVersion = model.commit();
129 queryEngine.flushChanges(); 92 queryEngine.flushChanges();
130 93
131
132 var bestFirst = new BestFirstStoreManager(store); 94 var bestFirst = new BestFirstStoreManager(store);
133 bestFirst.startExploration(initialVersion); 95 bestFirst.startExploration(initialVersion);
134 var resultStore = bestFirst.getSolutionStore(); 96 var resultStore = bestFirst.getSolutionStore();
135 System.out.println("states size: " + resultStore.getSolutions().size()); 97 System.out.println("states size: " + resultStore.getSolutions().size());
136
137 } 98 }
138} 99}
diff --git a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/DesignSpaceExplorationTest.java b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/DesignSpaceExplorationTest.java
deleted file mode 100644
index f5f13433..00000000
--- a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/DesignSpaceExplorationTest.java
+++ /dev/null
@@ -1,596 +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 tools.refinery.store.query.view.AnySymbolView;
9import tools.refinery.store.query.view.KeyOnlyView;
10import tools.refinery.store.representation.Symbol;
11
12class DesignSpaceExplorationTest {
13// private static final Symbol<Boolean> namedElement = Symbol.of("NamedElement", 1);
14// private static final Symbol<Boolean> attribute = Symbol.of("Attribute", 1);
15// private static final Symbol<Boolean> method = Symbol.of("Method", 1);
16// private static final Symbol<Boolean> dataDependency = Symbol.of("DataDependency", 2);
17// private static final Symbol<Boolean> functionalDependency = Symbol.of("FunctionalDependency", 2);
18
19 private static final Symbol<Boolean> classModel = Symbol.of("ClassModel", 1);
20 private static final Symbol<Boolean> classElement = Symbol.of("ClassElement", 1);
21 private static final Symbol<Boolean> feature = Symbol.of("Feature", 1);
22
23 private static final Symbol<Boolean> isEncapsulatedBy = Symbol.of("IsEncapsulatedBy", 2);
24 private static final Symbol<Boolean> encapsulates = Symbol.of("Encapsulates", 2);
25
26 private static final Symbol<Boolean> features = Symbol.of("Features", 2);
27 private static final Symbol<Boolean> classes = Symbol.of("Classes", 2);
28
29 private static final AnySymbolView classModelView = new KeyOnlyView<>(classModel);
30 private static final AnySymbolView classElementView = new KeyOnlyView<>(classElement);
31 private static final AnySymbolView featureView = new KeyOnlyView<>(feature);
32 private static final AnySymbolView isEncapsulatedByView = new KeyOnlyView<>(isEncapsulatedBy);
33 private static final AnySymbolView encapsulatesView = new KeyOnlyView<>(encapsulates);
34 private static final AnySymbolView featuresView = new KeyOnlyView<>(features);
35 private static final AnySymbolView classesView = new KeyOnlyView<>(classes);
36
37// @Test
38// void createObjectTest() {
39// var store = ModelStore.builder()
40// .with(ViatraModelQueryAdapter.builder())
41// .with(DesignSpaceExplorationAdapter.builder()
42// .strategy(new DepthFirstStrategy().withDepthLimit(0)))
43// .build();
44//
45// var model = store.createEmptyModel();
46// var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
47//
48// assertEquals(0, dseAdapter.getModelSize());
49//
50// var newModel = dseAdapter.createObject();
51// var newModelId = newModel.get(0);
52// var newClass1 = dseAdapter.createObject();
53// var newClass1Id = newClass1.get(0);
54// var newClass2 = dseAdapter.createObject();
55// var newClass2Id = newClass2.get(0);
56// var newField = dseAdapter.createObject();
57// var newFieldId = newField.get(0);
58//
59// assertEquals(0, newModelId);
60// assertEquals(1, newClass1Id);
61// assertEquals(2, newClass2Id);
62// assertEquals(3, newFieldId);
63// assertEquals(4, dseAdapter.getModelSize());
64// }
65
66// @Test
67// void deleteMiddleObjectTest() {
68// var store = ModelStore.builder()
69// .with(ViatraModelQueryAdapter.builder())
70// .with(DesignSpaceExplorationAdapter.builder()
71// .strategy(new DepthFirstStrategy()))
72// .build();
73//
74// var model = store.createEmptyModel();
75// var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
76//
77// assertEquals(0, dseAdapter.getModelSize());
78//
79// var newObject0 = dseAdapter.createObject();
80// var newObject0Id = newObject0.get(0);
81// var newObject1 = dseAdapter.createObject();
82// var newObject1Id = newObject1.get(0);
83// var newObject2 = dseAdapter.createObject();
84// var newObject2Id = newObject2.get(0);
85// var newObject3 = dseAdapter.createObject();
86// var newObject3Id = newObject3.get(0);
87//
88// assertEquals(0, newObject0Id);
89// assertEquals(1, newObject1Id);
90// assertEquals(2, newObject2Id);
91// assertEquals(3, newObject3Id);
92// assertEquals(4, dseAdapter.getModelSize());
93//
94// dseAdapter.deleteObject(newObject1);
95// assertEquals(4, dseAdapter.getModelSize());
96//
97// var newObject4 = dseAdapter.createObject();
98// var newObject4Id = newObject4.get(0);
99// assertEquals(4, newObject4Id);
100// assertEquals(5, dseAdapter.getModelSize());
101//
102// dseAdapter.deleteObject(newObject4);
103// assertEquals(5, dseAdapter.getModelSize());
104// }
105//
106// @Test
107// void DFSTrivialTest() {
108// var store = ModelStore.builder()
109// .symbols(classModel)
110// .with(ViatraModelQueryAdapter.builder())
111// .with(DesignSpaceExplorationAdapter.builder()
112// .strategy(new DepthFirstStrategy().withDepthLimit(0)))
113// .build();
114//
115// var model = store.createEmptyModel();
116// var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
117//
118// var states = dseAdapter.explore();
119// assertEquals(1, states.size());
120// }
121//
122// @Test
123// void DFSOneRuleTest() {
124// var createClassPrecondition = Query.of("CreateClassPrecondition",
125// (builder, model) -> builder.clause(
126// classModelView.call(model)
127// ));
128//
129// var createClassRule = new TransformationRule("CreateClass",
130// createClassPrecondition,
131// (model) -> {
132// var classesInterpretation = model.getInterpretation(classes);
133// var classElementInterpretation = model.getInterpretation(classElement);
134// return ((Tuple activation) -> {
135// var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
136// var modelElement = activation.get(0);
137//
138// var newClassElement = dseAdapter.createObject();
139// var newClassElementId = newClassElement.get(0);
140//
141// classesInterpretation.put(Tuple.of(modelElement, newClassElementId), true);
142// classElementInterpretation.put(Tuple.of(newClassElementId), true);
143// });
144// });
145//
146// var store = ModelStore.builder()
147// .symbols(classModel, classElement, classes)
148// .with(ViatraModelQueryAdapter.builder()
149// .queries(createClassPrecondition))
150// .with(DesignSpaceExplorationAdapter.builder()
151// .transformations(createClassRule)
152// .strategy(new DepthFirstStrategy().withDepthLimit(0)
153// ))
154// .build();
155//
156// var model = store.createEmptyModel();
157// var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
158// var queryEngine = model.getAdapter(ModelQueryAdapter.class);
159//
160// var modelElementInterpretation = model.getInterpretation(classModel);
161// modelElementInterpretation.put(dseAdapter.createObject(), true);
162// queryEngine.flushChanges();
163//
164// var states = dseAdapter.explore();
165// assertEquals(1, states.size());
166// }
167//
168// @Test
169// void DFSContinueTest() {
170// var createClassPrecondition = Query.of("CreateClassPrecondition",
171// (builder, model) -> builder.clause(
172// classModelView.call(model)
173// ));
174//
175// var createClassRule = new TransformationRule("CreateClass",
176// createClassPrecondition,
177// (model) -> {
178// var classesInterpretation = model.getInterpretation(classes);
179// var classElementInterpretation = model.getInterpretation(classElement);
180// return ((Tuple activation) -> {
181// var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
182// var modelElement = activation.get(0);
183//
184// var newClassElement = dseAdapter.createObject();
185// var newClassElementId = newClassElement.get(0);
186//
187// classesInterpretation.put(Tuple.of(modelElement, newClassElementId), true);
188// classElementInterpretation.put(Tuple.of(newClassElementId), true);
189// });
190// });
191//
192// var store = ModelStore.builder()
193// .symbols(classModel, classElement, classes)
194// .with(ViatraModelQueryAdapter.builder()
195// .queries(createClassPrecondition))
196// .with(DesignSpaceExplorationAdapter.builder()
197// .transformations(createClassRule)
198// .strategy(new DepthFirstStrategy().withDepthLimit(4).continueIfHardObjectivesFulfilled()
199// ))
200// .build();
201//
202// var model = store.createEmptyModel();
203// var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
204// var queryEngine = model.getAdapter(ModelQueryAdapter.class);
205//
206// var modelElementInterpretation = model.getInterpretation(classModel);
207// modelElementInterpretation.put(dseAdapter.createObject(), true);
208// queryEngine.flushChanges();
209//
210// var states = dseAdapter.explore();
211// assertEquals(5, states.size());
212// }
213//
214// @Test
215// void DFSCompletenessTest() {
216// var createClassPrecondition = Query.of("CreateClassPrecondition",
217// (builder, model) -> builder.clause(
218// classModelView.call(model)
219// ));
220//
221// var createClassRule = new TransformationRule("CreateClass",
222// createClassPrecondition,
223// (model) -> {
224// var classesInterpretation = model.getInterpretation(classes);
225// var classElementInterpretation = model.getInterpretation(classElement);
226// return ((Tuple activation) -> {
227// var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
228// var modelElement = activation.get(0);
229//
230// var newClassElement = dseAdapter.createObject();
231// var newClassElementId = newClassElement.get(0);
232//
233// classesInterpretation.put(Tuple.of(modelElement, newClassElementId), true);
234// classElementInterpretation.put(Tuple.of(newClassElementId), true);
235// });
236// });
237//
238// var createFeaturePrecondition = Query.of("CreateFeaturePrecondition",
239// (builder, model) -> builder.clause(
240// classModelView.call(model)
241// ));
242//
243// var createFeatureRule = new TransformationRule("CreateFeature",
244// createFeaturePrecondition,
245// (model) -> {
246// var featuresInterpretation = model.getInterpretation(features);
247// var featureInterpretation = model.getInterpretation(feature);
248// return ((Tuple activation) -> {
249// var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
250// var modelElement = activation.get(0);
251//
252// var newClassElement = dseAdapter.createObject();
253// var newClassElementId = newClassElement.get(0);
254//
255// featuresInterpretation.put(Tuple.of(modelElement, newClassElementId), true);
256// featureInterpretation.put(Tuple.of(newClassElementId), true);
257// });
258// });
259//
260// var store = ModelStore.builder()
261// .symbols(classModel, classElement, classes, feature, features, isEncapsulatedBy, encapsulates)
262// .with(ViatraModelQueryAdapter.builder()
263// .queries(createClassPrecondition, createFeaturePrecondition))
264// .with(DesignSpaceExplorationAdapter.builder()
265// .transformations(createClassRule, createFeatureRule)
266// .strategy(new DepthFirstStrategy().withDepthLimit(10).continueIfHardObjectivesFulfilled()
267// ))
268// .build();
269//
270// var model = store.createEmptyModel();
271// var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
272// var queryEngine = model.getAdapter(ModelQueryAdapter.class);
273//
274// var modelElementInterpretation = model.getInterpretation(classModel);
275// modelElementInterpretation.put(dseAdapter.createObject(), true);
276// queryEngine.flushChanges();
277//
278// var states = dseAdapter.explore();
279// assertEquals(2047, states.size());
280// }
281//
282// @Test
283// void DFSSolutionLimitTest() {
284// var createClassPrecondition = Query.of("CreateClassPrecondition",
285// (builder, model) -> builder.clause(
286// classModelView.call(model)
287// ));
288//
289// var createClassRule = new TransformationRule("CreateClass",
290// createClassPrecondition,
291// (model) -> {
292// var classesInterpretation = model.getInterpretation(classes);
293// var classElementInterpretation = model.getInterpretation(classElement);
294// return ((Tuple activation) -> {
295// var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
296// var modelElement = activation.get(0);
297//
298// var newClassElement = dseAdapter.createObject();
299// var newClassElementId = newClassElement.get(0);
300//
301// classesInterpretation.put(Tuple.of(modelElement, newClassElementId), true);
302// classElementInterpretation.put(Tuple.of(newClassElementId), true);
303// });
304// });
305//
306// var createFeaturePrecondition = Query.of("CreateFeaturePrecondition",
307// (builder, model) -> builder.clause(
308// classModelView.call(model)
309// ));
310//
311// var createFeatureRule = new TransformationRule("CreateFeature",
312// createFeaturePrecondition,
313// (model) -> {
314// var featuresInterpretation = model.getInterpretation(features);
315// var featureInterpretation = model.getInterpretation(feature);
316// return ((Tuple activation) -> {
317// var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
318// var modelElement = activation.get(0);
319//
320// var newClassElement = dseAdapter.createObject();
321// var newClassElementId = newClassElement.get(0);
322//
323// featuresInterpretation.put(Tuple.of(modelElement, newClassElementId), true);
324// featureInterpretation.put(Tuple.of(newClassElementId), true);
325// });
326// });
327//
328// var store = ModelStore.builder()
329// .symbols(classModel, classElement, classes, feature, features, isEncapsulatedBy, encapsulates)
330// .with(ViatraModelQueryAdapter.builder()
331// .queries(createClassPrecondition, createFeaturePrecondition))
332// .with(DesignSpaceExplorationAdapter.builder()
333// .transformations(createClassRule, createFeatureRule)
334// .strategy(new DepthFirstStrategy().withSolutionLimit(222)
335// .continueIfHardObjectivesFulfilled()
336// ))
337// .build();
338//
339// var model = store.createEmptyModel();
340// var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
341// var queryEngine = model.getAdapter(ModelQueryAdapter.class);
342//
343// var modelElementInterpretation = model.getInterpretation(classModel);
344// modelElementInterpretation.put(dseAdapter.createObject(), true);
345// queryEngine.flushChanges();
346//
347// var states = dseAdapter.explore();
348// assertEquals(222, states.size());
349// }
350//
351// @Test
352// void BeFSTrivialTest() {
353// var store = ModelStore.builder()
354// .symbols(classModel)
355// .with(ViatraModelQueryAdapter.builder())
356// .with(DesignSpaceExplorationAdapter.builder()
357// .strategy(new BestFirstStrategy().withDepthLimit(0)))
358// .build();
359//
360// var model = store.createEmptyModel();
361// var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
362//
363// var states = dseAdapter.explore();
364// assertEquals(1, states.size());
365// }
366//
367// @Test
368// void BeFSOneRuleTest() {
369// var createClassPrecondition = Query.of("CreateClassPrecondition",
370// (builder, model) -> builder.clause(
371// classModelView.call(model)
372// ));
373//
374// var createClassRule = new TransformationRule("CreateClass",
375// createClassPrecondition,
376// (model) -> {
377// var classesInterpretation = model.getInterpretation(classes);
378// var classElementInterpretation = model.getInterpretation(classElement);
379// return ((Tuple activation) -> {
380// var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
381// var modelElement = activation.get(0);
382//
383// var newClassElement = dseAdapter.createObject();
384// var newClassElementId = newClassElement.get(0);
385//
386// classesInterpretation.put(Tuple.of(modelElement, newClassElementId), true);
387// classElementInterpretation.put(Tuple.of(newClassElementId), true);
388// });
389// });
390//
391// var store = ModelStore.builder()
392// .symbols(classModel, classElement, classes)
393// .with(ViatraModelQueryAdapter.builder()
394// .queries(createClassPrecondition))
395// .with(DesignSpaceExplorationAdapter.builder()
396// .transformations(createClassRule)
397// .strategy(new BestFirstStrategy().withDepthLimit(4)
398// ))
399// .build();
400//
401// var model = store.createEmptyModel();
402// var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
403// var queryEngine = model.getAdapter(ModelQueryAdapter.class);
404//
405// var modelElementInterpretation = model.getInterpretation(classModel);
406// modelElementInterpretation.put(dseAdapter.createObject(), true);
407// queryEngine.flushChanges();
408//
409// var states = dseAdapter.explore();
410// assertEquals(1, states.size());
411// }
412//
413// @Test
414// void BeFSContinueTest() {
415// var createClassPrecondition = Query.of("CreateClassPrecondition",
416// (builder, model) -> builder.clause(
417// classModelView.call(model)
418// ));
419//
420// var createClassRule = new TransformationRule("CreateClass",
421// createClassPrecondition,
422// (model) -> {
423// var classesInterpretation = model.getInterpretation(classes);
424// var classElementInterpretation = model.getInterpretation(classElement);
425// return ((Tuple activation) -> {
426// var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
427// var modelElement = activation.get(0);
428//
429// var newClassElement = dseAdapter.createObject();
430// var newClassElementId = newClassElement.get(0);
431//
432// classesInterpretation.put(Tuple.of(modelElement, newClassElementId), true);
433// classElementInterpretation.put(Tuple.of(newClassElementId), true);
434// });
435// });
436//
437// var store = ModelStore.builder()
438// .symbols(classModel, classElement, classes)
439// .with(ViatraModelQueryAdapter.builder()
440// .queries(createClassPrecondition))
441// .with(DesignSpaceExplorationAdapter.builder()
442// .transformations(createClassRule)
443// .strategy(new BestFirstStrategy().withDepthLimit(4).continueIfHardObjectivesFulfilled()
444// ))
445// .build();
446//
447// var model = store.createEmptyModel();
448// var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
449// var queryEngine = model.getAdapter(ModelQueryAdapter.class);
450//
451// var modelElementInterpretation = model.getInterpretation(classModel);
452// modelElementInterpretation.put(dseAdapter.createObject(), true);
453// queryEngine.flushChanges();
454//
455// var states = dseAdapter.explore();
456// assertEquals(5, states.size());
457// }
458//
459// @Test
460// void BeFSCompletenessTest() {
461// var createClassPrecondition = Query.of("CreateClassPrecondition",
462// (builder, model) -> builder.clause(
463// classModelView.call(model)
464// ));
465//
466// var createClassRule = new TransformationRule("CreateClass",
467// createClassPrecondition,
468// (model) -> {
469// var classesInterpretation = model.getInterpretation(classes);
470// var classElementInterpretation = model.getInterpretation(classElement);
471// return ((Tuple activation) -> {
472// var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
473// var modelElement = activation.get(0);
474//
475// var newClassElement = dseAdapter.createObject();
476// var newClassElementId = newClassElement.get(0);
477//
478// classesInterpretation.put(Tuple.of(modelElement, newClassElementId), true);
479// classElementInterpretation.put(Tuple.of(newClassElementId), true);
480// });
481// });
482//
483// var createFeaturePrecondition = Query.of("CreateFeaturePrecondition",
484// (builder, model) -> builder.clause(
485// classModelView.call(model)
486// ));
487//
488// var createFeatureRule = new TransformationRule("CreateFeature",
489// createFeaturePrecondition,
490// (model) -> {
491// var featuresInterpretation = model.getInterpretation(features);
492// var featureInterpretation = model.getInterpretation(feature);
493// return ((Tuple activation) -> {
494// var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
495// var modelElement = activation.get(0);
496//
497// var newClassElement = dseAdapter.createObject();
498// var newClassElementId = newClassElement.get(0);
499//
500// featuresInterpretation.put(Tuple.of(modelElement, newClassElementId), true);
501// featureInterpretation.put(Tuple.of(newClassElementId), true);
502// });
503// });
504//
505// var store = ModelStore.builder()
506// .symbols(classModel, classElement, classes, feature, features, isEncapsulatedBy, encapsulates)
507// .with(ViatraModelQueryAdapter.builder()
508// .queries(createClassPrecondition, createFeaturePrecondition))
509// .with(DesignSpaceExplorationAdapter.builder()
510// .transformations(createClassRule, createFeatureRule)
511// .strategy(new BestFirstStrategy().withDepthLimit(10).continueIfHardObjectivesFulfilled()
512// ))
513// .build();
514//
515// var model = store.createEmptyModel();
516// var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
517// var queryEngine = model.getAdapter(ModelQueryAdapter.class);
518//
519// var modelElementInterpretation = model.getInterpretation(classModel);
520// modelElementInterpretation.put(dseAdapter.createObject(), true);
521// queryEngine.flushChanges();
522//
523// var states = dseAdapter.explore();
524// assertEquals(2047, states.size());
525// }
526//
527// @Test
528// void BeFSSolutionLimitTest() {
529// var createClassPrecondition = Query.of("CreateClassPrecondition",
530// (builder, model) -> builder.clause(
531// classModelView.call(model)
532// ));
533//
534// var createClassRule = new TransformationRule("CreateClass",
535// createClassPrecondition,
536// (model) -> {
537// var classesInterpretation = model.getInterpretation(classes);
538// var classElementInterpretation = model.getInterpretation(classElement);
539// return ((Tuple activation) -> {
540// var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
541// var modelElement = activation.get(0);
542//
543// var newClassElement = dseAdapter.createObject();
544// var newClassElementId = newClassElement.get(0);
545//
546// classesInterpretation.put(Tuple.of(modelElement, newClassElementId), true);
547// classElementInterpretation.put(Tuple.of(newClassElementId), true);
548// });
549// });
550//
551// var createFeaturePrecondition = Query.of("CreateFeaturePrecondition",
552// (builder, model) -> builder.clause(
553// classModelView.call(model)
554// ));
555//
556// var createFeatureRule = new TransformationRule("CreateFeature",
557// createFeaturePrecondition,
558// (model) -> {
559// var featuresInterpretation = model.getInterpretation(features);
560// var featureInterpretation = model.getInterpretation(feature);
561// return ((Tuple activation) -> {
562// var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
563// var modelElement = activation.get(0);
564//
565// var newClassElement = dseAdapter.createObject();
566// var newClassElementId = newClassElement.get(0);
567//
568// featuresInterpretation.put(Tuple.of(modelElement, newClassElementId), true);
569// featureInterpretation.put(Tuple.of(newClassElementId), true);
570// });
571// });
572//
573// var store = ModelStore.builder()
574// .symbols(classModel, classElement, classes, feature, features, isEncapsulatedBy, encapsulates)
575// .with(ViatraModelQueryAdapter.builder()
576// .queries(createClassPrecondition, createFeaturePrecondition))
577// .with(DesignSpaceExplorationAdapter.builder()
578// .transformations(createClassRule, createFeatureRule)
579// .strategy(new BestFirstStrategy().withSolutionLimit(222)
580// .continueIfHardObjectivesFulfilled()
581// ))
582// .build();
583//
584// var model = store.createEmptyModel();
585// var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
586// var queryEngine = model.getAdapter(ModelQueryAdapter.class);
587//
588// var modelElementInterpretation = model.getInterpretation(classModel);
589// modelElementInterpretation.put(dseAdapter.createObject(), true);
590// queryEngine.flushChanges();
591//
592// var states = dseAdapter.explore();
593// assertEquals(222, states.size());
594// }
595
596}
diff --git a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/TransformationRuleTest.java b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/TransformationRuleTest.java
deleted file mode 100644
index 43b04e0d..00000000
--- a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/TransformationRuleTest.java
+++ /dev/null
@@ -1,414 +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.junit.jupiter.api.Test;
9//
10//import tools.refinery.store.dse.transition.DesignSpaceExplorationAdapter;
11//import tools.refinery.store.model.ModelStore;
12//import tools.refinery.store.query.ModelQueryAdapter;
13//import tools.refinery.store.query.dnf.Query;
14//import tools.refinery.store.dse.transition.TransformationRule;
15//import tools.refinery.store.query.viatra.ViatraModelQueryAdapter;
16//import tools.refinery.store.query.view.AnySymbolView;
17//import tools.refinery.store.query.view.KeyOnlyView;
18//import tools.refinery.store.representation.Symbol;
19//import tools.refinery.store.tuple.Tuple;
20//
21//import java.util.List;
22//import java.util.Map;
23//
24//import static org.junit.jupiter.api.Assertions.assertEquals;
25//import static tools.refinery.store.query.literal.Literals.not;
26//import static tools.refinery.store.dse.tests.QueryAssertions.assertResults;
27//
28class TransformationRuleTest {
29//
30// private static final Symbol<Boolean> classModel = Symbol.of("ClassModel", 1);
31// private static final Symbol<Boolean> classElement = Symbol.of("ClassElement", 1);
32// private static final Symbol<Boolean> feature = Symbol.of("Feature", 1);
33//
34// private static final Symbol<Boolean> isEncapsulatedBy = Symbol.of("IsEncapsulatedBy", 2);
35// private static final Symbol<Boolean> encapsulates = Symbol.of("Encapsulates", 2);
36//
37// private static final Symbol<Boolean> features = Symbol.of("Features", 2);
38// private static final Symbol<Boolean> classes = Symbol.of("Classes", 2);
39//
40// private static final AnySymbolView classModelView = new KeyOnlyView<>(classModel);
41// private static final AnySymbolView classElementView = new KeyOnlyView<>(classElement);
42// private static final AnySymbolView featureView = new KeyOnlyView<>(feature);
43// private static final AnySymbolView isEncapsulatedByView = new KeyOnlyView<>(isEncapsulatedBy);
44// private static final AnySymbolView encapsulatesView = new KeyOnlyView<>(encapsulates);
45// private static final AnySymbolView featuresView = new KeyOnlyView<>(features);
46// private static final AnySymbolView classesView = new KeyOnlyView<>(classes);
47//
48// @Test
49// void activationsTest() {
50// var assignFeaturePreconditionHelper = Query.of("AssignFeaturePreconditionHelper",
51// (builder, model, c, f) -> builder.clause(
52// classElementView.call(c),
53// classesView.call(model, c),
54// encapsulatesView.call(c, f)
55// ));
56//
57// var assignFeaturePrecondition = Query.of("AssignFeaturePrecondition", (builder, c2, f)
58// -> builder.clause((model, c1) -> List.of(
59// classModelView.call(model),
60// featureView.call(f),
61// classElementView.call(c2),
62// featuresView.call(model, f),
63// classesView.call(model, c1),
64// not(assignFeaturePreconditionHelper.call(model, c2, f)),
65// not(encapsulatesView.call(c2, f))
66// )));
67//
68// var deleteEmptyClassPrecondition = Query.of("DeleteEmptyClassPrecondition",
69// (builder, model, c) -> builder.clause((f) -> List.of(
70// classModelView.call(model),
71// classElementView.call(c),
72// featuresView.call(model, f),
73// not(encapsulatesView.call(c, f))
74// )));
75//
76// TransformationRule assignFeatureRule = new TransformationRule("AssignFeature",
77// assignFeaturePrecondition,
78// (model) -> {
79// var isEncapsulatedByInterpretation = model.getInterpretation(isEncapsulatedBy);
80// return ((Tuple activation) -> {
81// var feature = activation.get(0);
82// var classElement = activation.get(1);
83//
84// isEncapsulatedByInterpretation.put(Tuple.of(feature, classElement), true);
85// });
86// });
87//
88// TransformationRule deleteEmptyClassRule = new TransformationRule("DeleteEmptyClass",
89// deleteEmptyClassPrecondition,
90// (model) -> {
91// var classesInterpretation = model.getInterpretation(classes);
92// var classElementInterpretation = model.getInterpretation(classElement);
93// return ((Tuple activation) -> {
94// var modelElement = activation.get(0);
95// var classElement = activation.get(1);
96//
97// classesInterpretation.put(Tuple.of(modelElement, classElement), false);
98// classElementInterpretation.put(Tuple.of(classElement), false);
99// });
100// });
101//
102//
103// var store = ModelStore.builder()
104// .symbols(classModel, classElement, feature, isEncapsulatedBy, encapsulates, classes, features)
105// .with(ViatraModelQueryAdapter.builder()
106// .queries(assignFeaturePrecondition, assignFeaturePreconditionHelper,
107// deleteEmptyClassPrecondition))
108// .with(DesignSpaceExplorationAdapter.builder()
109// .strategy(new DepthFirstStrategy().withDepthLimit(0)))
110// .build();
111//
112// var model = store.createEmptyModel();
113// var queryEngine = model.getAdapter(ModelQueryAdapter.class);
114// assignFeatureRule.prepare(model, queryEngine);
115// deleteEmptyClassRule.prepare(model, queryEngine);
116//
117// var classModelInterpretation = model.getInterpretation(classModel);
118// var classElementInterpretation = model.getInterpretation(classElement);
119// var featureInterpretation = model.getInterpretation(feature);
120// var featuresInterpretation = model.getInterpretation(features);
121// var classesInterpretation = model.getInterpretation(classes);
122//
123// var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
124// var newModel = dseAdapter.createObject();
125// var newModelId = newModel.get(0);
126// var newClass1 = dseAdapter.createObject();
127// var newClass1Id = newClass1.get(0);
128// var newClass2 = dseAdapter.createObject();
129// var newClass2Id = newClass2.get(0);
130// var newField = dseAdapter.createObject();
131// var newFieldId = newField.get(0);
132//
133// classModelInterpretation.put(newModel, true);
134// classElementInterpretation.put(newClass1, true);
135// classElementInterpretation.put(newClass2, true);
136// featureInterpretation.put(newField, true);
137// classesInterpretation.put(Tuple.of(newModelId, newClass1Id), true);
138// classesInterpretation.put(Tuple.of(newModelId, newClass2Id), true);
139// featuresInterpretation.put(Tuple.of(newModelId, newFieldId), true);
140//
141// queryEngine.flushChanges();
142//
143// var assignFeatureRuleActivations = assignFeatureRule.getAllActivationsAsResultSet();
144// var deleteEmptyClassRuleActivations = deleteEmptyClassRule.getAllActivationsAsResultSet();
145//
146// assertResults(Map.of(
147// Tuple.of(newClass1Id, newFieldId), true,
148// Tuple.of(newClass2Id, newFieldId), true
149// ), assignFeatureRuleActivations);
150//
151// assertResults(Map.of(
152// Tuple.of(newModelId, newClass1Id), true,
153// Tuple.of(newModelId, newClass2Id), true
154// ), deleteEmptyClassRuleActivations);
155// }
156//
157// @Test
158// void randomActivationTest() {
159// var deleteEmptyClassPrecondition = Query.of("DeleteEmptyClassPrecondition",
160// (builder, model, c) -> builder.clause((f) -> List.of(
161// classModelView.call(model),
162// classElementView.call(c),
163// featuresView.call(model, f),
164// not(encapsulatesView.call(c, f))
165// )));
166//
167// TransformationRule deleteEmptyClassRule0 = new TransformationRule("DeleteEmptyClass0",
168// deleteEmptyClassPrecondition,
169// (model) -> {
170// var classesInterpretation = model.getInterpretation(classes);
171// var classElementInterpretation = model.getInterpretation(classElement);
172// return ((Tuple activation) -> {
173// var modelElement = activation.get(0);
174// var classElement = activation.get(1);
175//
176// classesInterpretation.put(Tuple.of(modelElement, classElement), false);
177// classElementInterpretation.put(Tuple.of(classElement), false);
178// });
179// },
180// 0L);
181//
182// TransformationRule deleteEmptyClassRule1 = new TransformationRule("DeleteEmptyClass1",
183// deleteEmptyClassPrecondition,
184// (model) -> {
185// var classesInterpretation = model.getInterpretation(classes);
186// var classElementInterpretation = model.getInterpretation(classElement);
187// return ((Tuple activation) -> {
188// var modelElement = activation.get(0);
189// var classElement = activation.get(1);
190//
191// classesInterpretation.put(Tuple.of(modelElement, classElement), false);
192// classElementInterpretation.put(Tuple.of(classElement), false);
193// });
194// },
195// 78634L);
196//
197// var store = ModelStore.builder()
198// .symbols(classModel, classElement, feature, isEncapsulatedBy, encapsulates, classes, features)
199// .with(ViatraModelQueryAdapter.builder()
200// .queries(deleteEmptyClassPrecondition))
201// .with(DesignSpaceExplorationAdapter.builder()
202// .strategy(new DepthFirstStrategy().withDepthLimit(0)))
203// .build();
204//
205// var model = store.createEmptyModel();
206// var queryEngine = model.getAdapter(ModelQueryAdapter.class);
207// deleteEmptyClassRule0.prepare(model, queryEngine);
208// deleteEmptyClassRule1.prepare(model, queryEngine);
209//
210// var classModelInterpretation = model.getInterpretation(classModel);
211// var classElementInterpretation = model.getInterpretation(classElement);
212// var featureInterpretation = model.getInterpretation(feature);
213// var featuresInterpretation = model.getInterpretation(features);
214// var classesInterpretation = model.getInterpretation(classes);
215//
216// var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
217// var newModel = dseAdapter.createObject();
218// var newModelId = newModel.get(0);
219// var newClass1 = dseAdapter.createObject();
220// var newClass1Id = newClass1.get(0);
221// var newClass2 = dseAdapter.createObject();
222// var newClass2Id = newClass2.get(0);
223// var newField = dseAdapter.createObject();
224// var newFieldId = newField.get(0);
225//
226// classModelInterpretation.put(newModel, true);
227// classElementInterpretation.put(newClass1, true);
228// classElementInterpretation.put(newClass2, true);
229// featureInterpretation.put(newField, true);
230// classesInterpretation.put(Tuple.of(newModelId, newClass1Id), true);
231// classesInterpretation.put(Tuple.of(newModelId, newClass2Id), true);
232// featuresInterpretation.put(Tuple.of(newModelId, newFieldId), true);
233//
234// queryEngine.flushChanges();
235//
236//
237// var activation0 = deleteEmptyClassRule0.getRandomActivation().activation();
238// var activation1 = deleteEmptyClassRule1.getRandomActivation().activation();
239//
240// assertResults(Map.of(
241// Tuple.of(newModelId, newClass1Id), true,
242// Tuple.of(newModelId, newClass2Id), true
243// ), deleteEmptyClassRule0.getAllActivationsAsResultSet());
244//
245// assertResults(Map.of(
246// Tuple.of(newModelId, newClass1Id), true,
247// Tuple.of(newModelId, newClass2Id), true
248// ), deleteEmptyClassRule1.getAllActivationsAsResultSet());
249//
250// assertEquals(Tuple.of(newModelId, newClass2Id), activation0);
251// assertEquals(Tuple.of(newModelId, newClass1Id), activation1);
252//
253// }
254//
255// @Test
256// void fireTest() {
257// var deleteEmptyClassPrecondition = Query.of("DeleteEmptyClassPrecondition",
258// (builder, model, c) -> builder.clause((f) -> List.of(
259// classModelView.call(model),
260// classElementView.call(c),
261// featuresView.call(model, f),
262// not(encapsulatesView.call(c, f))
263// )));
264//
265// TransformationRule deleteEmptyClassRule = new TransformationRule("DeleteEmptyClass",
266// deleteEmptyClassPrecondition,
267// (model) -> {
268// var classesInterpretation = model.getInterpretation(classes);
269// var classElementInterpretation = model.getInterpretation(classElement);
270// return ((Tuple activation) -> {
271// var modelElement = activation.get(0);
272// var classElement = activation.get(1);
273//
274// classesInterpretation.put(Tuple.of(modelElement, classElement), false);
275// classElementInterpretation.put(Tuple.of(classElement), false);
276// });
277// });
278//
279// var store = ModelStore.builder()
280// .symbols(classModel, classElement, feature, isEncapsulatedBy, encapsulates, classes, features)
281// .with(ViatraModelQueryAdapter.builder()
282// .queries(deleteEmptyClassPrecondition))
283// .with(DesignSpaceExplorationAdapter.builder()
284// .strategy(new DepthFirstStrategy().withDepthLimit(0)))
285// .build();
286//
287// var model = store.createEmptyModel();
288// var queryEngine = model.getAdapter(ModelQueryAdapter.class);
289// deleteEmptyClassRule.prepare(model, queryEngine);
290//
291// var classModelInterpretation = model.getInterpretation(classModel);
292// var classElementInterpretation = model.getInterpretation(classElement);
293// var featureInterpretation = model.getInterpretation(feature);
294// var featuresInterpretation = model.getInterpretation(features);
295// var classesInterpretation = model.getInterpretation(classes);
296//
297// var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
298// var newModel = dseAdapter.createObject();
299// var newModelId = newModel.get(0);
300// var newClass1 = dseAdapter.createObject();
301// var newClass1Id = newClass1.get(0);
302// var newClass2 = dseAdapter.createObject();
303// var newClass2Id = newClass2.get(0);
304// var newField = dseAdapter.createObject();
305// var newFieldId = newField.get(0);
306//
307// classModelInterpretation.put(newModel, true);
308// classElementInterpretation.put(newClass1, true);
309// classElementInterpretation.put(newClass2, true);
310// featureInterpretation.put(newField, true);
311// classesInterpretation.put(Tuple.of(newModelId, newClass1Id), true);
312// classesInterpretation.put(Tuple.of(newModelId, newClass2Id), true);
313// featuresInterpretation.put(Tuple.of(newModelId, newFieldId), true);
314//
315// queryEngine.flushChanges();
316//
317// assertResults(Map.of(
318// Tuple.of(newModelId, newClass1Id), true,
319// Tuple.of(newModelId, newClass2Id), true
320// ), deleteEmptyClassRule.getAllActivationsAsResultSet());
321//
322//
323// deleteEmptyClassRule.fireActivation(Tuple.of(0, 1));
324//
325// assertResults(Map.of(
326// Tuple.of(newModelId, newClass1Id), false,
327// Tuple.of(newModelId, newClass2Id), true
328// ), deleteEmptyClassRule.getAllActivationsAsResultSet());
329// }
330//
331// @Test
332// void randomFireTest() {
333// var deleteEmptyClassPrecondition = Query.of("DeleteEmptyClassPrecondition",
334// (builder, model, c) -> builder.clause((f) -> List.of(
335// classModelView.call(model),
336// classElementView.call(c),
337// featuresView.call(model, f),
338// not(encapsulatesView.call(c, f))
339// )));
340//
341// TransformationRule deleteEmptyClassRule = new TransformationRule("DeleteEmptyClass0",
342// deleteEmptyClassPrecondition,
343// (model) -> {
344// var classesInterpretation = model.getInterpretation(classes);
345// var classElementInterpretation = model.getInterpretation(classElement);
346// return ((Tuple activation) -> {
347// var modelElement = activation.get(0);
348// var classElement = activation.get(1);
349//
350// classesInterpretation.put(Tuple.of(modelElement, classElement), false);
351// classElementInterpretation.put(Tuple.of(classElement), false);
352// });
353// },
354// 0L);
355//
356// var store = ModelStore.builder()
357// .symbols(classModel, classElement, feature, isEncapsulatedBy, encapsulates, classes, features)
358// .with(ViatraModelQueryAdapter.builder()
359// .queries(deleteEmptyClassPrecondition))
360// .with(DesignSpaceExplorationAdapter.builder()
361// .strategy(new DepthFirstStrategy().withDepthLimit(0)))
362// .build();
363//
364// var model = store.createEmptyModel();
365// var queryEngine = model.getAdapter(ModelQueryAdapter.class);
366// deleteEmptyClassRule.prepare(model, queryEngine);
367//
368// var classModelInterpretation = model.getInterpretation(classModel);
369// var classElementInterpretation = model.getInterpretation(classElement);
370// var featureInterpretation = model.getInterpretation(feature);
371// var featuresInterpretation = model.getInterpretation(features);
372// var classesInterpretation = model.getInterpretation(classes);
373//
374// var dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class);
375// var newModel = dseAdapter.createObject();
376// var newModelId = newModel.get(0);
377// var newClass1 = dseAdapter.createObject();
378// var newClass1Id = newClass1.get(0);
379// var newClass2 = dseAdapter.createObject();
380// var newClass2Id = newClass2.get(0);
381// var newField = dseAdapter.createObject();
382// var newFieldId = newField.get(0);
383//
384// classModelInterpretation.put(newModel, true);
385// classElementInterpretation.put(newClass1, true);
386// classElementInterpretation.put(newClass2, true);
387// featureInterpretation.put(newField, true);
388// classesInterpretation.put(Tuple.of(newModelId, newClass1Id), true);
389// classesInterpretation.put(Tuple.of(newModelId, newClass2Id), true);
390// featuresInterpretation.put(Tuple.of(newModelId, newFieldId), true);
391//
392// queryEngine.flushChanges();
393//
394// assertResults(Map.of(
395// Tuple.of(newModelId, newClass1Id), true,
396// Tuple.of(newModelId, newClass2Id), true
397// ), deleteEmptyClassRule.getAllActivationsAsResultSet());
398//
399// deleteEmptyClassRule.fireRandomActivation();
400//
401// assertResults(Map.of(
402// Tuple.of(newModelId, newClass1Id), true,
403// Tuple.of(newModelId, newClass2Id), false
404// ), deleteEmptyClassRule.getAllActivationsAsResultSet());
405//
406// deleteEmptyClassRule.fireRandomActivation();
407//
408// assertResults(Map.of(
409// Tuple.of(newModelId, newClass1Id), false,
410// Tuple.of(newModelId, newClass2Id), false
411// ), deleteEmptyClassRule.getAllActivationsAsResultSet());
412//
413// }
414}
diff --git a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/QueryAssertions.java b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/QueryAssertions.java
index be514eaf..f0a20720 100644
--- a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/QueryAssertions.java
+++ b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/tests/QueryAssertions.java
@@ -30,7 +30,7 @@ public final class QueryAssertions {
30 } 30 }
31 31
32 public static <T> void assertResults(Map<Tuple, T> expected, ResultSet<T> resultSet) { 32 public static <T> void assertResults(Map<Tuple, T> expected, ResultSet<T> resultSet) {
33 var defaultValue = resultSet.getQuery().defaultValue(); 33 var defaultValue = resultSet.getCanonicalQuery().defaultValue();
34 var filteredExpected = new LinkedHashMap<Tuple, T>(); 34 var filteredExpected = new LinkedHashMap<Tuple, T>();
35 var executables = new ArrayList<Executable>(); 35 var executables = new ArrayList<Executable>();
36 for (var entry : expected.entrySet()) { 36 for (var entry : expected.entrySet()) {
diff --git a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/transition/TransitionTests.java b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/transition/TransitionTests.java
index b89360cb..42a0f89b 100644
--- a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/transition/TransitionTests.java
+++ b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/transition/TransitionTests.java
@@ -7,16 +7,14 @@ package tools.refinery.store.dse.transition;
7 7
8import org.junit.jupiter.api.Test; 8import org.junit.jupiter.api.Test;
9import tools.refinery.store.dse.modification.ModificationAdapter; 9import tools.refinery.store.dse.modification.ModificationAdapter;
10import tools.refinery.store.dse.transition.objectives.QueryCriteria; 10import tools.refinery.store.dse.transition.objectives.Criteria;
11import tools.refinery.store.dse.transition.objectives.QueryObjective; 11import tools.refinery.store.dse.transition.objectives.Objectives;
12import tools.refinery.store.model.Model; 12import tools.refinery.store.model.Model;
13import tools.refinery.store.model.ModelStore; 13import tools.refinery.store.model.ModelStore;
14import tools.refinery.store.query.ModelQueryAdapter; 14import tools.refinery.store.query.ModelQueryAdapter;
15import tools.refinery.store.query.dnf.FunctionalQuery; 15import tools.refinery.store.query.dnf.FunctionalQuery;
16import tools.refinery.store.query.dnf.Query; 16import tools.refinery.store.query.dnf.Query;
17import tools.refinery.store.query.dnf.RelationalQuery; 17import tools.refinery.store.query.dnf.RelationalQuery;
18import tools.refinery.store.query.literal.CallPolarity;
19import tools.refinery.store.query.literal.Literals;
20import tools.refinery.store.query.term.Variable; 18import tools.refinery.store.query.term.Variable;
21import tools.refinery.store.query.term.int_.IntTerms; 19import tools.refinery.store.query.term.int_.IntTerms;
22import tools.refinery.store.query.viatra.ViatraModelQueryAdapter; 20import tools.refinery.store.query.viatra.ViatraModelQueryAdapter;
@@ -29,33 +27,33 @@ import tools.refinery.store.tuple.Tuple;
29import java.util.List; 27import java.util.List;
30 28
31import static org.junit.jupiter.api.Assertions.*; 29import static org.junit.jupiter.api.Assertions.*;
30import static tools.refinery.store.query.literal.Literals.check;
31import static tools.refinery.store.query.literal.Literals.not;
32 32
33class TransitionBuildTests { 33class TransitionBuildTests {
34 Symbol<Boolean> person = new Symbol<>("Person", 1, Boolean.class, false); 34 Symbol<Boolean> person = new Symbol<>("Person", 1, Boolean.class, false);
35 Symbol<Boolean> friend = new Symbol<>("friend", 2, Boolean.class, false); 35 Symbol<Boolean> friend = new Symbol<>("friend", 2, Boolean.class, false);
36
36 AnySymbolView personView = new KeyOnlyView<>(person); 37 AnySymbolView personView = new KeyOnlyView<>(person);
37 AnySymbolView friendView = new KeyOnlyView<>(friend); 38 AnySymbolView friendView = new KeyOnlyView<>(friend);
38 39
39 /*RelationalQuery areNotFriends = Query.of("areNotFriends", 40 RelationalQuery moreThan3Friends = Query.of("moreThan3Friends", (builder, tooMuchFriends) -> builder
40 (builder, p1, p2) -> builder.clause( 41 .clause(Integer.class, (numberOfFriends) -> List.of(
41 personView.call(p1),
42 personView.call(p2),
43 not(friendView.call(p1, p2))))*/
44
45 RelationalQuery moreThan3Friends = Query.of("moreThan3Friends",
46 (builder, tooMuchFriends) -> builder.clause(Integer.class, (numberOfFriends) -> List.of(
47 numberOfFriends.assign(friendView.count(tooMuchFriends, Variable.of())), 42 numberOfFriends.assign(friendView.count(tooMuchFriends, Variable.of())),
48 Literals.assume(IntTerms.less(IntTerms.constant(3), numberOfFriends)), 43 check(IntTerms.less(IntTerms.constant(3), numberOfFriends)),
49 personView.call(tooMuchFriends) 44 personView.call(tooMuchFriends)
50 ))); 45 )));
51 46
52 RelationalQuery somebodyHasNoFriend = Query.of("somebodyHasNoFriend", 47 RelationalQuery somebodyHasNoFriend = Query.of("somebodyHasNoFriend", (builder, lonely) -> builder
53 (builder, lonely) -> builder.clause( 48 .clause(
54 personView.call(lonely), 49 personView.call(lonely),
55 friendView.call(CallPolarity.NEGATIVE, lonely, Variable.of()) 50 not(friendView.call(lonely, Variable.of()))
51 ));
52
53 FunctionalQuery<Integer> numberOfFriends = Query.of(Integer.class, (builder, output) -> builder
54 .clause(
55 output.assign(friendView.count(Variable.of(), Variable.of()))
56 )); 56 ));
57 FunctionalQuery<Integer> numberOfFriends = FunctionalQuery.of(Integer.class,
58 (builder, output) -> builder.clause(output.assign(friendView.count(Variable.of(), Variable.of()))));
59 57
60 @Test 58 @Test
61 void acceptTest() { 59 void acceptTest() {
@@ -141,9 +139,9 @@ class TransitionBuildTests {
141 .with(StateCoderAdapter.builder()) 139 .with(StateCoderAdapter.builder())
142 .with(ModificationAdapter.builder()) 140 .with(ModificationAdapter.builder())
143 .with(DesignSpaceExplorationAdapter.builder() 141 .with(DesignSpaceExplorationAdapter.builder()
144 .objective(new QueryObjective(numberOfFriends)) 142 .objective(Objectives.value(numberOfFriends))
145 .exclude(new QueryCriteria(moreThan3Friends, true)) 143 .exclude(Criteria.whenHasMatch(moreThan3Friends))
146 .accept(new QueryCriteria(somebodyHasNoFriend, false))) 144 .accept(Criteria.whenNoMatch(somebodyHasNoFriend)))
147 .build(); 145 .build();
148 146
149 return store.createEmptyModel(); 147 return store.createEmptyModel();