diff options
6 files changed, 129 insertions, 40 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 | } |
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/TermEvaluator.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/TermEvaluator.java index 5df861a6..d064ff2c 100644 --- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/TermEvaluator.java +++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/TermEvaluator.java | |||
@@ -5,10 +5,10 @@ | |||
5 | */ | 5 | */ |
6 | package tools.refinery.store.query.viatra.internal.pquery; | 6 | package tools.refinery.store.query.viatra.internal.pquery; |
7 | 7 | ||
8 | import tools.refinery.viatra.runtime.matchers.psystem.IExpressionEvaluator; | ||
9 | import tools.refinery.viatra.runtime.matchers.psystem.IValueProvider; | ||
10 | import tools.refinery.store.query.term.Term; | 8 | import tools.refinery.store.query.term.Term; |
11 | import tools.refinery.store.query.term.Variable; | 9 | import tools.refinery.store.query.term.Variable; |
10 | import tools.refinery.viatra.runtime.matchers.psystem.IExpressionEvaluator; | ||
11 | import tools.refinery.viatra.runtime.matchers.psystem.IValueProvider; | ||
12 | 12 | ||
13 | import java.util.stream.Collectors; | 13 | import java.util.stream.Collectors; |
14 | 14 | ||
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/update/TupleChangingViewUpdateListener.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/update/TupleChangingViewUpdateListener.java index 9dc739f1..5577faa3 100644 --- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/update/TupleChangingViewUpdateListener.java +++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/update/TupleChangingViewUpdateListener.java | |||
@@ -5,11 +5,11 @@ | |||
5 | */ | 5 | */ |
6 | package tools.refinery.store.query.viatra.internal.update; | 6 | package tools.refinery.store.query.viatra.internal.update; |
7 | 7 | ||
8 | import tools.refinery.viatra.runtime.matchers.tuple.Tuples; | ||
9 | import tools.refinery.store.model.Interpretation; | 8 | import tools.refinery.store.model.Interpretation; |
10 | import tools.refinery.store.query.viatra.internal.ViatraModelQueryAdapterImpl; | 9 | import tools.refinery.store.query.viatra.internal.ViatraModelQueryAdapterImpl; |
11 | import tools.refinery.store.query.view.SymbolView; | 10 | import tools.refinery.store.query.view.SymbolView; |
12 | import tools.refinery.store.tuple.Tuple; | 11 | import tools.refinery.store.tuple.Tuple; |
12 | import tools.refinery.viatra.runtime.matchers.tuple.Tuples; | ||
13 | 13 | ||
14 | import java.util.Arrays; | 14 | import java.util.Arrays; |
15 | 15 | ||
@@ -27,18 +27,19 @@ public class TupleChangingViewUpdateListener<T> extends SymbolViewUpdateListener | |||
27 | boolean fromPresent = view.filter(key, fromValue); | 27 | boolean fromPresent = view.filter(key, fromValue); |
28 | boolean toPresent = view.filter(key, toValue); | 28 | boolean toPresent = view.filter(key, toValue); |
29 | if (fromPresent) { | 29 | if (fromPresent) { |
30 | var fromArray = view.forwardMap(key, fromValue); | ||
30 | if (toPresent) { // value change | 31 | if (toPresent) { // value change |
31 | var fromArray = view.forwardMap(key, fromValue); | ||
32 | var toArray = view.forwardMap(key, toValue); | 32 | var toArray = view.forwardMap(key, toValue); |
33 | if (!Arrays.equals(fromArray, toArray)) { | 33 | if (!Arrays.equals(fromArray, toArray)) { |
34 | processUpdate(Tuples.flatTupleOf(fromArray), false); | 34 | processUpdate(Tuples.flatTupleOf(fromArray), false); |
35 | processUpdate(Tuples.flatTupleOf(toArray), true); | 35 | processUpdate(Tuples.flatTupleOf(toArray), true); |
36 | } | 36 | } |
37 | } else { // fromValue disappears | 37 | } else { // fromValue disappears |
38 | processUpdate(Tuples.flatTupleOf(view.forwardMap(key, fromValue)), false); | 38 | processUpdate(Tuples.flatTupleOf(fromArray), false); |
39 | } | 39 | } |
40 | } else if (toPresent) { // toValue appears | 40 | } else if (toPresent) { // toValue appears |
41 | processUpdate(Tuples.flatTupleOf(view.forwardMap(key, toValue)), true); | 41 | var toArray = view.forwardMap(key, toValue); |
42 | processUpdate(Tuples.flatTupleOf(toArray), true); | ||
42 | } | 43 | } |
43 | } | 44 | } |
44 | } | 45 | } |
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/ViatraQueryEngine.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/ViatraQueryEngine.java index 4c603a47..0f402b49 100644 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/ViatraQueryEngine.java +++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/api/ViatraQueryEngine.java | |||
@@ -15,6 +15,7 @@ import tools.refinery.viatra.runtime.api.scope.QueryScope; | |||
15 | import tools.refinery.viatra.runtime.matchers.ViatraQueryRuntimeException; | 15 | import tools.refinery.viatra.runtime.matchers.ViatraQueryRuntimeException; |
16 | 16 | ||
17 | import java.util.Set; | 17 | import java.util.Set; |
18 | import java.util.function.Supplier; | ||
18 | import java.util.stream.Collectors; | 19 | import java.util.stream.Collectors; |
19 | 20 | ||
20 | /** | 21 | /** |
@@ -147,4 +148,6 @@ public abstract class ViatraQueryEngine { | |||
147 | public abstract QueryScope getScope(); | 148 | public abstract QueryScope getScope(); |
148 | 149 | ||
149 | public abstract void flushChanges(); | 150 | public abstract void flushChanges(); |
151 | |||
152 | public abstract <T> T withFlushingChanges(Supplier<T> supplier); | ||
150 | } | 153 | } |
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/internal/apiimpl/ViatraQueryEngineImpl.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/internal/apiimpl/ViatraQueryEngineImpl.java index 47a51629..5317a79e 100644 --- a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/internal/apiimpl/ViatraQueryEngineImpl.java +++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/internal/apiimpl/ViatraQueryEngineImpl.java | |||
@@ -41,6 +41,7 @@ import java.lang.ref.WeakReference; | |||
41 | import java.lang.reflect.InvocationTargetException; | 41 | import java.lang.reflect.InvocationTargetException; |
42 | import java.util.*; | 42 | import java.util.*; |
43 | import java.util.concurrent.Callable; | 43 | import java.util.concurrent.Callable; |
44 | import java.util.function.Supplier; | ||
44 | import java.util.stream.Collectors; | 45 | import java.util.stream.Collectors; |
45 | 46 | ||
46 | import static tools.refinery.viatra.runtime.matchers.util.Preconditions.checkArgument; | 47 | import static tools.refinery.viatra.runtime.matchers.util.Preconditions.checkArgument; |
@@ -164,9 +165,27 @@ public final class ViatraQueryEngineImpl extends AdvancedViatraQueryEngine | |||
164 | } | 165 | } |
165 | delayMessageDelivery = false; | 166 | delayMessageDelivery = false; |
166 | try { | 167 | try { |
167 | for (IQueryBackend backend : this.queryBackends.values()) { | 168 | flushAllBackends(); |
168 | backend.flushUpdates(); | 169 | } finally { |
169 | } | 170 | delayMessageDelivery = true; |
171 | } | ||
172 | } | ||
173 | |||
174 | private void flushAllBackends() { | ||
175 | for (IQueryBackend backend : this.queryBackends.values()) { | ||
176 | backend.flushUpdates(); | ||
177 | } | ||
178 | } | ||
179 | |||
180 | @Override | ||
181 | public <T> T withFlushingChanges(Supplier<T> callback) { | ||
182 | if (!delayMessageDelivery) { | ||
183 | return callback.get(); | ||
184 | } | ||
185 | delayMessageDelivery = false; | ||
186 | try { | ||
187 | flushAllBackends(); | ||
188 | return callback.get(); | ||
170 | } finally { | 189 | } finally { |
171 | delayMessageDelivery = true; | 190 | delayMessageDelivery = true; |
172 | } | 191 | } |
@@ -186,18 +205,20 @@ public final class ViatraQueryEngineImpl extends AdvancedViatraQueryEngine | |||
186 | @Override | 205 | @Override |
187 | public <Matcher extends ViatraQueryMatcher<? extends IPatternMatch>> Matcher getMatcher( | 206 | public <Matcher extends ViatraQueryMatcher<? extends IPatternMatch>> Matcher getMatcher( |
188 | IQuerySpecification<Matcher> querySpecification, QueryEvaluationHint optionalEvaluationHints) { | 207 | IQuerySpecification<Matcher> querySpecification, QueryEvaluationHint optionalEvaluationHints) { |
189 | IMatcherCapability capability = getRequestedCapability(querySpecification, optionalEvaluationHints); | 208 | return withFlushingChanges(() -> { |
190 | Matcher matcher = doGetExistingMatcher(querySpecification, capability); | 209 | IMatcherCapability capability = getRequestedCapability(querySpecification, optionalEvaluationHints); |
191 | if (matcher != null) { | 210 | Matcher matcher = doGetExistingMatcher(querySpecification, capability); |
192 | return matcher; | 211 | if (matcher != null) { |
193 | } | 212 | return matcher; |
194 | matcher = querySpecification.instantiate(); | 213 | } |
195 | 214 | matcher = querySpecification.instantiate(); | |
196 | BaseMatcher<?> baseMatcher = (BaseMatcher<?>) matcher; | 215 | |
197 | ((QueryResultWrapper) baseMatcher).setBackend(this, | 216 | BaseMatcher<?> baseMatcher = (BaseMatcher<?>) matcher; |
198 | getResultProvider(querySpecification, optionalEvaluationHints), capability); | 217 | ((QueryResultWrapper) baseMatcher).setBackend(this, |
199 | internalRegisterMatcher(querySpecification, baseMatcher); | 218 | getResultProvider(querySpecification, optionalEvaluationHints), capability); |
200 | return matcher; | 219 | internalRegisterMatcher(querySpecification, baseMatcher); |
220 | return matcher; | ||
221 | }); | ||
201 | } | 222 | } |
202 | 223 | ||
203 | @Override | 224 | @Override |