diff options
13 files changed, 1037 insertions, 0 deletions
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/DesignSpaceExplorationAdapter.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/DesignSpaceExplorationAdapter.java index 5aed5298..ab87ddd5 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/DesignSpaceExplorationAdapter.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/DesignSpaceExplorationAdapter.java | |||
@@ -6,6 +6,7 @@ | |||
6 | package tools.refinery.store.dse; | 6 | package tools.refinery.store.dse; |
7 | 7 | ||
8 | import tools.refinery.store.adapter.ModelAdapter; | 8 | import tools.refinery.store.adapter.ModelAdapter; |
9 | import tools.refinery.store.dse.internal.TransformationRule; | ||
9 | import tools.refinery.store.map.Version; | 10 | import tools.refinery.store.map.Version; |
10 | import tools.refinery.store.dse.internal.Activation; | 11 | import tools.refinery.store.dse.internal.Activation; |
11 | import tools.refinery.store.dse.internal.DesignSpaceExplorationBuilderImpl; | 12 | import tools.refinery.store.dse.internal.DesignSpaceExplorationBuilderImpl; |
@@ -65,4 +66,6 @@ public interface DesignSpaceExplorationAdapter extends ModelAdapter { | |||
65 | public void setRandom(long seed); | 66 | public void setRandom(long seed); |
66 | 67 | ||
67 | public List<Version> getSolutions(); | 68 | public List<Version> getSolutions(); |
69 | |||
70 | void addTransformationRule(TransformationRule transformationRule); | ||
68 | } | 71 | } |
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationAdapterImpl.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationAdapterImpl.java index 220f0b2d..1ae09916 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationAdapterImpl.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/DesignSpaceExplorationAdapterImpl.java | |||
@@ -13,6 +13,7 @@ import tools.refinery.store.map.Version; | |||
13 | import tools.refinery.store.model.Interpretation; | 13 | import tools.refinery.store.model.Interpretation; |
14 | import tools.refinery.store.model.Model; | 14 | import tools.refinery.store.model.Model; |
15 | import tools.refinery.store.query.ModelQueryAdapter; | 15 | import tools.refinery.store.query.ModelQueryAdapter; |
16 | import tools.refinery.store.query.dnf.Query; | ||
16 | import tools.refinery.store.query.dnf.RelationalQuery; | 17 | import tools.refinery.store.query.dnf.RelationalQuery; |
17 | import tools.refinery.store.dse.DesignSpaceExplorationAdapter; | 18 | import tools.refinery.store.dse.DesignSpaceExplorationAdapter; |
18 | import tools.refinery.store.dse.DesignSpaceExplorationStoreAdapter; | 19 | import tools.refinery.store.dse.DesignSpaceExplorationStoreAdapter; |
@@ -45,6 +46,7 @@ public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExploration | |||
45 | private Map<Version, Version> parents = new HashMap<>(); | 46 | private Map<Version, Version> parents = new HashMap<>(); |
46 | private final List<Version> solutions = new ArrayList<>(); | 47 | private final List<Version> solutions = new ArrayList<>(); |
47 | private Map<Version, List<Activation>> statesAndTraversedActivations; | 48 | private Map<Version, List<Activation>> statesAndTraversedActivations; |
49 | @SuppressWarnings("squid:S2245") | ||
48 | private Random random = new Random(); | 50 | private Random random = new Random(); |
49 | private boolean isNewState = false; | 51 | private boolean isNewState = false; |
50 | private final boolean isVisualizationEnabled; | 52 | private final boolean isVisualizationEnabled; |
@@ -77,6 +79,12 @@ public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExploration | |||
77 | 79 | ||
78 | } | 80 | } |
79 | 81 | ||
82 | @Override | ||
83 | public void addTransformationRule(TransformationRule rule) { | ||
84 | transformationRules.add(rule); | ||
85 | rule.prepare(model, queryEngine); | ||
86 | } | ||
87 | |||
80 | public List<Version> getTrajectory() { | 88 | public List<Version> getTrajectory() { |
81 | return new ArrayList<>(trajectory); | 89 | return new ArrayList<>(trajectory); |
82 | } | 90 | } |
@@ -175,6 +183,7 @@ public class DesignSpaceExplorationAdapterImpl implements DesignSpaceExploration | |||
175 | } | 183 | } |
176 | 184 | ||
177 | @Override | 185 | @Override |
186 | @SuppressWarnings("squid:S2245") | ||
178 | public void setRandom(long seed) { | 187 | public void setRandom(long seed) { |
179 | this.random = new Random(seed); | 188 | this.random = new Random(seed); |
180 | } | 189 | } |
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/TransformationRule.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/TransformationRule.java index 8123c0d6..37117164 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/TransformationRule.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/TransformationRule.java | |||
@@ -26,10 +26,12 @@ public class TransformationRule { | |||
26 | private Random random; | 26 | private Random random; |
27 | private ModelQueryAdapter queryEngine; | 27 | private ModelQueryAdapter queryEngine; |
28 | 28 | ||
29 | @SuppressWarnings("squid:S2245") | ||
29 | public TransformationRule(String name, RelationalQuery precondition, ActionFactory actionFactory) { | 30 | public TransformationRule(String name, RelationalQuery precondition, ActionFactory actionFactory) { |
30 | this(name, precondition, actionFactory, new Random()); | 31 | this(name, precondition, actionFactory, new Random()); |
31 | } | 32 | } |
32 | 33 | ||
34 | @SuppressWarnings("squid:S2245") | ||
33 | public TransformationRule(String name, RelationalQuery precondition, ActionFactory actionFactory, long seed) { | 35 | public TransformationRule(String name, RelationalQuery precondition, ActionFactory actionFactory, long seed) { |
34 | this(name, precondition, actionFactory, new Random(seed)); | 36 | this(name, precondition, actionFactory, new Random(seed)); |
35 | } | 37 | } |
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/ActionVariable.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/ActionVariable.java new file mode 100644 index 00000000..92de565d --- /dev/null +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/ActionVariable.java | |||
@@ -0,0 +1,12 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.dse.internal.action; | ||
7 | |||
8 | import tools.refinery.store.tuple.Tuple; | ||
9 | |||
10 | public interface ActionVariable extends AtomicAction { | ||
11 | Tuple getValue(); | ||
12 | } | ||
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/ActivationVariable.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/ActivationVariable.java new file mode 100644 index 00000000..6b4c6340 --- /dev/null +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/ActivationVariable.java | |||
@@ -0,0 +1,54 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.dse.internal.action; | ||
7 | |||
8 | import tools.refinery.store.model.Model; | ||
9 | import tools.refinery.store.tuple.Tuple; | ||
10 | |||
11 | public class ActivationVariable implements ActionVariable { | ||
12 | |||
13 | private final int index; | ||
14 | private Tuple value; | ||
15 | |||
16 | public ActivationVariable() { | ||
17 | this(0); | ||
18 | } | ||
19 | |||
20 | public ActivationVariable(int index) { | ||
21 | this.index = index; | ||
22 | } | ||
23 | |||
24 | @Override | ||
25 | public void fire(Tuple activation) { | ||
26 | value = Tuple.of(activation.get(index)); | ||
27 | } | ||
28 | |||
29 | @Override | ||
30 | public ActivationVariable prepare(Model model) { | ||
31 | return this; | ||
32 | } | ||
33 | |||
34 | @Override | ||
35 | public Tuple getValue() { | ||
36 | return value; | ||
37 | } | ||
38 | |||
39 | @Override | ||
40 | public boolean equalsWithSubstitution(AtomicAction other) { | ||
41 | if (other == null || getClass() != other.getClass()) { | ||
42 | return false; | ||
43 | } | ||
44 | var otherAction = (ActivationVariable) other; | ||
45 | |||
46 | if (index != otherAction.index) { | ||
47 | return false; | ||
48 | } | ||
49 | if (value == null) { | ||
50 | return otherAction.value == null; | ||
51 | } | ||
52 | return value.equals(otherAction.value); | ||
53 | } | ||
54 | } | ||
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/AtomicAction.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/AtomicAction.java new file mode 100644 index 00000000..a8f10bca --- /dev/null +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/AtomicAction.java | |||
@@ -0,0 +1,18 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.dse.internal.action; | ||
7 | |||
8 | import tools.refinery.store.model.Model; | ||
9 | import tools.refinery.store.tuple.Tuple; | ||
10 | |||
11 | public interface AtomicAction { | ||
12 | |||
13 | void fire(Tuple activation); | ||
14 | |||
15 | AtomicAction prepare(Model model); | ||
16 | |||
17 | boolean equalsWithSubstitution(AtomicAction other); | ||
18 | } | ||
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/DeleteAction.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/DeleteAction.java new file mode 100644 index 00000000..9900390f --- /dev/null +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/DeleteAction.java | |||
@@ -0,0 +1,40 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.dse.internal.action; | ||
7 | |||
8 | import tools.refinery.store.dse.DesignSpaceExplorationAdapter; | ||
9 | import tools.refinery.store.model.Model; | ||
10 | import tools.refinery.store.tuple.Tuple; | ||
11 | |||
12 | public class DeleteAction implements AtomicAction { | ||
13 | |||
14 | private final ActionVariable variable; | ||
15 | private DesignSpaceExplorationAdapter dseAdapter; | ||
16 | |||
17 | public DeleteAction(ActionVariable variable) { | ||
18 | this.variable = variable; | ||
19 | } | ||
20 | |||
21 | @Override | ||
22 | public void fire(Tuple activation) { | ||
23 | dseAdapter.deleteObject(variable.getValue()); | ||
24 | } | ||
25 | |||
26 | @Override | ||
27 | public DeleteAction prepare(Model model) { | ||
28 | dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class); | ||
29 | return this; | ||
30 | } | ||
31 | |||
32 | @Override | ||
33 | public boolean equalsWithSubstitution(AtomicAction other) { | ||
34 | if (other == null || getClass() != other.getClass()) { | ||
35 | return false; | ||
36 | } | ||
37 | var otherAction = (DeleteAction) other; | ||
38 | return this.variable.getClass() == otherAction.variable.getClass(); | ||
39 | } | ||
40 | } | ||
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/InsertAction.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/InsertAction.java new file mode 100644 index 00000000..90fcc5ac --- /dev/null +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/InsertAction.java | |||
@@ -0,0 +1,94 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.dse.internal.action; | ||
7 | |||
8 | import tools.refinery.store.model.Interpretation; | ||
9 | import tools.refinery.store.model.Model; | ||
10 | import tools.refinery.store.tuple.Tuple; | ||
11 | import tools.refinery.store.tuple.Tuple0; | ||
12 | |||
13 | import java.util.Arrays; | ||
14 | |||
15 | public class InsertAction<T> implements AtomicAction { | ||
16 | |||
17 | private final Interpretation<T> interpretation; | ||
18 | private final T value; | ||
19 | private final int arity; | ||
20 | private final ActionVariable[] variables; | ||
21 | |||
22 | public InsertAction(Interpretation<T> interpretation, T value, ActionVariable... variables) { | ||
23 | this.interpretation = interpretation; | ||
24 | this.value = value; | ||
25 | this.variables = variables; | ||
26 | this.arity = interpretation.getSymbol().arity(); | ||
27 | if (variables.length != arity) { | ||
28 | throw new IllegalArgumentException("Expected " + arity + " variables, but got " + variables.length); | ||
29 | } | ||
30 | } | ||
31 | |||
32 | @Override | ||
33 | public void fire(Tuple activation) { | ||
34 | Tuple tuple; | ||
35 | if (arity == 0) { | ||
36 | tuple = Tuple0.INSTANCE; | ||
37 | } | ||
38 | else if (arity == 1) { | ||
39 | tuple = variables[0].getValue(); | ||
40 | } | ||
41 | else if (arity == 2) { | ||
42 | tuple = Tuple.of(variables[0].getValue().get(0), variables[1].getValue().get(0)); | ||
43 | } | ||
44 | else if (arity == 3) { | ||
45 | tuple = Tuple.of(variables[0].getValue().get(0), variables[1].getValue().get(0), variables[2].getValue().get(0)); | ||
46 | } | ||
47 | else { | ||
48 | tuple = Tuple.of(Arrays.stream(variables).map(variable -> variable.getValue().get(0)) | ||
49 | .mapToInt(Integer::intValue).toArray()); | ||
50 | } | ||
51 | interpretation.put(tuple, value); | ||
52 | } | ||
53 | |||
54 | public void put(Tuple tuple) { | ||
55 | interpretation.put(tuple, value); | ||
56 | } | ||
57 | |||
58 | @Override | ||
59 | public InsertAction<T> prepare(Model model) { | ||
60 | return this; | ||
61 | } | ||
62 | |||
63 | public ActionVariable[] getVariables() { | ||
64 | return variables; | ||
65 | } | ||
66 | |||
67 | @Override | ||
68 | public boolean equalsWithSubstitution(AtomicAction other) { | ||
69 | if (other == null || getClass() != other.getClass()) { | ||
70 | return false; | ||
71 | } | ||
72 | var otherAction = (InsertAction<?>) other; | ||
73 | if (variables.length != otherAction.variables.length) { | ||
74 | return false; | ||
75 | } | ||
76 | if (!interpretation.equals(otherAction.interpretation)) { | ||
77 | return false; | ||
78 | } | ||
79 | if (value == null) { | ||
80 | if (otherAction.value != null) { | ||
81 | return false; | ||
82 | } | ||
83 | } | ||
84 | else if (!value.equals(otherAction.value)) { | ||
85 | return false; | ||
86 | } | ||
87 | for (var i = 0; i < variables.length; i++) { | ||
88 | if (!variables[i].equalsWithSubstitution(otherAction.variables[i])) { | ||
89 | return false; | ||
90 | } | ||
91 | } | ||
92 | return true; | ||
93 | } | ||
94 | } | ||
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/NewItemVariable.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/NewItemVariable.java new file mode 100644 index 00000000..cbb9697e --- /dev/null +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/NewItemVariable.java | |||
@@ -0,0 +1,45 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.dse.internal.action; | ||
7 | |||
8 | import tools.refinery.store.dse.DesignSpaceExplorationAdapter; | ||
9 | import tools.refinery.store.model.Model; | ||
10 | import tools.refinery.store.tuple.Tuple; | ||
11 | import tools.refinery.store.tuple.Tuple1; | ||
12 | |||
13 | public class NewItemVariable implements ActionVariable { | ||
14 | private DesignSpaceExplorationAdapter dseAdapter; | ||
15 | private Tuple1 value; | ||
16 | |||
17 | @Override | ||
18 | public void fire(Tuple activation) { | ||
19 | value = dseAdapter.createObject(); | ||
20 | } | ||
21 | |||
22 | @Override | ||
23 | public NewItemVariable prepare(Model model) { | ||
24 | dseAdapter = model.getAdapter(DesignSpaceExplorationAdapter.class); | ||
25 | return this; | ||
26 | } | ||
27 | |||
28 | @Override | ||
29 | public Tuple1 getValue() { | ||
30 | return value; | ||
31 | } | ||
32 | |||
33 | @Override | ||
34 | public boolean equalsWithSubstitution(AtomicAction other) { | ||
35 | if (other == null || getClass() != other.getClass()) { | ||
36 | return false; | ||
37 | } | ||
38 | var otherAction = (NewItemVariable) other; | ||
39 | if (value == null) { | ||
40 | return otherAction.value == null; | ||
41 | } | ||
42 | return value.equals(otherAction.value); | ||
43 | |||
44 | } | ||
45 | } | ||
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/TransformationAction.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/TransformationAction.java new file mode 100644 index 00000000..adc4df9e --- /dev/null +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/internal/action/TransformationAction.java | |||
@@ -0,0 +1,129 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.dse.internal.action; | ||
7 | |||
8 | import tools.refinery.store.model.Model; | ||
9 | import tools.refinery.store.tuple.Tuple; | ||
10 | import tools.refinery.store.tuple.Tuple2; | ||
11 | |||
12 | import java.util.*; | ||
13 | |||
14 | public class TransformationAction { | ||
15 | private final List<ActionVariable> actionVariables = new ArrayList<>(); | ||
16 | private final List<InsertAction<?>> insertActions = new ArrayList<>(); | ||
17 | private final List<DeleteAction> deleteActions = new ArrayList<>(); | ||
18 | private boolean configured = false; | ||
19 | private final Map<Integer, List<Tuple2>> actionVariableUsageMap = new LinkedHashMap<>(); | ||
20 | |||
21 | public TransformationAction add(ActionVariable action) { | ||
22 | checkConfigured(); | ||
23 | actionVariables.add(action); | ||
24 | return this; | ||
25 | } | ||
26 | |||
27 | public TransformationAction add(InsertAction<?> action) { | ||
28 | checkConfigured(); | ||
29 | insertActions.add(action); | ||
30 | return this; | ||
31 | } | ||
32 | |||
33 | public TransformationAction add(DeleteAction action) { | ||
34 | checkConfigured(); | ||
35 | deleteActions.add(action); | ||
36 | return this; | ||
37 | } | ||
38 | |||
39 | private void checkConfigured() { | ||
40 | if (configured) { | ||
41 | throw new IllegalStateException("Action already configured."); | ||
42 | } | ||
43 | } | ||
44 | |||
45 | public TransformationAction prepare(Model model) { | ||
46 | for (ActionVariable action : actionVariables) { | ||
47 | action.prepare(model); | ||
48 | } | ||
49 | for (InsertAction<?> action : insertActions) { | ||
50 | action.prepare(model); | ||
51 | } | ||
52 | for (DeleteAction action : deleteActions) { | ||
53 | action.prepare(model); | ||
54 | } | ||
55 | |||
56 | for (var insertAction : insertActions) { | ||
57 | var actionIndex = insertActions.indexOf(insertAction); | ||
58 | var variables = insertAction.getVariables(); | ||
59 | for (var i = 0; i < variables.length; i++) { | ||
60 | var variablelGlobalIndex = actionVariables.indexOf(variables[i]); | ||
61 | actionVariableUsageMap.computeIfAbsent(variablelGlobalIndex, k -> new ArrayList<>()); | ||
62 | actionVariableUsageMap.get(variablelGlobalIndex).add(Tuple.of(actionIndex, i)); | ||
63 | } | ||
64 | } | ||
65 | |||
66 | configured = true; | ||
67 | return this; | ||
68 | } | ||
69 | |||
70 | public boolean fire(Tuple activation) { | ||
71 | for (ActionVariable action : actionVariables) { | ||
72 | action.fire(activation); | ||
73 | } | ||
74 | for (InsertAction<?> action : insertActions) { | ||
75 | action.fire(activation); | ||
76 | } | ||
77 | for (DeleteAction action : deleteActions) { | ||
78 | action.fire(activation); | ||
79 | } | ||
80 | return true; | ||
81 | } | ||
82 | |||
83 | // Returns true if ActionVariables and InsertActions are inserted in same order, ActionVariables are equal (they | ||
84 | // have the same index for getting the value from the activation Tuple) and InsertActions are equal (they have | ||
85 | // the same arity and value to be set). | ||
86 | public boolean equalsWithSubstitution(TransformationAction other) { | ||
87 | if (other == this) { | ||
88 | return true; | ||
89 | } | ||
90 | |||
91 | if (actionVariables.size() != other.actionVariables.size()) { | ||
92 | return false; | ||
93 | } | ||
94 | |||
95 | if (insertActions.size() != other.insertActions.size()) { | ||
96 | return false; | ||
97 | } | ||
98 | |||
99 | if (deleteActions.size() != other.deleteActions.size()) { | ||
100 | return false; | ||
101 | } | ||
102 | |||
103 | for (var i = 0; i < actionVariables.size(); i++) { | ||
104 | var variable = actionVariables.get(i); | ||
105 | var otherVariable = other.actionVariables.get(i); | ||
106 | if (!variable.equalsWithSubstitution(otherVariable)) { | ||
107 | return false; | ||
108 | } | ||
109 | } | ||
110 | |||
111 | for (var i = 0; i < insertActions.size(); i++) { | ||
112 | var insertAction = insertActions.get(i); | ||
113 | var otherInsertAction = other.insertActions.get(i); | ||
114 | if (!insertAction.equalsWithSubstitution(otherInsertAction)) { | ||
115 | return false; | ||
116 | } | ||
117 | } | ||
118 | |||
119 | for (var i = 0; i < deleteActions.size(); i++) { | ||
120 | var deleteAction = deleteActions.get(i); | ||
121 | var otherDeleteAction = other.deleteActions.get(i); | ||
122 | if (!deleteAction.equalsWithSubstitution(otherDeleteAction)) { | ||
123 | return false; | ||
124 | } | ||
125 | } | ||
126 | return this.actionVariableUsageMap.equals(other.actionVariableUsageMap); | ||
127 | |||
128 | } | ||
129 | } | ||
diff --git a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/AlwaysSatisfiedRandomHardObjective.java b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/AlwaysSatisfiedRandomHardObjective.java index 327d5e2f..cdd1754f 100644 --- a/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/AlwaysSatisfiedRandomHardObjective.java +++ b/subprojects/store-dse/src/main/java/tools/refinery/store/dse/objectives/AlwaysSatisfiedRandomHardObjective.java | |||
@@ -22,6 +22,7 @@ import java.util.Random; | |||
22 | public class AlwaysSatisfiedRandomHardObjective extends BaseObjective { | 22 | public class AlwaysSatisfiedRandomHardObjective extends BaseObjective { |
23 | 23 | ||
24 | private static final String DEFAULT_NAME = "AlwaysSatisfiedDummyHardObjective"; | 24 | private static final String DEFAULT_NAME = "AlwaysSatisfiedDummyHardObjective"; |
25 | @SuppressWarnings("squid:S2245") | ||
25 | private static final Random random = new Random(0); | 26 | private static final Random random = new Random(0); |
26 | 27 | ||
27 | public AlwaysSatisfiedRandomHardObjective() { | 28 | public AlwaysSatisfiedRandomHardObjective() { |
diff --git a/subprojects/store-dse/src/test/java/tools/refinery/store/dse/ActionEqualsTest.java b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/ActionEqualsTest.java new file mode 100644 index 00000000..d4a05d12 --- /dev/null +++ b/subprojects/store-dse/src/test/java/tools/refinery/store/dse/ActionEqualsTest.java | |||
@@ -0,0 +1,629 @@ | |||
1 | /* | ||
2 | * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/> | ||
3 | * | ||
4 | * SPDX-License-Identifier: EPL-2.0 | ||
5 | */ | ||
6 | package tools.refinery.store.dse; | ||
7 | |||
8 | import org.junit.jupiter.api.BeforeAll; | ||
9 | import org.junit.jupiter.api.Test; | ||
10 | import tools.refinery.store.dse.internal.action.*; | ||
11 | import tools.refinery.store.dse.strategy.DepthFirstStrategy; | ||
12 | import tools.refinery.store.model.Model; | ||
13 | import tools.refinery.store.model.ModelStore; | ||
14 | import tools.refinery.store.query.dnf.Query; | ||
15 | import tools.refinery.store.query.viatra.ViatraModelQueryAdapter; | ||
16 | import tools.refinery.store.query.view.KeyOnlyView; | ||
17 | import tools.refinery.store.representation.Symbol; | ||
18 | |||
19 | import static org.junit.jupiter.api.Assertions.assertFalse; | ||
20 | import static org.junit.jupiter.api.Assertions.assertTrue; | ||
21 | |||
22 | public class ActionEqualsTest { | ||
23 | |||
24 | private static Model model; | ||
25 | private static Symbol<Boolean> type1; | ||
26 | private static Symbol<Boolean> relation1; | ||
27 | private static Symbol<Boolean> relation2; | ||
28 | |||
29 | @BeforeAll | ||
30 | public static void init() { | ||
31 | type1 = Symbol.of("type1", 1); | ||
32 | relation1 = Symbol.of("relation1", 2); | ||
33 | relation2 = Symbol.of("relation2", 2); | ||
34 | var type1View = new KeyOnlyView<>(type1); | ||
35 | var precondition1 = Query.of("CreateClassPrecondition", | ||
36 | (builder, model) -> builder.clause( | ||
37 | type1View.call(model) | ||
38 | )); | ||
39 | |||
40 | var precondition2 = Query.of("CreateFeaturePrecondition", | ||
41 | (builder, model) -> builder.clause( | ||
42 | type1View.call(model) | ||
43 | )); | ||
44 | var store = ModelStore.builder() | ||
45 | .symbols(type1, relation2, relation1) | ||
46 | .with(ViatraModelQueryAdapter.builder() | ||
47 | .queries(precondition1, precondition2)) | ||
48 | .with(DesignSpaceExplorationAdapter.builder() | ||
49 | .strategy(new DepthFirstStrategy())) | ||
50 | .build(); | ||
51 | |||
52 | |||
53 | model = store.createEmptyModel(); | ||
54 | } | ||
55 | |||
56 | @Test | ||
57 | void emptyActionEqualsTest() { | ||
58 | var action1 = new TransformationAction(); | ||
59 | var action2 = new TransformationAction(); | ||
60 | |||
61 | assertTrue(action1.equalsWithSubstitution(action1)); | ||
62 | assertTrue(action2.equalsWithSubstitution(action2)); | ||
63 | assertTrue(action1.equalsWithSubstitution(action2)); | ||
64 | } | ||
65 | |||
66 | @Test | ||
67 | void actionTrivialTest() { | ||
68 | var newItemSymbol1 = new NewItemVariable(); | ||
69 | var activationSymbol = new ActivationVariable(); | ||
70 | var insertAction1 = new InsertAction<>(model.getInterpretation(type1), true, newItemSymbol1); | ||
71 | var insertAction2 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1, | ||
72 | activationSymbol); | ||
73 | var insertAction3 = new InsertAction<>(model.getInterpretation(type1), true, newItemSymbol1); | ||
74 | var insertAction4 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1, | ||
75 | activationSymbol); | ||
76 | |||
77 | var action1 = new TransformationAction(); | ||
78 | action1.add(newItemSymbol1); | ||
79 | action1.add(activationSymbol); | ||
80 | action1.add(insertAction1); | ||
81 | action1.add(insertAction2); | ||
82 | action1.prepare(model); | ||
83 | |||
84 | var action2 = new TransformationAction(); | ||
85 | action2.add(newItemSymbol1); | ||
86 | action2.add(activationSymbol); | ||
87 | action2.add(insertAction3); | ||
88 | action2.add(insertAction4); | ||
89 | action2.prepare(model); | ||
90 | |||
91 | assertTrue(action1.equalsWithSubstitution(action2)); | ||
92 | } | ||
93 | |||
94 | @Test | ||
95 | void actionIdenticalTest() { | ||
96 | var newItemSymbol1 = new NewItemVariable(); | ||
97 | var activationSymbol1 = new ActivationVariable(); | ||
98 | var insertAction1 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1, | ||
99 | activationSymbol1); | ||
100 | |||
101 | var action1 = new TransformationAction(); | ||
102 | action1.add(newItemSymbol1); | ||
103 | action1.add(activationSymbol1); | ||
104 | action1.add(insertAction1); | ||
105 | action1.prepare(model); | ||
106 | |||
107 | var newItemSymbol2 = new NewItemVariable(); | ||
108 | var activationSymbol2 = new ActivationVariable(); | ||
109 | var insertAction2 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol2, | ||
110 | activationSymbol2); | ||
111 | |||
112 | var action2 = new TransformationAction(); | ||
113 | action2.add(newItemSymbol2); | ||
114 | action2.add(activationSymbol2); | ||
115 | action2.add(insertAction2); | ||
116 | action2.prepare(model); | ||
117 | |||
118 | assertTrue(action1.equalsWithSubstitution(action2)); | ||
119 | } | ||
120 | |||
121 | @Test | ||
122 | void actionSymbolGlobalOrderTest() { | ||
123 | var newItemSymbol1 = new NewItemVariable(); | ||
124 | var activationSymbol1 = new ActivationVariable(); | ||
125 | var insertAction1 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1, | ||
126 | activationSymbol1); | ||
127 | |||
128 | var action1 = new TransformationAction(); | ||
129 | action1.add(newItemSymbol1); | ||
130 | action1.add(activationSymbol1); | ||
131 | action1.add(insertAction1); | ||
132 | action1.prepare(model); | ||
133 | |||
134 | var newItemSymbol2 = new NewItemVariable(); | ||
135 | var activationSymbol2 = new ActivationVariable(); | ||
136 | var insertAction2 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol2, | ||
137 | activationSymbol2); | ||
138 | |||
139 | var action2 = new TransformationAction(); | ||
140 | action2.add(activationSymbol2); | ||
141 | action2.add(newItemSymbol2); | ||
142 | action2.add(insertAction2); | ||
143 | action2.prepare(model); | ||
144 | |||
145 | assertFalse(action1.equalsWithSubstitution(action2)); | ||
146 | } | ||
147 | |||
148 | @Test | ||
149 | void actionSymbolRepeatedInInsertActionTest() { | ||
150 | var newItemSymbol1 = new NewItemVariable(); | ||
151 | var insertAction1 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1, | ||
152 | newItemSymbol1); | ||
153 | |||
154 | var action1 = new TransformationAction(); | ||
155 | action1.add(newItemSymbol1); | ||
156 | action1.add(insertAction1); | ||
157 | action1.prepare(model); | ||
158 | |||
159 | var newItemSymbol2 = new NewItemVariable(); | ||
160 | var insertAction2 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol2, | ||
161 | newItemSymbol2); | ||
162 | |||
163 | var action2 = new TransformationAction(); | ||
164 | action2.add(newItemSymbol2); | ||
165 | action2.add(insertAction2); | ||
166 | action2.prepare(model); | ||
167 | |||
168 | assertTrue(action1.equalsWithSubstitution(action2)); | ||
169 | } | ||
170 | |||
171 | @Test | ||
172 | void identicalInsertActionInDifferentOrderTest() { | ||
173 | var newItemSymbol1 = new NewItemVariable(); | ||
174 | var activationSymbol1 = new ActivationVariable(); | ||
175 | var insertAction1 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1, | ||
176 | activationSymbol1); | ||
177 | var insertAction2 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1, | ||
178 | activationSymbol1); | ||
179 | |||
180 | var action1 = new TransformationAction(); | ||
181 | action1.add(newItemSymbol1); | ||
182 | action1.add(activationSymbol1); | ||
183 | action1.add(insertAction1); | ||
184 | action1.add(insertAction2); | ||
185 | action1.prepare(model); | ||
186 | |||
187 | var action2 = new TransformationAction(); | ||
188 | action2.add(newItemSymbol1); | ||
189 | action2.add(activationSymbol1); | ||
190 | action2.add(insertAction2); | ||
191 | action2.add(insertAction1); | ||
192 | action2.prepare(model); | ||
193 | |||
194 | assertTrue(action1.equalsWithSubstitution(action2)); | ||
195 | } | ||
196 | |||
197 | @Test | ||
198 | void identicalActionAndSymbolDifferentOrderTest() { | ||
199 | var newItemSymbol1 = new NewItemVariable(); | ||
200 | var newItemSymbol2 = new NewItemVariable(); | ||
201 | var activationSymbol1 = new ActivationVariable(); | ||
202 | var activationSymbol2 = new ActivationVariable(); | ||
203 | |||
204 | var insertAction1 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1, | ||
205 | activationSymbol1); | ||
206 | |||
207 | var insertAction2 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol2, | ||
208 | activationSymbol2); | ||
209 | |||
210 | var action1 = new TransformationAction(); | ||
211 | action1.add(newItemSymbol1); | ||
212 | action1.add(newItemSymbol2); | ||
213 | action1.add(activationSymbol1); | ||
214 | action1.add(activationSymbol2); | ||
215 | action1.add(insertAction1); | ||
216 | action1.add(insertAction2); | ||
217 | action1.prepare(model); | ||
218 | |||
219 | var action2 = new TransformationAction(); | ||
220 | action2.add(newItemSymbol2); | ||
221 | action2.add(newItemSymbol1); | ||
222 | action2.add(activationSymbol2); | ||
223 | action2.add(activationSymbol1); | ||
224 | action2.add(insertAction2); | ||
225 | action2.add(insertAction1); | ||
226 | action2.prepare(model); | ||
227 | |||
228 | assertTrue(action1.equalsWithSubstitution(action2)); | ||
229 | } | ||
230 | |||
231 | @Test | ||
232 | void identicalActionAndSymbolMixedOrderTest() { | ||
233 | var newItemSymbol1 = new NewItemVariable(); | ||
234 | var activationSymbol1 = new ActivationVariable(); | ||
235 | var insertAction1 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1, | ||
236 | activationSymbol1); | ||
237 | |||
238 | var newItemSymbol2 = new NewItemVariable(); | ||
239 | var activationSymbol2 = new ActivationVariable(); | ||
240 | var insertAction2 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol2, | ||
241 | activationSymbol2); | ||
242 | |||
243 | var action1 = new TransformationAction(); | ||
244 | action1.add(newItemSymbol1); | ||
245 | action1.add(newItemSymbol2); | ||
246 | action1.add(activationSymbol1); | ||
247 | action1.add(activationSymbol2); | ||
248 | action1.add(insertAction1); | ||
249 | action1.add(insertAction2); | ||
250 | action1.prepare(model); | ||
251 | |||
252 | var action2 = new TransformationAction(); | ||
253 | action2.add(insertAction1); | ||
254 | action2.add(newItemSymbol1); | ||
255 | action2.add(newItemSymbol2); | ||
256 | action2.add(activationSymbol1); | ||
257 | action2.add(insertAction2); | ||
258 | action2.add(activationSymbol2); | ||
259 | action2.prepare(model); | ||
260 | |||
261 | assertTrue(action1.equalsWithSubstitution(action2)); | ||
262 | } | ||
263 | |||
264 | @Test | ||
265 | void insertActionInterpretationTest() { | ||
266 | var newItemSymbol1 = new NewItemVariable(); | ||
267 | var activationSymbol1 = new ActivationVariable(); | ||
268 | var insertAction1 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1, | ||
269 | activationSymbol1); | ||
270 | var insertAction2 = new InsertAction<>(model.getInterpretation(relation2), true, newItemSymbol1, | ||
271 | activationSymbol1); | ||
272 | |||
273 | var action1 = new TransformationAction(); | ||
274 | action1.add(newItemSymbol1); | ||
275 | action1.add(activationSymbol1); | ||
276 | action1.add(insertAction1); | ||
277 | action1.prepare(model); | ||
278 | |||
279 | var action2 = new TransformationAction(); | ||
280 | action2.add(newItemSymbol1); | ||
281 | action2.add(activationSymbol1); | ||
282 | action2.add(insertAction2); | ||
283 | action2.prepare(model); | ||
284 | |||
285 | assertFalse(action1.equalsWithSubstitution(action2)); | ||
286 | } | ||
287 | |||
288 | @Test | ||
289 | void insertActionValueTest() { | ||
290 | var newItemSymbol1 = new NewItemVariable(); | ||
291 | var activationSymbol1 = new ActivationVariable(); | ||
292 | var insertAction1 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1, | ||
293 | activationSymbol1); | ||
294 | var insertAction2 = new InsertAction<>(model.getInterpretation(relation1), false, newItemSymbol1, | ||
295 | activationSymbol1); | ||
296 | |||
297 | var action1 = new TransformationAction(); | ||
298 | action1.add(newItemSymbol1); | ||
299 | action1.add(activationSymbol1); | ||
300 | action1.add(insertAction1); | ||
301 | action1.prepare(model); | ||
302 | |||
303 | var action2 = new TransformationAction(); | ||
304 | action2.add(newItemSymbol1); | ||
305 | action2.add(activationSymbol1); | ||
306 | action2.add(insertAction2); | ||
307 | action2.prepare(model); | ||
308 | |||
309 | assertFalse(action1.equalsWithSubstitution(action2)); | ||
310 | } | ||
311 | |||
312 | @Test | ||
313 | void newItemSymbolDuplicateTest() { | ||
314 | var newItemSymbol1 = new NewItemVariable(); | ||
315 | var newItemSymbol2 = new NewItemVariable(); | ||
316 | var activationSymbol1 = new ActivationVariable(); | ||
317 | var insertAction1 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1, | ||
318 | activationSymbol1); | ||
319 | var insertAction2 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol2, | ||
320 | activationSymbol1); | ||
321 | |||
322 | var action1 = new TransformationAction(); | ||
323 | action1.add(newItemSymbol1); | ||
324 | action1.add(activationSymbol1); | ||
325 | action1.add(insertAction1); | ||
326 | action1.prepare(model); | ||
327 | |||
328 | var action2 = new TransformationAction(); | ||
329 | action2.add(newItemSymbol2); | ||
330 | action2.add(activationSymbol1); | ||
331 | action2.add(insertAction2); | ||
332 | action2.prepare(model); | ||
333 | |||
334 | assertTrue(action1.equalsWithSubstitution(action2)); | ||
335 | } | ||
336 | |||
337 | @Test | ||
338 | void activationSymbolDuplicateTest() { | ||
339 | var newItemSymbol1 = new NewItemVariable(); | ||
340 | var activationSymbol1 = new ActivationVariable(); | ||
341 | var activationSymbol2 = new ActivationVariable(); | ||
342 | var insertAction1 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1, | ||
343 | activationSymbol1); | ||
344 | var insertAction2 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1, | ||
345 | activationSymbol2); | ||
346 | |||
347 | var action1 = new TransformationAction(); | ||
348 | action1.add(newItemSymbol1); | ||
349 | action1.add(activationSymbol1); | ||
350 | action1.add(insertAction1); | ||
351 | action1.prepare(model); | ||
352 | |||
353 | var action2 = new TransformationAction(); | ||
354 | action2.add(newItemSymbol1); | ||
355 | action2.add(activationSymbol2); | ||
356 | action2.add(insertAction2); | ||
357 | action2.prepare(model); | ||
358 | |||
359 | assertTrue(action1.equalsWithSubstitution(action2)); | ||
360 | } | ||
361 | |||
362 | @Test | ||
363 | void activationSymbolIndexTest() { | ||
364 | var newItemSymbol1 = new NewItemVariable(); | ||
365 | var activationSymbol1 = new ActivationVariable(0); | ||
366 | var activationSymbol2 = new ActivationVariable(1); | ||
367 | var insertAction1 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1, | ||
368 | activationSymbol1); | ||
369 | var insertAction2 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1, | ||
370 | activationSymbol2); | ||
371 | |||
372 | var action1 = new TransformationAction(); | ||
373 | action1.add(newItemSymbol1); | ||
374 | action1.add(activationSymbol1); | ||
375 | action1.add(insertAction1); | ||
376 | action1.prepare(model); | ||
377 | |||
378 | var action2 = new TransformationAction(); | ||
379 | action2.add(newItemSymbol1); | ||
380 | action2.add(activationSymbol2); | ||
381 | action2.add(insertAction2); | ||
382 | action2.prepare(model); | ||
383 | |||
384 | assertFalse(action1.equalsWithSubstitution(action2)); | ||
385 | } | ||
386 | |||
387 | @Test | ||
388 | void deleteActionTest() { | ||
389 | var newItemSymbol = new NewItemVariable(); | ||
390 | var activationSymbol = new ActivationVariable(0); | ||
391 | var insertAction = new InsertAction<>(model.getInterpretation(relation1), false, newItemSymbol, | ||
392 | activationSymbol); | ||
393 | var deleteAction = new DeleteAction(activationSymbol); | ||
394 | |||
395 | var action1 = new TransformationAction(); | ||
396 | action1.add(newItemSymbol); | ||
397 | action1.add(activationSymbol); | ||
398 | action1.add(insertAction); | ||
399 | action1.add(deleteAction); | ||
400 | action1.prepare(model); | ||
401 | |||
402 | var action2 = new TransformationAction(); | ||
403 | action2.add(newItemSymbol); | ||
404 | action2.add(activationSymbol); | ||
405 | action2.add(insertAction); | ||
406 | action2.add(deleteAction); | ||
407 | action2.prepare(model); | ||
408 | |||
409 | assertTrue(action1.equalsWithSubstitution(action2)); | ||
410 | } | ||
411 | |||
412 | @Test | ||
413 | void deleteActionMissingTest() { | ||
414 | var newItemSymbol = new NewItemVariable(); | ||
415 | var activationSymbol = new ActivationVariable(0); | ||
416 | var insertAction = new InsertAction<>(model.getInterpretation(relation1), false, newItemSymbol, | ||
417 | activationSymbol); | ||
418 | var deleteAction = new DeleteAction(activationSymbol); | ||
419 | |||
420 | var action1 = new TransformationAction(); | ||
421 | action1.add(newItemSymbol); | ||
422 | action1.add(activationSymbol); | ||
423 | action1.add(insertAction); | ||
424 | action1.add(deleteAction); | ||
425 | action1.prepare(model); | ||
426 | |||
427 | var action2 = new TransformationAction(); | ||
428 | action2.add(newItemSymbol); | ||
429 | action2.add(activationSymbol); | ||
430 | action2.add(insertAction); | ||
431 | action2.prepare(model); | ||
432 | |||
433 | assertFalse(action1.equalsWithSubstitution(action2)); | ||
434 | } | ||
435 | |||
436 | @Test | ||
437 | void deleteActionIdenticalTest() { | ||
438 | var newItemSymbol = new NewItemVariable(); | ||
439 | var activationSymbol = new ActivationVariable(0); | ||
440 | var insertAction = new InsertAction<>(model.getInterpretation(relation1), false, newItemSymbol, | ||
441 | activationSymbol); | ||
442 | var deleteAction1 = new DeleteAction(activationSymbol); | ||
443 | var deleteAction2 = new DeleteAction(activationSymbol); | ||
444 | |||
445 | var action1 = new TransformationAction(); | ||
446 | action1.add(newItemSymbol); | ||
447 | action1.add(activationSymbol); | ||
448 | action1.add(insertAction); | ||
449 | action1.add(deleteAction1); | ||
450 | action1.prepare(model); | ||
451 | |||
452 | var action2 = new TransformationAction(); | ||
453 | action2.add(newItemSymbol); | ||
454 | action2.add(activationSymbol); | ||
455 | action2.add(insertAction); | ||
456 | action2.add(deleteAction2); | ||
457 | action2.prepare(model); | ||
458 | |||
459 | assertTrue(action1.equalsWithSubstitution(action2)); | ||
460 | } | ||
461 | |||
462 | @Test | ||
463 | void deleteActionSymbolTypeTest() { | ||
464 | var newItemSymbol = new NewItemVariable(); | ||
465 | var activationSymbol = new ActivationVariable(0); | ||
466 | var insertAction = new InsertAction<>(model.getInterpretation(relation1), false, newItemSymbol, | ||
467 | activationSymbol); | ||
468 | var deleteAction1 = new DeleteAction(activationSymbol); | ||
469 | var deleteAction2 = new DeleteAction(newItemSymbol); | ||
470 | |||
471 | var action1 = new TransformationAction(); | ||
472 | action1.add(newItemSymbol); | ||
473 | action1.add(activationSymbol); | ||
474 | action1.add(insertAction); | ||
475 | action1.add(deleteAction1); | ||
476 | action1.prepare(model); | ||
477 | |||
478 | var action2 = new TransformationAction(); | ||
479 | action2.add(newItemSymbol); | ||
480 | action2.add(activationSymbol); | ||
481 | action2.add(insertAction); | ||
482 | action2.add(deleteAction2); | ||
483 | action2.prepare(model); | ||
484 | |||
485 | assertFalse(action1.equalsWithSubstitution(action2)); | ||
486 | } | ||
487 | |||
488 | @Test | ||
489 | void deleteActionOrderTest() { | ||
490 | var newItemSymbol = new NewItemVariable(); | ||
491 | var activationSymbol = new ActivationVariable(0); | ||
492 | var insertAction = new InsertAction<>(model.getInterpretation(relation1), false, newItemSymbol, | ||
493 | activationSymbol); | ||
494 | var deleteAction1 = new DeleteAction(activationSymbol); | ||
495 | var deleteAction2 = new DeleteAction(newItemSymbol); | ||
496 | |||
497 | var action1 = new TransformationAction(); | ||
498 | action1.add(newItemSymbol); | ||
499 | action1.add(activationSymbol); | ||
500 | action1.add(insertAction); | ||
501 | action1.add(deleteAction1); | ||
502 | action1.add(deleteAction2); | ||
503 | action1.prepare(model); | ||
504 | |||
505 | var action2 = new TransformationAction(); | ||
506 | action2.add(newItemSymbol); | ||
507 | action2.add(activationSymbol); | ||
508 | action2.add(insertAction); | ||
509 | action2.add(deleteAction2); | ||
510 | action2.add(deleteAction1); | ||
511 | action2.prepare(model); | ||
512 | |||
513 | assertFalse(action1.equalsWithSubstitution(action2)); | ||
514 | } | ||
515 | |||
516 | @Test | ||
517 | void actionsMixedOrderTest() { | ||
518 | var newItemSymbol1 = new NewItemVariable(); | ||
519 | var activationSymbol1 = new ActivationVariable(); | ||
520 | var insertAction1 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1, | ||
521 | activationSymbol1); | ||
522 | var deleteAction1 = new DeleteAction(newItemSymbol1); | ||
523 | |||
524 | var newItemSymbol2 = new NewItemVariable(); | ||
525 | var activationSymbol2 = new ActivationVariable(); | ||
526 | var insertAction2 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol2, | ||
527 | activationSymbol2); | ||
528 | var deleteAction2 = new DeleteAction(activationSymbol2); | ||
529 | |||
530 | var action1 = new TransformationAction(); | ||
531 | action1.add(newItemSymbol1); | ||
532 | action1.add(newItemSymbol2); | ||
533 | action1.add(activationSymbol1); | ||
534 | action1.add(activationSymbol2); | ||
535 | action1.add(insertAction1); | ||
536 | action1.add(insertAction2); | ||
537 | action1.add(deleteAction1); | ||
538 | action1.add(deleteAction2); | ||
539 | action1.prepare(model); | ||
540 | |||
541 | var action2 = new TransformationAction(); | ||
542 | action2.add(deleteAction1); | ||
543 | action2.add(newItemSymbol1); | ||
544 | action2.add(insertAction1); | ||
545 | action2.add(newItemSymbol2); | ||
546 | action2.add(deleteAction2); | ||
547 | action2.add(activationSymbol1); | ||
548 | action2.add(insertAction2); | ||
549 | action2.add(activationSymbol2); | ||
550 | action2.prepare(model); | ||
551 | |||
552 | assertTrue(action1.equalsWithSubstitution(action2)); | ||
553 | } | ||
554 | |||
555 | @Test | ||
556 | void twoUnpreparedActionsTest() { | ||
557 | var newItemSymbol1 = new NewItemVariable(); | ||
558 | var activationSymbol1 = new ActivationVariable(); | ||
559 | var insertAction1 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1, | ||
560 | activationSymbol1); | ||
561 | var deleteAction1 = new DeleteAction(newItemSymbol1); | ||
562 | |||
563 | var newItemSymbol2 = new NewItemVariable(); | ||
564 | var activationSymbol2 = new ActivationVariable(); | ||
565 | var insertAction2 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol2, | ||
566 | activationSymbol2); | ||
567 | var deleteAction2 = new DeleteAction(activationSymbol2); | ||
568 | |||
569 | var action1 = new TransformationAction(); | ||
570 | action1.add(newItemSymbol1); | ||
571 | action1.add(newItemSymbol2); | ||
572 | action1.add(activationSymbol1); | ||
573 | action1.add(activationSymbol2); | ||
574 | action1.add(insertAction1); | ||
575 | action1.add(insertAction2); | ||
576 | action1.add(deleteAction1); | ||
577 | action1.add(deleteAction2); | ||
578 | |||
579 | var action2 = new TransformationAction(); | ||
580 | action2.add(deleteAction1); | ||
581 | action2.add(newItemSymbol1); | ||
582 | action2.add(insertAction1); | ||
583 | action2.add(newItemSymbol2); | ||
584 | action2.add(deleteAction2); | ||
585 | action2.add(activationSymbol1); | ||
586 | action2.add(insertAction2); | ||
587 | action2.add(activationSymbol2); | ||
588 | |||
589 | assertTrue(action1.equalsWithSubstitution(action2)); | ||
590 | } | ||
591 | |||
592 | @Test | ||
593 | void oneUnpreparedActionTest() { | ||
594 | var newItemSymbol1 = new NewItemVariable(); | ||
595 | var activationSymbol1 = new ActivationVariable(); | ||
596 | var insertAction1 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol1, | ||
597 | activationSymbol1); | ||
598 | var deleteAction1 = new DeleteAction(newItemSymbol1); | ||
599 | |||
600 | var newItemSymbol2 = new NewItemVariable(); | ||
601 | var activationSymbol2 = new ActivationVariable(); | ||
602 | var insertAction2 = new InsertAction<>(model.getInterpretation(relation1), true, newItemSymbol2, | ||
603 | activationSymbol2); | ||
604 | var deleteAction2 = new DeleteAction(activationSymbol2); | ||
605 | |||
606 | var action1 = new TransformationAction(); | ||
607 | action1.add(newItemSymbol1); | ||
608 | action1.add(newItemSymbol2); | ||
609 | action1.add(activationSymbol1); | ||
610 | action1.add(activationSymbol2); | ||
611 | action1.add(insertAction1); | ||
612 | action1.add(insertAction2); | ||
613 | action1.add(deleteAction1); | ||
614 | action1.add(deleteAction2); | ||
615 | action1.prepare(model); | ||
616 | |||
617 | var action2 = new TransformationAction(); | ||
618 | action2.add(deleteAction1); | ||
619 | action2.add(newItemSymbol1); | ||
620 | action2.add(insertAction1); | ||
621 | action2.add(newItemSymbol2); | ||
622 | action2.add(deleteAction2); | ||
623 | action2.add(activationSymbol1); | ||
624 | action2.add(insertAction2); | ||
625 | action2.add(activationSymbol2); | ||
626 | |||
627 | assertFalse(action1.equalsWithSubstitution(action2)); | ||
628 | } | ||
629 | } | ||
diff --git a/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerAdapterImpl.java b/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerAdapterImpl.java index 531969b4..e60ae4b7 100644 --- a/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerAdapterImpl.java +++ b/subprojects/visualization/src/main/java/tools/refinery/visualization/internal/ModelVisualizerAdapterImpl.java | |||
@@ -220,6 +220,7 @@ public class ModelVisualizerAdapterImpl implements ModelVisualizerAdapter { | |||
220 | } | 220 | } |
221 | 221 | ||
222 | private Integer[] typeColor(String name) { | 222 | private Integer[] typeColor(String name) { |
223 | @SuppressWarnings("squid:S2245") | ||
223 | var random = new Random(name.hashCode()); | 224 | var random = new Random(name.hashCode()); |
224 | return new Integer[] { random.nextInt(128) + 128, random.nextInt(128) + 128, random.nextInt(128) + 128 }; | 225 | return new Integer[] { random.nextInt(128) + 128, random.nextInt(128) + 128, random.nextInt(128) + 128 }; |
225 | } | 226 | } |