diff options
author | Kristóf Marussy <kristof@marussy.com> | 2023-09-10 23:07:11 +0200 |
---|---|---|
committer | Kristóf Marussy <kristof@marussy.com> | 2023-09-10 23:07:11 +0200 |
commit | c7a86623b1589a3bd68a84a8d54a1eadc1aacefb (patch) | |
tree | 16fb5eb3d3b1282fecedefd9c7ae519162c540da /subprojects/language-semantics/src/test | |
parent | feat: integrate DSE with partial interpretation (diff) | |
download | refinery-c7a86623b1589a3bd68a84a8d54a1eadc1aacefb.tar.gz refinery-c7a86623b1589a3bd68a84a8d54a1eadc1aacefb.tar.zst refinery-c7a86623b1589a3bd68a84a8d54a1eadc1aacefb.zip |
fix: VIATRA projection indexer error
When a projection indexer is constructed for a production node, the projection
memory is only populated if changes are being propagated. The cache doesn't get
populated even if changes are flushed afterwards. This not only returns invalid
query results, but also a duplicate deletion exception will be thrown when the
production node tries to delete a tuple from the index memory.
To counteract this issue, we enable update propagation while a matcher (and its
associated indexers) are being created.
Diffstat (limited to 'subprojects/language-semantics/src/test')
2 files changed, 83 insertions, 19 deletions
diff --git a/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/model/CountPropagationTest.java b/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/model/CountPropagationTest.java index a383d043..eee2c4ae 100644 --- a/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/model/CountPropagationTest.java +++ b/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/model/CountPropagationTest.java | |||
@@ -67,15 +67,12 @@ class CountPropagationTest { | |||
67 | .put(Tuple.of(3), TruthValue.TRUE)) | 67 | .put(Tuple.of(3), TruthValue.TRUE)) |
68 | .build(); | 68 | .build(); |
69 | 69 | ||
70 | var model = store.getAdapter(ReasoningStoreAdapter.class).createInitialModel(modelSeed); | 70 | var initialModel = store.getAdapter(ReasoningStoreAdapter.class).createInitialModel(modelSeed); |
71 | var initialState = initialModel.commit(); | ||
72 | |||
73 | var model = store.createModelForState(initialState); | ||
71 | var reasoningAdapter = model.getAdapter(ReasoningAdapter.class); | 74 | var reasoningAdapter = model.getAdapter(ReasoningAdapter.class); |
72 | var propagationAdapter = model.getAdapter(PropagationAdapter.class); | 75 | var propagationAdapter = model.getAdapter(PropagationAdapter.class); |
73 | model.commit(); | ||
74 | |||
75 | reasoningAdapter.split(0); | ||
76 | assertThat(propagationAdapter.propagate(), is(PropagationResult.UNCHANGED)); | ||
77 | model.commit(); | ||
78 | |||
79 | reasoningAdapter.split(0); | 76 | reasoningAdapter.split(0); |
80 | assertThat(propagationAdapter.propagate(), is(PropagationResult.UNCHANGED)); | 77 | assertThat(propagationAdapter.propagate(), is(PropagationResult.UNCHANGED)); |
81 | } | 78 | } |
diff --git a/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/model/ModelGenerationTest.java b/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/model/ModelGenerationTest.java index 779e18ab..ecd5d39c 100644 --- a/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/model/ModelGenerationTest.java +++ b/subprojects/language-semantics/src/test/java/tools/refinery/language/semantics/model/ModelGenerationTest.java | |||
@@ -122,30 +122,30 @@ class ModelGenerationTest { | |||
122 | 122 | ||
123 | abstract class Vertex { | 123 | abstract class Vertex { |
124 | container Region[0..1] region opposite vertices | 124 | container Region[0..1] region opposite vertices |
125 | Transition[] outgoingTransition opposite source | 125 | contains Transition[] outgoingTransition opposite source |
126 | Transition[] incomingTransition opposite target | 126 | Transition[] incomingTransition opposite target |
127 | } | 127 | } |
128 | 128 | ||
129 | class Transition { | 129 | class Transition { |
130 | Vertex source opposite outgoingTransition | 130 | container Vertex[0..1] source opposite outgoingTransition |
131 | Vertex target opposite incomingTransition | 131 | Vertex target opposite incomingTransition |
132 | } | 132 | } |
133 | 133 | ||
134 | abstract class Pseudostate extends Vertex {} | 134 | abstract class Pseudostate extends Vertex. |
135 | 135 | ||
136 | abstract class RegularState extends Vertex {} | 136 | abstract class RegularState extends Vertex. |
137 | 137 | ||
138 | class Entry extends Pseudostate {} | 138 | class Entry extends Pseudostate. |
139 | 139 | ||
140 | class Exit extends Pseudostate {} | 140 | class Exit extends Pseudostate. |
141 | 141 | ||
142 | class Choice extends Pseudostate {} | 142 | class Choice extends Pseudostate. |
143 | 143 | ||
144 | class FinalState extends RegularState {} | 144 | class FinalState extends RegularState. |
145 | 145 | ||
146 | class State extends RegularState, CompositeElement {} | 146 | class State extends RegularState, CompositeElement. |
147 | 147 | ||
148 | class Statechart extends CompositeElement {} | 148 | class Statechart extends CompositeElement. |
149 | 149 | ||
150 | // Constraints | 150 | // Constraints |
151 | 151 | ||
@@ -209,7 +209,74 @@ class ModelGenerationTest { | |||
209 | error choiceHasNoIncoming(Choice c) <-> | 209 | error choiceHasNoIncoming(Choice c) <-> |
210 | !target(_, c). | 210 | !target(_, c). |
211 | 211 | ||
212 | scope node = 50..60, Statechart = 1. | 212 | scope node = 50..60, Region = 5..10, Statechart = 1. |
213 | """); | ||
214 | assertThat(parsedProblem.errors(), empty()); | ||
215 | var problem = parsedProblem.problem(); | ||
216 | |||
217 | var storeBuilder = ModelStore.builder() | ||
218 | .with(ViatraModelQueryAdapter.builder()) | ||
219 | // .with(ModelVisualizerAdapter.builder() | ||
220 | // .withOutputPath("test_output") | ||
221 | // .withFormat(FileFormat.DOT) | ||
222 | // .withFormat(FileFormat.SVG) | ||
223 | // .saveStates() | ||
224 | // .saveDesignSpace()) | ||
225 | .with(PropagationAdapter.builder()) | ||
226 | .with(StateCoderAdapter.builder()) | ||
227 | .with(DesignSpaceExplorationAdapter.builder()) | ||
228 | .with(ReasoningAdapter.builder()); | ||
229 | |||
230 | var modelSeed = modelInitializer.createModel(problem, storeBuilder); | ||
231 | |||
232 | var store = storeBuilder.build(); | ||
233 | |||
234 | var initialModel = store.getAdapter(ReasoningStoreAdapter.class).createInitialModel(modelSeed); | ||
235 | |||
236 | var initialVersion = initialModel.commit(); | ||
237 | |||
238 | var bestFirst = new BestFirstStoreManager(store, 1); | ||
239 | bestFirst.startExploration(initialVersion); | ||
240 | var resultStore = bestFirst.getSolutionStore(); | ||
241 | System.out.println("states size: " + resultStore.getSolutions().size()); | ||
242 | |||
243 | var model = store.createModelForState(resultStore.getSolutions().get(0).version()); | ||
244 | var interpretation = model.getAdapter(ReasoningAdapter.class) | ||
245 | .getPartialInterpretation(Concreteness.CANDIDATE, ReasoningAdapter.EXISTS_SYMBOL); | ||
246 | var cursor = interpretation.getAll(); | ||
247 | int max = -1; | ||
248 | var types = new LinkedHashMap<PartialRelation, Integer>(); | ||
249 | var typeInterpretation = model.getInterpretation(TypeHierarchyTranslator.TYPE_SYMBOL); | ||
250 | while (cursor.move()) { | ||
251 | max = Math.max(max, cursor.getKey().get(0)); | ||
252 | var type = typeInterpretation.get(cursor.getKey()); | ||
253 | if (type != null) { | ||
254 | types.compute(type.candidateType(), (ignoredKey, oldValue) -> oldValue == null ? 1 : oldValue + 1); | ||
255 | } | ||
256 | } | ||
257 | System.out.println("Model size: " + (max + 1)); | ||
258 | System.out.println(types); | ||
259 | // initialModel.getAdapter(ModelVisualizerAdapter.class).visualize(bestFirst.getVisualizationStore()); | ||
260 | } | ||
261 | |||
262 | @Test | ||
263 | void filesystemTest() { | ||
264 | var parsedProblem = parseHelper.parse(""" | ||
265 | class Filesystem { | ||
266 | contains Entry root | ||
267 | } | ||
268 | |||
269 | abstract class Entry. | ||
270 | |||
271 | class Directory extends Entry { | ||
272 | contains Entry[] entries | ||
273 | } | ||
274 | |||
275 | class File extends Entry. | ||
276 | |||
277 | Filesystem(fs). | ||
278 | |||
279 | scope Filesystem += 0, Entry = 100. | ||
213 | """); | 280 | """); |
214 | assertThat(parsedProblem.errors(), empty()); | 281 | assertThat(parsedProblem.errors(), empty()); |
215 | var problem = parsedProblem.problem(); | 282 | var problem = parsedProblem.problem(); |
@@ -265,7 +332,7 @@ class ModelGenerationTest { | |||
265 | var test = injector.getInstance(ModelGenerationTest.class); | 332 | var test = injector.getInstance(ModelGenerationTest.class); |
266 | try { | 333 | try { |
267 | test.statechartTest(); | 334 | test.statechartTest(); |
268 | } catch (AssertionError e) { | 335 | } catch (Throwable e) { |
269 | e.printStackTrace(); | 336 | e.printStackTrace(); |
270 | } | 337 | } |
271 | } | 338 | } |