aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store-query-viatra/src/main
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/store-query-viatra/src/main')
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/ViatraModelQueryBuilder.java14
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/ViatraModelQueryStoreAdapter.java2
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/RelationalScope.java8
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraModelQueryAdapterImpl.java89
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraModelQueryBuilderImpl.java90
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraModelQueryStoreAdapterImpl.java30
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/DummyBaseIndexer.java10
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalEngineContext.java6
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalQueryMetaContext.java8
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalRuntimeContext.java33
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/ExtendOperationExecutor.java76
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/ExtendPositivePatternCall.java117
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/FlatCostFunction.java12
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/GenericTypeExtend.java137
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/RelationalLocalSearchBackendFactory.java60
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/RelationalLocalSearchResultProvider.java28
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/RelationalOperationCompiler.java70
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/AbstractViatraMatcher.java4
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/FunctionalCursor.java4
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/FunctionalViatraMatcher.java16
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/IndexerUtils.java53
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/MatcherUtils.java6
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/RawPatternMatcher.java6
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/RelationalCursor.java2
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/RelationalViatraMatcher.java16
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/UnsafeFunctionalCursor.java2
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/CheckEvaluator.java (renamed from subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/AssumptionEvaluator.java)6
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/Dnf2PQuery.java151
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/QueryWrapperFactory.java24
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/RawPQuery.java16
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/StatefulMultisetAggregator.java2
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/StatelessMultisetAggregator.java2
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/SymbolViewWrapper.java2
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/TermEvaluator.java4
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/ValueProviderBasedValuation.java2
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/update/ModelUpdateListener.java6
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/update/RelationViewFilter.java8
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/update/SymbolViewUpdateListener.java8
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/update/TupleChangingViewUpdateListener.java9
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/update/TuplePreservingViewUpdateListener.java2
40 files changed, 290 insertions, 851 deletions
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/ViatraModelQueryBuilder.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/ViatraModelQueryBuilder.java
index 931a07aa..d19c3bb4 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/ViatraModelQueryBuilder.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/ViatraModelQueryBuilder.java
@@ -5,13 +5,14 @@
5 */ 5 */
6package tools.refinery.store.query.viatra; 6package tools.refinery.store.query.viatra;
7 7
8import org.eclipse.viatra.query.runtime.api.ViatraQueryEngineOptions;
9import org.eclipse.viatra.query.runtime.matchers.backend.IQueryBackendFactory;
10import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint;
11import tools.refinery.store.model.ModelStore; 8import tools.refinery.store.model.ModelStore;
9import tools.refinery.store.query.ModelQueryBuilder;
12import tools.refinery.store.query.dnf.AnyQuery; 10import tools.refinery.store.query.dnf.AnyQuery;
13import tools.refinery.store.query.dnf.Dnf; 11import tools.refinery.store.query.dnf.Dnf;
14import tools.refinery.store.query.ModelQueryBuilder; 12import tools.refinery.store.query.rewriter.DnfRewriter;
13import tools.refinery.viatra.runtime.api.ViatraQueryEngineOptions;
14import tools.refinery.viatra.runtime.matchers.backend.IQueryBackendFactory;
15import tools.refinery.viatra.runtime.matchers.backend.QueryEvaluationHint;
15 16
16import java.util.Collection; 17import java.util.Collection;
17import java.util.function.Function; 18import java.util.function.Function;
@@ -43,12 +44,11 @@ public interface ViatraModelQueryBuilder extends ModelQueryBuilder {
43 @Override 44 @Override
44 ViatraModelQueryBuilder query(AnyQuery query); 45 ViatraModelQueryBuilder query(AnyQuery query);
45 46
46 ViatraModelQueryBuilder query(AnyQuery query, QueryEvaluationHint queryEvaluationHint); 47 @Override
48 ViatraModelQueryBuilder rewriter(DnfRewriter rewriter);
47 49
48 ViatraModelQueryBuilder computeHint(Function<Dnf, QueryEvaluationHint> computeHint); 50 ViatraModelQueryBuilder computeHint(Function<Dnf, QueryEvaluationHint> computeHint);
49 51
50 ViatraModelQueryBuilder hint(Dnf dnf, QueryEvaluationHint queryEvaluationHint);
51
52 @Override 52 @Override
53 ViatraModelQueryStoreAdapter build(ModelStore store); 53 ViatraModelQueryStoreAdapter build(ModelStore store);
54} 54}
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/ViatraModelQueryStoreAdapter.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/ViatraModelQueryStoreAdapter.java
index da6d7bd5..588c00d4 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/ViatraModelQueryStoreAdapter.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/ViatraModelQueryStoreAdapter.java
@@ -5,7 +5,7 @@
5 */ 5 */
6package tools.refinery.store.query.viatra; 6package tools.refinery.store.query.viatra;
7 7
8import org.eclipse.viatra.query.runtime.api.ViatraQueryEngineOptions; 8import tools.refinery.viatra.runtime.api.ViatraQueryEngineOptions;
9import tools.refinery.store.model.Model; 9import tools.refinery.store.model.Model;
10import tools.refinery.store.query.ModelQueryStoreAdapter; 10import tools.refinery.store.query.ModelQueryStoreAdapter;
11 11
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/RelationalScope.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/RelationalScope.java
index d1a65a89..9303cae6 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/RelationalScope.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/RelationalScope.java
@@ -6,10 +6,10 @@
6package tools.refinery.store.query.viatra.internal; 6package tools.refinery.store.query.viatra.internal;
7 7
8import org.apache.log4j.Logger; 8import org.apache.log4j.Logger;
9import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; 9import tools.refinery.viatra.runtime.api.ViatraQueryEngine;
10import org.eclipse.viatra.query.runtime.api.scope.IEngineContext; 10import tools.refinery.viatra.runtime.api.scope.IEngineContext;
11import org.eclipse.viatra.query.runtime.api.scope.IIndexingErrorListener; 11import tools.refinery.viatra.runtime.api.scope.IIndexingErrorListener;
12import org.eclipse.viatra.query.runtime.api.scope.QueryScope; 12import tools.refinery.viatra.runtime.api.scope.QueryScope;
13import tools.refinery.store.query.viatra.internal.context.RelationalEngineContext; 13import tools.refinery.store.query.viatra.internal.context.RelationalEngineContext;
14 14
15public class RelationalScope extends QueryScope { 15public class RelationalScope extends QueryScope {
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraModelQueryAdapterImpl.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraModelQueryAdapterImpl.java
index 5f3e86b4..ad754988 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraModelQueryAdapterImpl.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraModelQueryAdapterImpl.java
@@ -5,69 +5,47 @@
5 */ 5 */
6package tools.refinery.store.query.viatra.internal; 6package tools.refinery.store.query.viatra.internal;
7 7
8import org.eclipse.viatra.query.runtime.api.AdvancedViatraQueryEngine;
9import org.eclipse.viatra.query.runtime.api.GenericQueryGroup;
10import org.eclipse.viatra.query.runtime.api.IQuerySpecification;
11import org.eclipse.viatra.query.runtime.internal.apiimpl.ViatraQueryEngineImpl;
12import org.eclipse.viatra.query.runtime.matchers.backend.IQueryBackend;
13import org.eclipse.viatra.query.runtime.matchers.backend.IQueryBackendFactory;
14import tools.refinery.store.model.Model; 8import tools.refinery.store.model.Model;
15import tools.refinery.store.model.ModelListener; 9import tools.refinery.store.model.ModelListener;
16import tools.refinery.store.query.resultset.AnyResultSet;
17import tools.refinery.store.query.resultset.EmptyResultSet;
18import tools.refinery.store.query.resultset.ResultSet;
19import tools.refinery.store.query.dnf.AnyQuery; 10import tools.refinery.store.query.dnf.AnyQuery;
20import tools.refinery.store.query.dnf.FunctionalQuery; 11import tools.refinery.store.query.dnf.FunctionalQuery;
21import tools.refinery.store.query.dnf.Query; 12import tools.refinery.store.query.dnf.Query;
22import tools.refinery.store.query.dnf.RelationalQuery; 13import tools.refinery.store.query.dnf.RelationalQuery;
14import tools.refinery.store.query.resultset.AnyResultSet;
15import tools.refinery.store.query.resultset.EmptyResultSet;
16import tools.refinery.store.query.resultset.ResultSet;
23import tools.refinery.store.query.viatra.ViatraModelQueryAdapter; 17import tools.refinery.store.query.viatra.ViatraModelQueryAdapter;
24import tools.refinery.store.query.viatra.internal.matcher.FunctionalViatraMatcher; 18import tools.refinery.store.query.viatra.internal.matcher.FunctionalViatraMatcher;
25import tools.refinery.store.query.viatra.internal.matcher.RawPatternMatcher; 19import tools.refinery.store.query.viatra.internal.matcher.RawPatternMatcher;
26import tools.refinery.store.query.viatra.internal.matcher.RelationalViatraMatcher; 20import tools.refinery.store.query.viatra.internal.matcher.RelationalViatraMatcher;
21import tools.refinery.viatra.runtime.CancellationToken;
22import tools.refinery.viatra.runtime.api.AdvancedViatraQueryEngine;
23import tools.refinery.viatra.runtime.api.GenericQueryGroup;
24import tools.refinery.viatra.runtime.api.IQuerySpecification;
27 25
28import java.lang.invoke.MethodHandle;
29import java.lang.invoke.MethodHandles;
30import java.util.Collection;
31import java.util.Collections; 26import java.util.Collections;
32import java.util.LinkedHashMap; 27import java.util.LinkedHashMap;
33import java.util.Map; 28import java.util.Map;
34 29
35public class ViatraModelQueryAdapterImpl implements ViatraModelQueryAdapter, ModelListener { 30public class ViatraModelQueryAdapterImpl implements ViatraModelQueryAdapter, ModelListener {
36 private static final String DELAY_MESSAGE_DELIVERY_FIELD_NAME = "delayMessageDelivery";
37 private static final MethodHandle SET_UPDATE_PROPAGATION_DELAYED_HANDLE;
38 private static final String QUERY_BACKENDS_FIELD_NAME = "queryBackends";
39 private static final MethodHandle GET_QUERY_BACKENDS_HANDLE;
40
41 private final Model model; 31 private final Model model;
42 private final ViatraModelQueryStoreAdapterImpl storeAdapter; 32 private final ViatraModelQueryStoreAdapterImpl storeAdapter;
43 private final ViatraQueryEngineImpl queryEngine; 33 private final AdvancedViatraQueryEngine queryEngine;
44 private final Map<AnyQuery, AnyResultSet> resultSets; 34 private final Map<AnyQuery, AnyResultSet> resultSets;
45 private boolean pendingChanges; 35 private boolean pendingChanges;
46 36
47 static {
48 try {
49 var lookup = MethodHandles.privateLookupIn(ViatraQueryEngineImpl.class, MethodHandles.lookup());
50 SET_UPDATE_PROPAGATION_DELAYED_HANDLE = lookup.findSetter(ViatraQueryEngineImpl.class,
51 DELAY_MESSAGE_DELIVERY_FIELD_NAME, Boolean.TYPE);
52 GET_QUERY_BACKENDS_HANDLE = lookup.findGetter(ViatraQueryEngineImpl.class, QUERY_BACKENDS_FIELD_NAME,
53 Map.class);
54 } catch (IllegalAccessException | NoSuchFieldException e) {
55 throw new IllegalStateException("Cannot access private members of %s"
56 .formatted(ViatraQueryEngineImpl.class.getName()), e);
57 }
58 }
59
60 ViatraModelQueryAdapterImpl(Model model, ViatraModelQueryStoreAdapterImpl storeAdapter) { 37 ViatraModelQueryAdapterImpl(Model model, ViatraModelQueryStoreAdapterImpl storeAdapter) {
61 this.model = model; 38 this.model = model;
62 this.storeAdapter = storeAdapter; 39 this.storeAdapter = storeAdapter;
63 var scope = new RelationalScope(this); 40 var scope = new RelationalScope(this);
64 queryEngine = (ViatraQueryEngineImpl) AdvancedViatraQueryEngine.createUnmanagedEngine(scope, 41 queryEngine = AdvancedViatraQueryEngine.createUnmanagedEngine(scope,
65 storeAdapter.getEngineOptions()); 42 storeAdapter.getEngineOptions());
66 43
67 var querySpecifications = storeAdapter.getQuerySpecifications(); 44 var querySpecifications = storeAdapter.getQuerySpecifications();
68 GenericQueryGroup.of( 45 GenericQueryGroup.of(
69 Collections.<IQuerySpecification<?>>unmodifiableCollection(querySpecifications.values()).stream() 46 Collections.<IQuerySpecification<?>>unmodifiableCollection(querySpecifications.values()).stream()
70 ).prepare(queryEngine); 47 ).prepare(queryEngine);
48 queryEngine.flushChanges();
71 var vacuousQueries = storeAdapter.getVacuousQueries(); 49 var vacuousQueries = storeAdapter.getVacuousQueries();
72 resultSets = new LinkedHashMap<>(querySpecifications.size() + vacuousQueries.size()); 50 resultSets = new LinkedHashMap<>(querySpecifications.size() + vacuousQueries.size());
73 for (var entry : querySpecifications.entrySet()) { 51 for (var entry : querySpecifications.entrySet()) {
@@ -79,7 +57,6 @@ public class ViatraModelQueryAdapterImpl implements ViatraModelQueryAdapter, Mod
79 resultSets.put(vacuousQuery, new EmptyResultSet<>(this, (Query<?>) vacuousQuery)); 57 resultSets.put(vacuousQuery, new EmptyResultSet<>(this, (Query<?>) vacuousQuery));
80 } 58 }
81 59
82 setUpdatePropagationDelayed(true);
83 model.addListener(this); 60 model.addListener(this);
84 } 61 }
85 62
@@ -95,30 +72,6 @@ public class ViatraModelQueryAdapterImpl implements ViatraModelQueryAdapter, Mod
95 } 72 }
96 } 73 }
97 74
98 private void setUpdatePropagationDelayed(boolean value) {
99 try {
100 SET_UPDATE_PROPAGATION_DELAYED_HANDLE.invokeExact(queryEngine, value);
101 } catch (Error e) {
102 // Fatal JVM errors should not be wrapped.
103 throw e;
104 } catch (Throwable e) {
105 throw new IllegalStateException("Cannot set %s".formatted(DELAY_MESSAGE_DELIVERY_FIELD_NAME), e);
106 }
107 }
108
109 private Collection<IQueryBackend> getQueryBackends() {
110 try {
111 @SuppressWarnings("unchecked")
112 var backendMap = (Map<IQueryBackendFactory, IQueryBackend>) GET_QUERY_BACKENDS_HANDLE.invokeExact(queryEngine);
113 return backendMap.values();
114 } catch (Error e) {
115 // Fatal JVM errors should not be wrapped.
116 throw e;
117 } catch (Throwable e) {
118 throw new IllegalStateException("Cannot get %s".formatted(QUERY_BACKENDS_FIELD_NAME), e);
119 }
120 }
121
122 @Override 75 @Override
123 public Model getModel() { 76 public Model getModel() {
124 return model; 77 return model;
@@ -129,9 +82,14 @@ public class ViatraModelQueryAdapterImpl implements ViatraModelQueryAdapter, Mod
129 return storeAdapter; 82 return storeAdapter;
130 } 83 }
131 84
85 public CancellationToken getCancellationToken() {
86 return storeAdapter.getCancellationToken();
87 }
88
132 @Override 89 @Override
133 public <T> ResultSet<T> getResultSet(Query<T> query) { 90 public <T> ResultSet<T> getResultSet(Query<T> query) {
134 var resultSet = resultSets.get(query); 91 var canonicalQuery = storeAdapter.getCanonicalQuery(query);
92 var resultSet = resultSets.get(canonicalQuery);
135 if (resultSet == null) { 93 if (resultSet == null) {
136 throw new IllegalArgumentException("No matcher for query %s in model".formatted(query.name())); 94 throw new IllegalArgumentException("No matcher for query %s in model".formatted(query.name()));
137 } 95 }
@@ -153,20 +111,7 @@ public class ViatraModelQueryAdapterImpl implements ViatraModelQueryAdapter, Mod
153 111
154 @Override 112 @Override
155 public void flushChanges() { 113 public void flushChanges() {
156 if (!queryEngine.isUpdatePropagationDelayed()) { 114 queryEngine.flushChanges();
157 throw new IllegalStateException("Trying to flush changes while changes are already being flushed");
158 }
159 if (!pendingChanges) {
160 return;
161 }
162 setUpdatePropagationDelayed(false);
163 try {
164 for (var queryBackend : getQueryBackends()) {
165 queryBackend.flushUpdates();
166 }
167 } finally {
168 setUpdatePropagationDelayed(true);
169 }
170 pendingChanges = false; 115 pendingChanges = false;
171 } 116 }
172 117
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraModelQueryBuilderImpl.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraModelQueryBuilderImpl.java
index ce2467b4..c68152e3 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraModelQueryBuilderImpl.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraModelQueryBuilderImpl.java
@@ -5,22 +5,25 @@
5 */ 5 */
6package tools.refinery.store.query.viatra.internal; 6package tools.refinery.store.query.viatra.internal;
7 7
8import org.eclipse.viatra.query.runtime.api.IQuerySpecification;
9import org.eclipse.viatra.query.runtime.api.ViatraQueryEngineOptions;
10import org.eclipse.viatra.query.runtime.localsearch.matcher.integration.LocalSearchHintOptions;
11import org.eclipse.viatra.query.runtime.matchers.backend.IQueryBackendFactory;
12import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint;
13import org.eclipse.viatra.query.runtime.rete.matcher.ReteBackendFactory;
14import tools.refinery.store.adapter.AbstractModelAdapterBuilder; 8import tools.refinery.store.adapter.AbstractModelAdapterBuilder;
15import tools.refinery.store.model.ModelStore; 9import tools.refinery.store.model.ModelStore;
16import tools.refinery.store.model.ModelStoreBuilder;
17import tools.refinery.store.query.dnf.AnyQuery; 10import tools.refinery.store.query.dnf.AnyQuery;
18import tools.refinery.store.query.dnf.Dnf; 11import tools.refinery.store.query.dnf.Dnf;
12import tools.refinery.store.query.rewriter.CompositeRewriter;
13import tools.refinery.store.query.rewriter.DnfRewriter;
14import tools.refinery.store.query.rewriter.DuplicateDnfRemover;
15import tools.refinery.store.query.rewriter.InputParameterResolver;
19import tools.refinery.store.query.viatra.ViatraModelQueryBuilder; 16import tools.refinery.store.query.viatra.ViatraModelQueryBuilder;
20import tools.refinery.store.query.viatra.internal.localsearch.FlatCostFunction; 17import tools.refinery.store.query.viatra.internal.localsearch.FlatCostFunction;
21import tools.refinery.store.query.viatra.internal.localsearch.RelationalLocalSearchBackendFactory;
22import tools.refinery.store.query.viatra.internal.matcher.RawPatternMatcher; 18import tools.refinery.store.query.viatra.internal.matcher.RawPatternMatcher;
23import tools.refinery.store.query.viatra.internal.pquery.Dnf2PQuery; 19import tools.refinery.store.query.viatra.internal.pquery.Dnf2PQuery;
20import tools.refinery.viatra.runtime.api.IQuerySpecification;
21import tools.refinery.viatra.runtime.api.ViatraQueryEngineOptions;
22import tools.refinery.viatra.runtime.localsearch.matcher.integration.LocalSearchGenericBackendFactory;
23import tools.refinery.viatra.runtime.localsearch.matcher.integration.LocalSearchHintOptions;
24import tools.refinery.viatra.runtime.matchers.backend.IQueryBackendFactory;
25import tools.refinery.viatra.runtime.matchers.backend.QueryEvaluationHint;
26import tools.refinery.viatra.runtime.rete.matcher.ReteBackendFactory;
24 27
25import java.util.*; 28import java.util.*;
26import java.util.function.Function; 29import java.util.function.Function;
@@ -32,15 +35,18 @@ public class ViatraModelQueryBuilderImpl extends AbstractModelAdapterBuilder<Via
32 // Use a cost function that ignores the initial (empty) model but allows higher arity input keys. 35 // Use a cost function that ignores the initial (empty) model but allows higher arity input keys.
33 LocalSearchHintOptions.PLANNER_COST_FUNCTION, new FlatCostFunction() 36 LocalSearchHintOptions.PLANNER_COST_FUNCTION, new FlatCostFunction()
34 ), (IQueryBackendFactory) null); 37 ), (IQueryBackendFactory) null);
38 private final CompositeRewriter rewriter;
35 private final Dnf2PQuery dnf2PQuery = new Dnf2PQuery(); 39 private final Dnf2PQuery dnf2PQuery = new Dnf2PQuery();
36 private final Set<AnyQuery> vacuousQueries = new LinkedHashSet<>(); 40 private final Set<AnyQuery> queries = new LinkedHashSet<>();
37 private final Map<AnyQuery, IQuerySpecification<RawPatternMatcher>> querySpecifications = new LinkedHashMap<>();
38 41
39 public ViatraModelQueryBuilderImpl() { 42 public ViatraModelQueryBuilderImpl() {
40 engineOptionsBuilder = new ViatraQueryEngineOptions.Builder() 43 engineOptionsBuilder = new ViatraQueryEngineOptions.Builder()
41 .withDefaultBackend(ReteBackendFactory.INSTANCE) 44 .withDefaultBackend(ReteBackendFactory.INSTANCE)
42 .withDefaultCachingBackend(ReteBackendFactory.INSTANCE) 45 .withDefaultCachingBackend(ReteBackendFactory.INSTANCE)
43 .withDefaultSearchBackend(RelationalLocalSearchBackendFactory.INSTANCE); 46 .withDefaultSearchBackend(LocalSearchGenericBackendFactory.INSTANCE);
47 rewriter = new CompositeRewriter();
48 rewriter.addFirst(new DuplicateDnfRemover());
49 rewriter.addFirst(new InputParameterResolver());
44 } 50 }
45 51
46 @Override 52 @Override
@@ -79,58 +85,58 @@ public class ViatraModelQueryBuilderImpl extends AbstractModelAdapterBuilder<Via
79 } 85 }
80 86
81 @Override 87 @Override
82 public ViatraModelQueryBuilder query(AnyQuery query) { 88 public ViatraModelQueryBuilder queries(Collection<? extends AnyQuery> queries) {
83 checkNotConfigured(); 89 checkNotConfigured();
84 if (querySpecifications.containsKey(query) || vacuousQueries.contains(query)) { 90 this.queries.addAll(queries);
85 // Ignore duplicate queries.
86 return this;
87 }
88 var dnf = query.getDnf();
89 var reduction = dnf.getReduction();
90 switch (reduction) {
91 case NOT_REDUCIBLE -> {
92 var pQuery = dnf2PQuery.translate(dnf);
93 querySpecifications.put(query, pQuery.build());
94 }
95 case ALWAYS_FALSE -> vacuousQueries.add(query);
96 case ALWAYS_TRUE -> throw new IllegalArgumentException(
97 "Query %s is relationally unsafe (it matches every tuple)".formatted(query.name()));
98 default -> throw new IllegalArgumentException("Unknown reduction: " + reduction);
99 }
100 return this; 91 return this;
101 } 92 }
102 93
103 @Override 94 @Override
104 public ViatraModelQueryBuilder query(AnyQuery query, QueryEvaluationHint queryEvaluationHint) { 95 public ViatraModelQueryBuilder query(AnyQuery query) {
105 hint(query.getDnf(), queryEvaluationHint); 96 checkNotConfigured();
106 query(query); 97 queries.add(query);
107 return this; 98 return this;
108 } 99 }
109 100
110 @Override 101 @Override
111 public ViatraModelQueryBuilder computeHint(Function<Dnf, QueryEvaluationHint> computeHint) { 102 public ViatraModelQueryBuilder rewriter(DnfRewriter rewriter) {
112 checkNotConfigured(); 103 this.rewriter.addFirst(rewriter);
113 dnf2PQuery.setComputeHint(computeHint);
114 return this; 104 return this;
115 } 105 }
116 106
117 @Override 107 @Override
118 public ViatraModelQueryBuilder hint(Dnf dnf, QueryEvaluationHint queryEvaluationHint) { 108 public ViatraModelQueryBuilder computeHint(Function<Dnf, QueryEvaluationHint> computeHint) {
119 checkNotConfigured(); 109 checkNotConfigured();
120 dnf2PQuery.hint(dnf, queryEvaluationHint); 110 dnf2PQuery.setComputeHint(computeHint);
121 return this; 111 return this;
122 } 112 }
123 113
124 @Override 114 @Override
125 public void doConfigure(ModelStoreBuilder storeBuilder) {
126 dnf2PQuery.assertNoUnusedHints();
127 }
128
129 @Override
130 public ViatraModelQueryStoreAdapterImpl doBuild(ModelStore store) { 115 public ViatraModelQueryStoreAdapterImpl doBuild(ModelStore store) {
116 var canonicalQueryMap = new HashMap<AnyQuery, AnyQuery>();
117 var querySpecifications = new LinkedHashMap<AnyQuery, IQuerySpecification<RawPatternMatcher>>();
118 var vacuousQueries = new LinkedHashSet<AnyQuery>();
119 for (var query : queries) {
120 var canonicalQuery = rewriter.rewrite(query);
121 canonicalQueryMap.put(query, canonicalQuery);
122 var dnf = canonicalQuery.getDnf();
123 var reduction = dnf.getReduction();
124 switch (reduction) {
125 case NOT_REDUCIBLE -> {
126 var pQuery = dnf2PQuery.translate(dnf);
127 querySpecifications.put(canonicalQuery, pQuery.build());
128 }
129 case ALWAYS_FALSE -> vacuousQueries.add(canonicalQuery);
130 case ALWAYS_TRUE -> throw new IllegalArgumentException(
131 "Query %s is relationally unsafe (it matches every tuple)".formatted(query.name()));
132 default -> throw new IllegalArgumentException("Unknown reduction: " + reduction);
133 }
134 }
135
131 validateSymbols(store); 136 validateSymbols(store);
132 return new ViatraModelQueryStoreAdapterImpl(store, buildEngineOptions(), dnf2PQuery.getSymbolViews(), 137 return new ViatraModelQueryStoreAdapterImpl(store, buildEngineOptions(), dnf2PQuery.getSymbolViews(),
133 Collections.unmodifiableMap(querySpecifications), Collections.unmodifiableSet(vacuousQueries)); 138 Collections.unmodifiableMap(canonicalQueryMap), Collections.unmodifiableMap(querySpecifications),
139 Collections.unmodifiableSet(vacuousQueries), store::checkCancelled);
134 } 140 }
135 141
136 private ViatraQueryEngineOptions buildEngineOptions() { 142 private ViatraQueryEngineOptions buildEngineOptions() {
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraModelQueryStoreAdapterImpl.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraModelQueryStoreAdapterImpl.java
index 11a3c7fd..f32e1cc6 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraModelQueryStoreAdapterImpl.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraModelQueryStoreAdapterImpl.java
@@ -5,12 +5,14 @@
5 */ 5 */
6package tools.refinery.store.query.viatra.internal; 6package tools.refinery.store.query.viatra.internal;
7 7
8import org.eclipse.viatra.query.runtime.api.IQuerySpecification; 8import tools.refinery.viatra.runtime.CancellationToken;
9import org.eclipse.viatra.query.runtime.api.ViatraQueryEngineOptions; 9import tools.refinery.viatra.runtime.api.IQuerySpecification;
10import org.eclipse.viatra.query.runtime.matchers.context.IInputKey; 10import tools.refinery.viatra.runtime.api.ViatraQueryEngineOptions;
11import tools.refinery.viatra.runtime.matchers.context.IInputKey;
11import tools.refinery.store.model.Model; 12import tools.refinery.store.model.Model;
12import tools.refinery.store.model.ModelStore; 13import tools.refinery.store.model.ModelStore;
13import tools.refinery.store.query.dnf.AnyQuery; 14import tools.refinery.store.query.dnf.AnyQuery;
15import tools.refinery.store.query.dnf.Query;
14import tools.refinery.store.query.viatra.ViatraModelQueryStoreAdapter; 16import tools.refinery.store.query.viatra.ViatraModelQueryStoreAdapter;
15import tools.refinery.store.query.viatra.internal.matcher.RawPatternMatcher; 17import tools.refinery.store.query.viatra.internal.matcher.RawPatternMatcher;
16import tools.refinery.store.query.view.AnySymbolView; 18import tools.refinery.store.query.view.AnySymbolView;
@@ -21,19 +23,24 @@ public class ViatraModelQueryStoreAdapterImpl implements ViatraModelQueryStoreAd
21 private final ModelStore store; 23 private final ModelStore store;
22 private final ViatraQueryEngineOptions engineOptions; 24 private final ViatraQueryEngineOptions engineOptions;
23 private final Map<AnySymbolView, IInputKey> inputKeys; 25 private final Map<AnySymbolView, IInputKey> inputKeys;
26 private final Map<AnyQuery, AnyQuery> canonicalQueryMap;
24 private final Map<AnyQuery, IQuerySpecification<RawPatternMatcher>> querySpecifications; 27 private final Map<AnyQuery, IQuerySpecification<RawPatternMatcher>> querySpecifications;
25 private final Set<AnyQuery> vacuousQueries; 28 private final Set<AnyQuery> vacuousQueries;
26 private final Set<AnyQuery> allQueries; 29 private final Set<AnyQuery> allQueries;
30 private final CancellationToken cancellationToken;
27 31
28 ViatraModelQueryStoreAdapterImpl(ModelStore store, ViatraQueryEngineOptions engineOptions, 32 ViatraModelQueryStoreAdapterImpl(ModelStore store, ViatraQueryEngineOptions engineOptions,
29 Map<AnySymbolView, IInputKey> inputKeys, 33 Map<AnySymbolView, IInputKey> inputKeys,
34 Map<AnyQuery, AnyQuery> canonicalQueryMap,
30 Map<AnyQuery, IQuerySpecification<RawPatternMatcher>> querySpecifications, 35 Map<AnyQuery, IQuerySpecification<RawPatternMatcher>> querySpecifications,
31 Set<AnyQuery> vacuousQueries) { 36 Set<AnyQuery> vacuousQueries, CancellationToken cancellationToken) {
32 this.store = store; 37 this.store = store;
33 this.engineOptions = engineOptions; 38 this.engineOptions = engineOptions;
34 this.inputKeys = inputKeys; 39 this.inputKeys = inputKeys;
40 this.canonicalQueryMap = canonicalQueryMap;
35 this.querySpecifications = querySpecifications; 41 this.querySpecifications = querySpecifications;
36 this.vacuousQueries = vacuousQueries; 42 this.vacuousQueries = vacuousQueries;
43 this.cancellationToken = cancellationToken;
37 var mutableAllQueries = new LinkedHashSet<AnyQuery>(querySpecifications.size() + vacuousQueries.size()); 44 var mutableAllQueries = new LinkedHashSet<AnyQuery>(querySpecifications.size() + vacuousQueries.size());
38 mutableAllQueries.addAll(querySpecifications.keySet()); 45 mutableAllQueries.addAll(querySpecifications.keySet());
39 mutableAllQueries.addAll(vacuousQueries); 46 mutableAllQueries.addAll(vacuousQueries);
@@ -58,6 +65,21 @@ public class ViatraModelQueryStoreAdapterImpl implements ViatraModelQueryStoreAd
58 return allQueries; 65 return allQueries;
59 } 66 }
60 67
68 public CancellationToken getCancellationToken() {
69 return cancellationToken;
70 }
71
72 @Override
73 public <T> Query<T> getCanonicalQuery(Query<T> query) {
74 // We know that canonical forms of queries do not change output types.
75 @SuppressWarnings("unchecked")
76 var canonicalQuery = (Query<T>) canonicalQueryMap.get(query);
77 if (canonicalQuery == null) {
78 throw new IllegalArgumentException("Unknown query: " + query);
79 }
80 return canonicalQuery;
81 }
82
61 Map<AnyQuery, IQuerySpecification<RawPatternMatcher>> getQuerySpecifications() { 83 Map<AnyQuery, IQuerySpecification<RawPatternMatcher>> getQuerySpecifications() {
62 return querySpecifications; 84 return querySpecifications;
63 } 85 }
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/DummyBaseIndexer.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/DummyBaseIndexer.java
index 8cb199d2..64d98258 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/DummyBaseIndexer.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/DummyBaseIndexer.java
@@ -5,16 +5,16 @@
5 */ 5 */
6package tools.refinery.store.query.viatra.internal.context; 6package tools.refinery.store.query.viatra.internal.context;
7 7
8import org.eclipse.viatra.query.runtime.api.scope.IBaseIndex; 8import tools.refinery.viatra.runtime.api.scope.IBaseIndex;
9import org.eclipse.viatra.query.runtime.api.scope.IIndexingErrorListener; 9import tools.refinery.viatra.runtime.api.scope.IIndexingErrorListener;
10import org.eclipse.viatra.query.runtime.api.scope.IInstanceObserver; 10import tools.refinery.viatra.runtime.api.scope.IInstanceObserver;
11import org.eclipse.viatra.query.runtime.api.scope.ViatraBaseIndexChangeListener; 11import tools.refinery.viatra.runtime.api.scope.ViatraBaseIndexChangeListener;
12 12
13import java.lang.reflect.InvocationTargetException; 13import java.lang.reflect.InvocationTargetException;
14import java.util.concurrent.Callable; 14import java.util.concurrent.Callable;
15 15
16/** 16/**
17 * Copied from <code>org.eclipse.viatra.query.runtime.tabular.TabularEngineContext</code> 17 * Copied from <code>tools.refinery.viatra.runtime.tabular.TabularEngineContext</code>
18 */ 18 */
19public class DummyBaseIndexer implements IBaseIndex { 19public class DummyBaseIndexer implements IBaseIndex {
20 DummyBaseIndexer() { 20 DummyBaseIndexer() {
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalEngineContext.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalEngineContext.java
index 7220f8ca..f7d323ff 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalEngineContext.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalEngineContext.java
@@ -5,9 +5,9 @@
5 */ 5 */
6package tools.refinery.store.query.viatra.internal.context; 6package tools.refinery.store.query.viatra.internal.context;
7 7
8import org.eclipse.viatra.query.runtime.api.scope.IBaseIndex; 8import tools.refinery.viatra.runtime.api.scope.IBaseIndex;
9import org.eclipse.viatra.query.runtime.api.scope.IEngineContext; 9import tools.refinery.viatra.runtime.api.scope.IEngineContext;
10import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContext; 10import tools.refinery.viatra.runtime.matchers.context.IQueryRuntimeContext;
11import tools.refinery.store.query.viatra.internal.ViatraModelQueryAdapterImpl; 11import tools.refinery.store.query.viatra.internal.ViatraModelQueryAdapterImpl;
12 12
13public class RelationalEngineContext implements IEngineContext { 13public class RelationalEngineContext implements IEngineContext {
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalQueryMetaContext.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalQueryMetaContext.java
index 211eacb4..77d86a1c 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalQueryMetaContext.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalQueryMetaContext.java
@@ -5,10 +5,10 @@
5 */ 5 */
6package tools.refinery.store.query.viatra.internal.context; 6package tools.refinery.store.query.viatra.internal.context;
7 7
8import org.eclipse.viatra.query.runtime.matchers.context.AbstractQueryMetaContext; 8import tools.refinery.viatra.runtime.matchers.context.AbstractQueryMetaContext;
9import org.eclipse.viatra.query.runtime.matchers.context.IInputKey; 9import tools.refinery.viatra.runtime.matchers.context.IInputKey;
10import org.eclipse.viatra.query.runtime.matchers.context.InputKeyImplication; 10import tools.refinery.viatra.runtime.matchers.context.InputKeyImplication;
11import org.eclipse.viatra.query.runtime.matchers.context.common.JavaTransitiveInstancesKey; 11import tools.refinery.viatra.runtime.matchers.context.common.JavaTransitiveInstancesKey;
12import tools.refinery.store.query.viatra.internal.pquery.SymbolViewWrapper; 12import tools.refinery.store.query.viatra.internal.pquery.SymbolViewWrapper;
13import tools.refinery.store.query.view.AnySymbolView; 13import tools.refinery.store.query.view.AnySymbolView;
14 14
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalRuntimeContext.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalRuntimeContext.java
index 0f2daca8..dadab5dd 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalRuntimeContext.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalRuntimeContext.java
@@ -5,12 +5,13 @@
5 */ 5 */
6package tools.refinery.store.query.viatra.internal.context; 6package tools.refinery.store.query.viatra.internal.context;
7 7
8import org.eclipse.viatra.query.runtime.matchers.context.*; 8import tools.refinery.viatra.runtime.CancellationToken;
9import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; 9import tools.refinery.viatra.runtime.matchers.context.*;
10import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; 10import tools.refinery.viatra.runtime.matchers.tuple.ITuple;
11import org.eclipse.viatra.query.runtime.matchers.tuple.TupleMask; 11import tools.refinery.viatra.runtime.matchers.tuple.Tuple;
12import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; 12import tools.refinery.viatra.runtime.matchers.tuple.TupleMask;
13import org.eclipse.viatra.query.runtime.matchers.util.Accuracy; 13import tools.refinery.viatra.runtime.matchers.tuple.Tuples;
14import tools.refinery.viatra.runtime.matchers.util.Accuracy;
14import tools.refinery.store.model.Model; 15import tools.refinery.store.model.Model;
15import tools.refinery.store.query.viatra.internal.ViatraModelQueryAdapterImpl; 16import tools.refinery.store.query.viatra.internal.ViatraModelQueryAdapterImpl;
16import tools.refinery.store.query.viatra.internal.pquery.SymbolViewWrapper; 17import tools.refinery.store.query.viatra.internal.pquery.SymbolViewWrapper;
@@ -32,10 +33,13 @@ public class RelationalRuntimeContext implements IQueryRuntimeContext {
32 33
33 private final Model model; 34 private final Model model;
34 35
36 private final CancellationToken cancellationToken;
37
35 RelationalRuntimeContext(ViatraModelQueryAdapterImpl adapter) { 38 RelationalRuntimeContext(ViatraModelQueryAdapterImpl adapter) {
36 model = adapter.getModel(); 39 model = adapter.getModel();
37 metaContext = new RelationalQueryMetaContext(adapter.getStoreAdapter().getInputKeys()); 40 metaContext = new RelationalQueryMetaContext(adapter.getStoreAdapter().getInputKeys());
38 modelUpdateListener = new ModelUpdateListener(adapter); 41 modelUpdateListener = new ModelUpdateListener(adapter);
42 cancellationToken = adapter.getCancellationToken();
39 } 43 }
40 44
41 @Override 45 @Override
@@ -119,10 +123,20 @@ public class RelationalRuntimeContext implements IQueryRuntimeContext {
119 123
120 private Iterable<Object[]> enumerate(IInputKey key, TupleMask seedMask, ITuple seed) { 124 private Iterable<Object[]> enumerate(IInputKey key, TupleMask seedMask, ITuple seed) {
121 var relationViewKey = checkKey(key); 125 var relationViewKey = checkKey(key);
122 Iterable<Object[]> allObjects = relationViewKey.getAll(model); 126 Iterable<Object[]> allObjects = getAllObjects(relationViewKey, seedMask, seed);
123 return filter(allObjects, objectArray -> isMatching(objectArray, seedMask, seed)); 127 return filter(allObjects, objectArray -> isMatching(objectArray, seedMask, seed));
124 } 128 }
125 129
130 private Iterable<Object[]> getAllObjects(AnySymbolView key, TupleMask seedMask, ITuple seed) {
131 for (int i = 0; i < seedMask.indices.length; i++) {
132 int slot = seedMask.indices[i];
133 if (key.canIndexSlot(slot)) {
134 return key.getAdjacent(model, slot, seed.get(i));
135 }
136 }
137 return key.getAll(model);
138 }
139
126 private static boolean isMatching(Object[] tuple, TupleMask seedMask, ITuple seed) { 140 private static boolean isMatching(Object[] tuple, TupleMask seedMask, ITuple seed) {
127 for (int i = 0; i < seedMask.indices.length; i++) { 141 for (int i = 0; i < seedMask.indices.length; i++) {
128 final Object seedElement = seed.get(i); 142 final Object seedElement = seed.get(i);
@@ -182,4 +196,9 @@ public class RelationalRuntimeContext implements IQueryRuntimeContext {
182 public void executeAfterTraversal(Runnable runnable) { 196 public void executeAfterTraversal(Runnable runnable) {
183 runnable.run(); 197 runnable.run();
184 } 198 }
199
200 @Override
201 public CancellationToken getCancellationToken() {
202 return cancellationToken;
203 }
185} 204}
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/ExtendOperationExecutor.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/ExtendOperationExecutor.java
deleted file mode 100644
index 37177cbf..00000000
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/ExtendOperationExecutor.java
+++ /dev/null
@@ -1,76 +0,0 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2013, Zoltan Ujhelyi, Akos Horvath, Istvan Rath and Daniel Varro
3 * Copyright (c) 2023 The Refinery Authors <https://refinery.tools/>
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v. 2.0 which is available at
6 * http://www.eclipse.org/legal/epl-v20.html.
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package tools.refinery.store.query.viatra.internal.localsearch;
10
11import org.eclipse.viatra.query.runtime.localsearch.MatchingFrame;
12import org.eclipse.viatra.query.runtime.localsearch.matcher.ISearchContext;
13import org.eclipse.viatra.query.runtime.localsearch.operations.ISearchOperation.ISearchOperationExecutor;
14
15import java.util.Iterator;
16
17/**
18 * An operation that can be used to enumerate all possible values for a single position based on a constraint
19 * @author Zoltan Ujhelyi, Akos Horvath
20 * @since 2.0
21 */
22abstract class ExtendOperationExecutor<T> implements ISearchOperationExecutor {
23
24 private Iterator<? extends T> it;
25
26 /**
27 * Returns an iterator with the possible options from the current state
28 * @since 2.0
29 */
30 @SuppressWarnings("squid:S1452")
31 protected abstract Iterator<? extends T> getIterator(MatchingFrame frame, ISearchContext context);
32 /**
33 * Updates the frame with the next element of the iterator. Called during {@link #execute(MatchingFrame, ISearchContext)}.
34 *
35 * @return true if the update is successful or false otherwise; in case of false is returned, the next element should be taken from the iterator.
36 * @since 2.0
37 */
38 protected abstract boolean fillInValue(T newValue, MatchingFrame frame, ISearchContext context);
39
40 /**
41 * Restores the frame to the state before {@link #fillInValue(Object, MatchingFrame, ISearchContext)}. Called during
42 * {@link #onBacktrack(MatchingFrame, ISearchContext)}.
43 *
44 * @since 2.0
45 */
46 protected abstract void cleanup(MatchingFrame frame, ISearchContext context);
47
48 @Override
49 public void onInitialize(MatchingFrame frame, ISearchContext context) {
50 it = getIterator(frame, context);
51 }
52
53 @Override
54 public void onBacktrack(MatchingFrame frame, ISearchContext context) {
55 it = null;
56
57 }
58
59 /**
60 * Fixed version of {@link org.eclipse.viatra.query.runtime.localsearch.operations.ExtendOperationExecutor#execute}
61 * that handles failed unification of variables correctly.
62 * @param frame The matching frame to extend.
63 * @param context The search context.
64 * @return {@code true} if an extension was found, {@code false} otherwise.
65 */
66 @Override
67 public boolean execute(MatchingFrame frame, ISearchContext context) {
68 while (it.hasNext()) {
69 var newValue = it.next();
70 if (fillInValue(newValue, frame, context)) {
71 return true;
72 }
73 }
74 return false;
75 }
76}
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/ExtendPositivePatternCall.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/ExtendPositivePatternCall.java
deleted file mode 100644
index 9d48c785..00000000
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/ExtendPositivePatternCall.java
+++ /dev/null
@@ -1,117 +0,0 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2016, Grill Balázs, IncQueryLabs
3 * Copyright (c) 2023 The Refinery Authors <https://refinery.tools/>
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v. 2.0 which is available at
6 * http://www.eclipse.org/legal/epl-v20.html.
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package tools.refinery.store.query.viatra.internal.localsearch;
10
11import org.eclipse.viatra.query.runtime.localsearch.MatchingFrame;
12import org.eclipse.viatra.query.runtime.localsearch.matcher.ISearchContext;
13import org.eclipse.viatra.query.runtime.localsearch.operations.IPatternMatcherOperation;
14import org.eclipse.viatra.query.runtime.localsearch.operations.ISearchOperation;
15import org.eclipse.viatra.query.runtime.localsearch.operations.util.CallInformation;
16import org.eclipse.viatra.query.runtime.matchers.backend.IQueryResultProvider;
17import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple;
18import org.eclipse.viatra.query.runtime.matchers.tuple.TupleMask;
19import org.eclipse.viatra.query.runtime.matchers.tuple.VolatileModifiableMaskedTuple;
20
21import java.util.Iterator;
22import java.util.List;
23import java.util.function.Function;
24
25/**
26 * @author Grill Balázs
27 * @since 1.4
28 *
29 */
30public class ExtendPositivePatternCall implements ISearchOperation, IPatternMatcherOperation {
31
32 private class Executor extends ExtendOperationExecutor<Tuple> {
33 private final VolatileModifiableMaskedTuple maskedTuple;
34
35 public Executor() {
36 maskedTuple = new VolatileModifiableMaskedTuple(information.getThinFrameMask());
37 }
38
39 @Override
40 protected Iterator<? extends Tuple> getIterator(MatchingFrame frame, ISearchContext context) {
41 maskedTuple.updateTuple(frame);
42 IQueryResultProvider matcher = context.getMatcher(information.getCallWithAdornment());
43 return matcher.getAllMatches(information.getParameterMask(), maskedTuple).iterator();
44 }
45
46 /**
47 * @since 2.0
48 */
49 @Override
50 protected boolean fillInValue(Tuple result, MatchingFrame frame, ISearchContext context) {
51 TupleMask mask = information.getFullFrameMask();
52 // The first loop clears out the elements from a possible previous iteration
53 for(int i : information.getFreeParameterIndices()) {
54 mask.set(frame, i, null);
55 }
56 for(int i : information.getFreeParameterIndices()) {
57 Object oldValue = mask.getValue(frame, i);
58 Object valueToFill = result.get(i);
59 if (oldValue != null && !oldValue.equals(valueToFill)){
60 // If the inverse map contains more than one values for the same key, it means that these arguments are unified by the caller.
61 // In this case if the callee assigns different values the frame shall be dropped
62 return false;
63 }
64 mask.set(frame, i, valueToFill);
65 }
66 return true;
67 }
68
69 @Override
70 protected void cleanup(MatchingFrame frame, ISearchContext context) {
71 TupleMask mask = information.getFullFrameMask();
72 for(int i : information.getFreeParameterIndices()){
73 mask.set(frame, i, null);
74 }
75
76 }
77
78 @Override
79 public ISearchOperation getOperation() {
80 return ExtendPositivePatternCall.this;
81 }
82 }
83
84 private final CallInformation information;
85
86 /**
87 * @since 1.7
88 */
89 public ExtendPositivePatternCall(CallInformation information) {
90 this.information = information;
91 }
92
93 @Override
94 public ISearchOperationExecutor createExecutor() {
95 return new Executor();
96 }
97
98 @Override
99 public List<Integer> getVariablePositions() {
100 return information.getVariablePositions();
101 }
102
103 @Override
104 public String toString() {
105 return toString(Object::toString);
106 }
107
108 @Override
109 public String toString(@SuppressWarnings("squid:S4276") Function<Integer, String> variableMapping) {
110 return "extend find " + information.toString(variableMapping);
111 }
112
113 @Override
114 public CallInformation getCallInformation() {
115 return information;
116 }
117}
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/FlatCostFunction.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/FlatCostFunction.java
index cc906f22..ce2a75bd 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/FlatCostFunction.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/FlatCostFunction.java
@@ -5,12 +5,12 @@
5 */ 5 */
6package tools.refinery.store.query.viatra.internal.localsearch; 6package tools.refinery.store.query.viatra.internal.localsearch;
7 7
8import org.eclipse.viatra.query.runtime.localsearch.planner.cost.IConstraintEvaluationContext; 8import tools.refinery.viatra.runtime.localsearch.planner.cost.IConstraintEvaluationContext;
9import org.eclipse.viatra.query.runtime.localsearch.planner.cost.impl.StatisticsBasedConstraintCostFunction; 9import tools.refinery.viatra.runtime.localsearch.planner.cost.impl.StatisticsBasedConstraintCostFunction;
10import org.eclipse.viatra.query.runtime.matchers.context.IInputKey; 10import tools.refinery.viatra.runtime.matchers.context.IInputKey;
11import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; 11import tools.refinery.viatra.runtime.matchers.psystem.basicenumerables.TypeConstraint;
12import org.eclipse.viatra.query.runtime.matchers.tuple.TupleMask; 12import tools.refinery.viatra.runtime.matchers.tuple.TupleMask;
13import org.eclipse.viatra.query.runtime.matchers.util.Accuracy; 13import tools.refinery.viatra.runtime.matchers.util.Accuracy;
14 14
15import java.util.Optional; 15import java.util.Optional;
16 16
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/GenericTypeExtend.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/GenericTypeExtend.java
deleted file mode 100644
index 96ac4a72..00000000
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/GenericTypeExtend.java
+++ /dev/null
@@ -1,137 +0,0 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2017, Zoltan Ujhelyi, IncQuery Labs Ltd.
3 * Copyright (c) 2023 The Refinery Authors <https://refinery.tools/>
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v. 2.0 which is available at
6 * http://www.eclipse.org/legal/epl-v20.html.
7 * SPDX-License-Identifier: EPL-2.0
8 *******************************************************************************/
9package tools.refinery.store.query.viatra.internal.localsearch;
10
11import org.eclipse.viatra.query.runtime.localsearch.MatchingFrame;
12import org.eclipse.viatra.query.runtime.localsearch.matcher.ISearchContext;
13import org.eclipse.viatra.query.runtime.localsearch.operations.IIteratingSearchOperation;
14import org.eclipse.viatra.query.runtime.localsearch.operations.ISearchOperation;
15import org.eclipse.viatra.query.runtime.matchers.context.IInputKey;
16import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple;
17import org.eclipse.viatra.query.runtime.matchers.tuple.TupleMask;
18import org.eclipse.viatra.query.runtime.matchers.tuple.VolatileMaskedTuple;
19import org.eclipse.viatra.query.runtime.matchers.util.Preconditions;
20
21import java.util.*;
22import java.util.function.Function;
23import java.util.stream.Collectors;
24
25/**
26 * @author Zoltan Ujhelyi
27 * @since 1.7
28 */
29public class GenericTypeExtend implements IIteratingSearchOperation {
30 private class Executor extends ExtendOperationExecutor<Tuple> {
31 private final VolatileMaskedTuple maskedTuple;
32
33 public Executor() {
34 this.maskedTuple = new VolatileMaskedTuple(callMask);
35 }
36
37 @Override
38 protected Iterator<? extends Tuple> getIterator(MatchingFrame frame, ISearchContext context) {
39 maskedTuple.updateTuple(frame);
40 return context.getRuntimeContext().enumerateTuples(type, indexerMask, maskedTuple).iterator();
41 }
42
43 @Override
44 protected boolean fillInValue(Tuple newTuple, MatchingFrame frame, ISearchContext context) {
45 for (Integer position : unboundVariableIndices) {
46 frame.setValue(position, null);
47 }
48 for (int i = 0; i < positions.length; i++) {
49 Object newValue = newTuple.get(i);
50 Object oldValue = frame.getValue(positions[i]);
51 if (oldValue != null && !Objects.equals(oldValue, newValue)) {
52 // If positions tuple maps more than one values for the same element (e.g. loop), it means that
53 // these arguments are to unified by the caller. In this case if the callee assigns different values
54 // the frame shall be considered a failed match
55 return false;
56 }
57 frame.setValue(positions[i], newValue);
58 }
59 return true;
60 }
61
62 @Override
63 protected void cleanup(MatchingFrame frame, ISearchContext context) {
64 for (Integer position : unboundVariableIndices) {
65 frame.setValue(position, null);
66 }
67 }
68
69 @Override
70 public ISearchOperation getOperation() {
71 return GenericTypeExtend.this;
72 }
73 }
74
75 private final IInputKey type;
76 private final int[] positions;
77 private final List<Integer> positionList;
78 private final Set<Integer> unboundVariableIndices;
79 private final TupleMask indexerMask;
80 private final TupleMask callMask;
81
82 /**
83 *
84 * @param type
85 * the type to execute the extend operation on
86 * @param positions
87 * the parameter positions that represent the variables of the input key
88 * @param unboundVariableIndices
89 * the set of positions that are bound at the start of the operation
90 */
91 public GenericTypeExtend(IInputKey type, int[] positions, TupleMask callMask, TupleMask indexerMask, Set<Integer> unboundVariableIndices) {
92 Preconditions.checkArgument(positions.length == type.getArity(),
93 "The type %s requires %d parameters, but %d positions are provided", type.getPrettyPrintableName(),
94 type.getArity(), positions.length);
95 List<Integer> modifiablePositionList = new ArrayList<>();
96 for (int position : positions) {
97 modifiablePositionList.add(position);
98 }
99 this.positionList = Collections.unmodifiableList(modifiablePositionList);
100 this.positions = positions;
101 this.type = type;
102
103 this.unboundVariableIndices = unboundVariableIndices;
104 this.indexerMask = indexerMask;
105 this.callMask = callMask;
106 }
107
108 @Override
109 public IInputKey getIteratedInputKey() {
110 return type;
111 }
112
113 @Override
114 public ISearchOperationExecutor createExecutor() {
115 return new Executor();
116 }
117
118 @Override
119 public List<Integer> getVariablePositions() {
120 return positionList;
121 }
122
123 @Override
124 public String toString() {
125 return toString(Object::toString);
126 }
127
128 @Override
129 public String toString(@SuppressWarnings("squid:S4276") Function<Integer, String> variableMapping) {
130 return "extend " + type.getPrettyPrintableName() + "("
131 + positionList.stream()
132 .map(input -> String.format("%s%s", unboundVariableIndices.contains(input) ? "-" : "+", variableMapping.apply(input)))
133 .collect(Collectors.joining(", "))
134 + ")";
135 }
136
137}
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/RelationalLocalSearchBackendFactory.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/RelationalLocalSearchBackendFactory.java
deleted file mode 100644
index 0c77f587..00000000
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/RelationalLocalSearchBackendFactory.java
+++ /dev/null
@@ -1,60 +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.query.viatra.internal.localsearch;
7
8import org.eclipse.viatra.query.runtime.localsearch.matcher.integration.AbstractLocalSearchResultProvider;
9import org.eclipse.viatra.query.runtime.localsearch.matcher.integration.LocalSearchBackend;
10import org.eclipse.viatra.query.runtime.localsearch.matcher.integration.LocalSearchHints;
11import org.eclipse.viatra.query.runtime.localsearch.plan.IPlanProvider;
12import org.eclipse.viatra.query.runtime.localsearch.plan.SimplePlanProvider;
13import org.eclipse.viatra.query.runtime.matchers.backend.IMatcherCapability;
14import org.eclipse.viatra.query.runtime.matchers.backend.IQueryBackend;
15import org.eclipse.viatra.query.runtime.matchers.backend.IQueryBackendFactory;
16import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint;
17import org.eclipse.viatra.query.runtime.matchers.context.IQueryBackendContext;
18import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery;
19
20public class RelationalLocalSearchBackendFactory implements IQueryBackendFactory {
21 public static final RelationalLocalSearchBackendFactory INSTANCE = new RelationalLocalSearchBackendFactory();
22
23 private RelationalLocalSearchBackendFactory() {
24 }
25
26 @Override
27 public IQueryBackend create(IQueryBackendContext context) {
28 return new LocalSearchBackend(context) {
29 // Create a new {@link IPlanProvider}, because the original {@link LocalSearchBackend#planProvider} is not
30 // accessible.
31 private final IPlanProvider planProvider = new SimplePlanProvider(context.getLogger());
32
33 @Override
34 protected AbstractLocalSearchResultProvider initializeResultProvider(PQuery query,
35 QueryEvaluationHint hints) {
36 return new RelationalLocalSearchResultProvider(this, context, query, planProvider, hints);
37 }
38
39 @Override
40 public IQueryBackendFactory getFactory() {
41 return RelationalLocalSearchBackendFactory.this;
42 }
43 };
44 }
45
46 @Override
47 public Class<? extends IQueryBackend> getBackendClass() {
48 return LocalSearchBackend.class;
49 }
50
51 @Override
52 public IMatcherCapability calculateRequiredCapability(PQuery pQuery, QueryEvaluationHint queryEvaluationHint) {
53 return LocalSearchHints.parse(queryEvaluationHint);
54 }
55
56 @Override
57 public boolean isCaching() {
58 return false;
59 }
60}
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/RelationalLocalSearchResultProvider.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/RelationalLocalSearchResultProvider.java
deleted file mode 100644
index da37be14..00000000
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/RelationalLocalSearchResultProvider.java
+++ /dev/null
@@ -1,28 +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.query.viatra.internal.localsearch;
7
8import org.eclipse.viatra.query.runtime.localsearch.matcher.integration.AbstractLocalSearchResultProvider;
9import org.eclipse.viatra.query.runtime.localsearch.matcher.integration.LocalSearchBackend;
10import org.eclipse.viatra.query.runtime.localsearch.matcher.integration.LocalSearchHints;
11import org.eclipse.viatra.query.runtime.localsearch.plan.IPlanProvider;
12import org.eclipse.viatra.query.runtime.localsearch.planner.compiler.IOperationCompiler;
13import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint;
14import org.eclipse.viatra.query.runtime.matchers.context.IQueryBackendContext;
15import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery;
16
17class RelationalLocalSearchResultProvider extends AbstractLocalSearchResultProvider {
18 public RelationalLocalSearchResultProvider(LocalSearchBackend backend, IQueryBackendContext context, PQuery query,
19 IPlanProvider planProvider, QueryEvaluationHint userHints) {
20 super(backend, context, query, planProvider, userHints);
21 }
22
23 @Override
24 protected IOperationCompiler getOperationCompiler(IQueryBackendContext backendContext,
25 LocalSearchHints configuration) {
26 return new RelationalOperationCompiler(runtimeContext);
27 }
28}
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/RelationalOperationCompiler.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/RelationalOperationCompiler.java
deleted file mode 100644
index f76ef486..00000000
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/localsearch/RelationalOperationCompiler.java
+++ /dev/null
@@ -1,70 +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.query.viatra.internal.localsearch;
7
8import org.eclipse.viatra.query.runtime.localsearch.operations.generic.GenericTypeExtendSingleValue;
9import org.eclipse.viatra.query.runtime.localsearch.operations.util.CallInformation;
10import org.eclipse.viatra.query.runtime.localsearch.planner.compiler.GenericOperationCompiler;
11import org.eclipse.viatra.query.runtime.matchers.context.IInputKey;
12import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContext;
13import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable;
14import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall;
15import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint;
16import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple;
17import org.eclipse.viatra.query.runtime.matchers.tuple.TupleMask;
18
19import java.util.*;
20
21public class RelationalOperationCompiler extends GenericOperationCompiler {
22 public RelationalOperationCompiler(IQueryRuntimeContext runtimeContext) {
23 super(runtimeContext);
24 }
25
26 @Override
27 protected void createExtend(TypeConstraint typeConstraint, Map<PVariable, Integer> variableMapping) {
28 IInputKey inputKey = typeConstraint.getSupplierKey();
29 Tuple tuple = typeConstraint.getVariablesTuple();
30
31 int[] positions = new int[tuple.getSize()];
32 List<Integer> boundVariableIndices = new ArrayList<>();
33 List<Integer> boundVariables = new ArrayList<>();
34 Set<Integer> unboundVariables = new HashSet<>();
35 for (int i = 0; i < tuple.getSize(); i++) {
36 PVariable variable = (PVariable) tuple.get(i);
37 Integer position = variableMapping.get(variable);
38 positions[i] = position;
39 if (variableBindings.get(typeConstraint).contains(position)) {
40 boundVariableIndices.add(i);
41 boundVariables.add(position);
42 } else {
43 unboundVariables.add(position);
44 }
45 }
46 TupleMask indexerMask = TupleMask.fromSelectedIndices(inputKey.getArity(), boundVariableIndices);
47 TupleMask callMask = TupleMask.fromSelectedIndices(variableMapping.size(), boundVariables);
48 // If multiple tuple elements from the indexer should be bound to the same variable, we must use a
49 // {@link GenericTypeExtend} check whether the tuple elements have the same value.
50 if (unboundVariables.size() == 1 && indexerMask.getSize() + 1 == indexerMask.getSourceWidth()) {
51 operations.add(new GenericTypeExtendSingleValue(inputKey, positions, callMask, indexerMask,
52 unboundVariables.iterator().next()));
53 } else {
54 // Use a fixed version of
55 // {@code org.eclipse.viatra.query.runtime.localsearch.operations.generic.GenericTypeExtend} that handles
56 // failed unification of variables correctly.
57 operations.add(new GenericTypeExtend(inputKey, positions, callMask, indexerMask, unboundVariables));
58 }
59 }
60
61 @Override
62 protected void createExtend(PositivePatternCall pCall, Map<PVariable, Integer> variableMapping) {
63 CallInformation information = CallInformation.create(pCall, variableMapping, variableBindings.get(pCall));
64 // Use a fixed version of
65 // {@code org.eclipse.viatra.query.runtime.localsearch.operations.extend.ExtendPositivePatternCall} that handles
66 // failed unification of variables correctly.
67 operations.add(new ExtendPositivePatternCall(information));
68 dependencies.add(information.getCallWithAdornment());
69 }
70}
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/AbstractViatraMatcher.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/AbstractViatraMatcher.java
index 99b0a3d8..c4a5a236 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/AbstractViatraMatcher.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/AbstractViatraMatcher.java
@@ -5,8 +5,8 @@
5 */ 5 */
6package tools.refinery.store.query.viatra.internal.matcher; 6package tools.refinery.store.query.viatra.internal.matcher;
7 7
8import org.eclipse.viatra.query.runtime.matchers.backend.IQueryResultProvider; 8import tools.refinery.viatra.runtime.matchers.backend.IQueryResultProvider;
9import org.eclipse.viatra.query.runtime.matchers.backend.IUpdateable; 9import tools.refinery.viatra.runtime.matchers.backend.IUpdateable;
10import tools.refinery.store.query.dnf.Query; 10import tools.refinery.store.query.dnf.Query;
11import tools.refinery.store.query.resultset.AbstractResultSet; 11import tools.refinery.store.query.resultset.AbstractResultSet;
12import tools.refinery.store.query.viatra.internal.ViatraModelQueryAdapterImpl; 12import tools.refinery.store.query.viatra.internal.ViatraModelQueryAdapterImpl;
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/FunctionalCursor.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/FunctionalCursor.java
index 47efb2aa..44038669 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/FunctionalCursor.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/FunctionalCursor.java
@@ -5,7 +5,7 @@
5 */ 5 */
6package tools.refinery.store.query.viatra.internal.matcher; 6package tools.refinery.store.query.viatra.internal.matcher;
7 7
8import org.eclipse.viatra.query.runtime.rete.index.IterableIndexer; 8import tools.refinery.viatra.runtime.rete.index.IterableIndexer;
9import tools.refinery.store.map.Cursor; 9import tools.refinery.store.map.Cursor;
10import tools.refinery.store.tuple.Tuple; 10import tools.refinery.store.tuple.Tuple;
11 11
@@ -13,7 +13,7 @@ import java.util.Iterator;
13 13
14class FunctionalCursor<T> implements Cursor<Tuple, T> { 14class FunctionalCursor<T> implements Cursor<Tuple, T> {
15 private final IterableIndexer indexer; 15 private final IterableIndexer indexer;
16 private final Iterator<org.eclipse.viatra.query.runtime.matchers.tuple.Tuple> iterator; 16 private final Iterator<tools.refinery.viatra.runtime.matchers.tuple.Tuple> iterator;
17 private boolean terminated; 17 private boolean terminated;
18 private Tuple key; 18 private Tuple key;
19 private T value; 19 private T value;
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/FunctionalViatraMatcher.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/FunctionalViatraMatcher.java
index db4740cd..fb9e4df6 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/FunctionalViatraMatcher.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/FunctionalViatraMatcher.java
@@ -5,10 +5,10 @@
5 */ 5 */
6package tools.refinery.store.query.viatra.internal.matcher; 6package tools.refinery.store.query.viatra.internal.matcher;
7 7
8import org.eclipse.viatra.query.runtime.matchers.tuple.TupleMask; 8import tools.refinery.viatra.runtime.matchers.tuple.TupleMask;
9import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; 9import tools.refinery.viatra.runtime.matchers.tuple.Tuples;
10import org.eclipse.viatra.query.runtime.rete.index.IterableIndexer; 10import tools.refinery.viatra.runtime.rete.index.IterableIndexer;
11import org.eclipse.viatra.query.runtime.rete.matcher.RetePatternMatcher; 11import tools.refinery.viatra.runtime.rete.matcher.RetePatternMatcher;
12import tools.refinery.store.map.Cursor; 12import tools.refinery.store.map.Cursor;
13import tools.refinery.store.query.dnf.FunctionalQuery; 13import tools.refinery.store.query.dnf.FunctionalQuery;
14import tools.refinery.store.query.viatra.internal.ViatraModelQueryAdapterImpl; 14import tools.refinery.store.query.viatra.internal.ViatraModelQueryAdapterImpl;
@@ -17,9 +17,9 @@ import tools.refinery.store.tuple.Tuple;
17/** 17/**
18 * Directly access the tuples inside a VIATRA pattern matcher.<p> 18 * Directly access the tuples inside a VIATRA pattern matcher.<p>
19 * This class neglects calling 19 * This class neglects calling
20 * {@link org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContext#wrapTuple(org.eclipse.viatra.query.runtime.matchers.tuple.Tuple)} 20 * {@link tools.refinery.viatra.runtime.matchers.context.IQueryRuntimeContext#wrapTuple(org.eclipse.viatra.query.runtime.matchers.tuple.Tuple)}
21 * and 21 * and
22 * {@link org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContext#unwrapTuple(org.eclipse.viatra.query.runtime.matchers.tuple.Tuple)}, 22 * {@link tools.refinery.viatra.runtime.matchers.context.IQueryRuntimeContext#unwrapTuple(org.eclipse.viatra.query.runtime.matchers.tuple.Tuple)},
23 * because {@link tools.refinery.store.query.viatra.internal.context.RelationalRuntimeContext} provides a trivial 23 * because {@link tools.refinery.store.query.viatra.internal.context.RelationalRuntimeContext} provides a trivial
24 * implementation for these methods. 24 * implementation for these methods.
25 * Using this class with any other runtime context may lead to undefined behavior. 25 * Using this class with any other runtime context may lead to undefined behavior.
@@ -37,7 +37,7 @@ public class FunctionalViatraMatcher<T> extends AbstractViatraMatcher<T> {
37 emptyMask = TupleMask.empty(arityWithOutput); 37 emptyMask = TupleMask.empty(arityWithOutput);
38 omitOutputMask = TupleMask.omit(arity, arityWithOutput); 38 omitOutputMask = TupleMask.omit(arity, arityWithOutput);
39 if (backend instanceof RetePatternMatcher reteBackend) { 39 if (backend instanceof RetePatternMatcher reteBackend) {
40 var maybeIterableOmitOutputIndexer = IndexerUtils.getIndexer(reteBackend, omitOutputMask); 40 var maybeIterableOmitOutputIndexer = reteBackend.getInternalIndexer(omitOutputMask);
41 if (maybeIterableOmitOutputIndexer instanceof IterableIndexer iterableOmitOutputIndexer) { 41 if (maybeIterableOmitOutputIndexer instanceof IterableIndexer iterableOmitOutputIndexer) {
42 omitOutputIndexer = iterableOmitOutputIndexer; 42 omitOutputIndexer = iterableOmitOutputIndexer;
43 } else { 43 } else {
@@ -76,7 +76,7 @@ public class FunctionalViatraMatcher<T> extends AbstractViatraMatcher<T> {
76 } 76 }
77 77
78 @Override 78 @Override
79 public void update(org.eclipse.viatra.query.runtime.matchers.tuple.Tuple updateElement, boolean isInsertion) { 79 public void update(tools.refinery.viatra.runtime.matchers.tuple.Tuple updateElement, boolean isInsertion) {
80 var key = MatcherUtils.keyToRefineryTuple(updateElement); 80 var key = MatcherUtils.keyToRefineryTuple(updateElement);
81 var value = MatcherUtils.<T>getValue(updateElement); 81 var value = MatcherUtils.<T>getValue(updateElement);
82 if (isInsertion) { 82 if (isInsertion) {
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/IndexerUtils.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/IndexerUtils.java
deleted file mode 100644
index 15f00b2d..00000000
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/IndexerUtils.java
+++ /dev/null
@@ -1,53 +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.query.viatra.internal.matcher;
7
8import org.eclipse.viatra.query.runtime.matchers.tuple.TupleMask;
9import org.eclipse.viatra.query.runtime.rete.index.Indexer;
10import org.eclipse.viatra.query.runtime.rete.matcher.ReteEngine;
11import org.eclipse.viatra.query.runtime.rete.matcher.RetePatternMatcher;
12import org.eclipse.viatra.query.runtime.rete.traceability.RecipeTraceInfo;
13
14import java.lang.invoke.MethodHandle;
15import java.lang.invoke.MethodHandles;
16import java.lang.invoke.MethodType;
17
18final class IndexerUtils {
19 private static final MethodHandle GET_ENGINE_HANDLE;
20 private static final MethodHandle GET_PRODUCTION_NODE_TRACE_HANDLE;
21 private static final MethodHandle ACCESS_PROJECTION_HANDLE;
22
23 static {
24 try {
25 var lookup = MethodHandles.privateLookupIn(RetePatternMatcher.class, MethodHandles.lookup());
26 GET_ENGINE_HANDLE = lookup.findGetter(RetePatternMatcher.class, "engine", ReteEngine.class);
27 GET_PRODUCTION_NODE_TRACE_HANDLE = lookup.findGetter(RetePatternMatcher.class, "productionNodeTrace",
28 RecipeTraceInfo.class);
29 ACCESS_PROJECTION_HANDLE = lookup.findVirtual(ReteEngine.class, "accessProjection",
30 MethodType.methodType(Indexer.class, RecipeTraceInfo.class, TupleMask.class));
31 } catch (IllegalAccessException | NoSuchFieldException | NoSuchMethodException e) {
32 throw new IllegalStateException("Cannot access private members of %s"
33 .formatted(RetePatternMatcher.class.getPackageName()), e);
34 }
35 }
36
37 private IndexerUtils() {
38 throw new IllegalStateException("This is a static utility class and should not be instantiated directly");
39 }
40
41 public static Indexer getIndexer(RetePatternMatcher backend, TupleMask mask) {
42 try {
43 var engine = (ReteEngine) GET_ENGINE_HANDLE.invokeExact(backend);
44 var trace = (RecipeTraceInfo) GET_PRODUCTION_NODE_TRACE_HANDLE.invokeExact(backend);
45 return (Indexer) ACCESS_PROJECTION_HANDLE.invokeExact(engine, trace, mask);
46 } catch (Error e) {
47 // Fatal JVM errors should not be wrapped.
48 throw e;
49 } catch (Throwable e) {
50 throw new IllegalStateException("Cannot access matcher for mask " + mask, e);
51 }
52 }
53}
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/MatcherUtils.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/MatcherUtils.java
index 6e24812a..6cda23cd 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/MatcherUtils.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/MatcherUtils.java
@@ -5,8 +5,8 @@
5 */ 5 */
6package tools.refinery.store.query.viatra.internal.matcher; 6package tools.refinery.store.query.viatra.internal.matcher;
7 7
8import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; 8import tools.refinery.viatra.runtime.matchers.tuple.ITuple;
9import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; 9import tools.refinery.viatra.runtime.matchers.tuple.Tuples;
10import org.jetbrains.annotations.Nullable; 10import org.jetbrains.annotations.Nullable;
11import tools.refinery.store.tuple.*; 11import tools.refinery.store.tuple.*;
12 12
@@ -17,7 +17,7 @@ final class MatcherUtils {
17 throw new IllegalStateException("This is a static utility class and should not be instantiated directly"); 17 throw new IllegalStateException("This is a static utility class and should not be instantiated directly");
18 } 18 }
19 19
20 public static org.eclipse.viatra.query.runtime.matchers.tuple.Tuple toViatraTuple(Tuple refineryTuple) { 20 public static tools.refinery.viatra.runtime.matchers.tuple.Tuple toViatraTuple(Tuple refineryTuple) {
21 if (refineryTuple instanceof Tuple0) { 21 if (refineryTuple instanceof Tuple0) {
22 return Tuples.staticArityFlatTupleOf(); 22 return Tuples.staticArityFlatTupleOf();
23 } else if (refineryTuple instanceof Tuple1) { 23 } else if (refineryTuple instanceof Tuple1) {
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/RawPatternMatcher.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/RawPatternMatcher.java
index 5b82c4b7..c0be70ba 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/RawPatternMatcher.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/RawPatternMatcher.java
@@ -5,9 +5,9 @@
5 */ 5 */
6package tools.refinery.store.query.viatra.internal.matcher; 6package tools.refinery.store.query.viatra.internal.matcher;
7 7
8import org.eclipse.viatra.query.runtime.api.GenericPatternMatcher; 8import tools.refinery.viatra.runtime.api.GenericPatternMatcher;
9import org.eclipse.viatra.query.runtime.api.GenericQuerySpecification; 9import tools.refinery.viatra.runtime.api.GenericQuerySpecification;
10import org.eclipse.viatra.query.runtime.matchers.backend.IQueryResultProvider; 10import tools.refinery.viatra.runtime.matchers.backend.IQueryResultProvider;
11 11
12public class RawPatternMatcher extends GenericPatternMatcher { 12public class RawPatternMatcher extends GenericPatternMatcher {
13 public RawPatternMatcher(GenericQuerySpecification<? extends GenericPatternMatcher> specification) { 13 public RawPatternMatcher(GenericQuerySpecification<? extends GenericPatternMatcher> specification) {
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/RelationalCursor.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/RelationalCursor.java
index 1dc8f5db..53475218 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/RelationalCursor.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/RelationalCursor.java
@@ -5,7 +5,7 @@
5 */ 5 */
6package tools.refinery.store.query.viatra.internal.matcher; 6package tools.refinery.store.query.viatra.internal.matcher;
7 7
8import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; 8import tools.refinery.viatra.runtime.matchers.tuple.ITuple;
9import tools.refinery.store.map.Cursor; 9import tools.refinery.store.map.Cursor;
10import tools.refinery.store.tuple.Tuple; 10import tools.refinery.store.tuple.Tuple;
11 11
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/RelationalViatraMatcher.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/RelationalViatraMatcher.java
index ac95dcc0..da75e864 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/RelationalViatraMatcher.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/RelationalViatraMatcher.java
@@ -5,10 +5,10 @@
5 */ 5 */
6package tools.refinery.store.query.viatra.internal.matcher; 6package tools.refinery.store.query.viatra.internal.matcher;
7 7
8import org.eclipse.viatra.query.runtime.matchers.tuple.TupleMask; 8import tools.refinery.viatra.runtime.matchers.tuple.TupleMask;
9import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; 9import tools.refinery.viatra.runtime.matchers.tuple.Tuples;
10import org.eclipse.viatra.query.runtime.rete.index.Indexer; 10import tools.refinery.viatra.runtime.rete.index.Indexer;
11import org.eclipse.viatra.query.runtime.rete.matcher.RetePatternMatcher; 11import tools.refinery.viatra.runtime.rete.matcher.RetePatternMatcher;
12import tools.refinery.store.map.Cursor; 12import tools.refinery.store.map.Cursor;
13import tools.refinery.store.map.Cursors; 13import tools.refinery.store.map.Cursors;
14import tools.refinery.store.query.dnf.RelationalQuery; 14import tools.refinery.store.query.dnf.RelationalQuery;
@@ -18,9 +18,9 @@ import tools.refinery.store.tuple.Tuple;
18/** 18/**
19 * Directly access the tuples inside a VIATRA pattern matcher.<p> 19 * Directly access the tuples inside a VIATRA pattern matcher.<p>
20 * This class neglects calling 20 * This class neglects calling
21 * {@link org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContext#wrapTuple(org.eclipse.viatra.query.runtime.matchers.tuple.Tuple)} 21 * {@link tools.refinery.viatra.runtime.matchers.context.IQueryRuntimeContext#wrapTuple(org.eclipse.viatra.query.runtime.matchers.tuple.Tuple)}
22 * and 22 * and
23 * {@link org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContext#unwrapTuple(org.eclipse.viatra.query.runtime.matchers.tuple.Tuple)}, 23 * {@link tools.refinery.viatra.runtime.matchers.context.IQueryRuntimeContext#unwrapTuple(org.eclipse.viatra.query.runtime.matchers.tuple.Tuple)},
24 * because {@link tools.refinery.store.query.viatra.internal.context.RelationalRuntimeContext} provides a trivial 24 * because {@link tools.refinery.store.query.viatra.internal.context.RelationalRuntimeContext} provides a trivial
25 * implementation for these methods. 25 * implementation for these methods.
26 * Using this class with any other runtime context may lead to undefined behavior. 26 * Using this class with any other runtime context may lead to undefined behavior.
@@ -37,7 +37,7 @@ public class RelationalViatraMatcher extends AbstractViatraMatcher<Boolean> {
37 emptyMask = TupleMask.empty(arity); 37 emptyMask = TupleMask.empty(arity);
38 identityMask = TupleMask.identity(arity); 38 identityMask = TupleMask.identity(arity);
39 if (backend instanceof RetePatternMatcher reteBackend) { 39 if (backend instanceof RetePatternMatcher reteBackend) {
40 emptyMaskIndexer = IndexerUtils.getIndexer(reteBackend, emptyMask); 40 emptyMaskIndexer = reteBackend.getInternalIndexer(emptyMask);
41 } else { 41 } else {
42 emptyMaskIndexer = null; 42 emptyMaskIndexer = null;
43 } 43 }
@@ -73,7 +73,7 @@ public class RelationalViatraMatcher extends AbstractViatraMatcher<Boolean> {
73 } 73 }
74 74
75 @Override 75 @Override
76 public void update(org.eclipse.viatra.query.runtime.matchers.tuple.Tuple updateElement, boolean isInsertion) { 76 public void update(tools.refinery.viatra.runtime.matchers.tuple.Tuple updateElement, boolean isInsertion) {
77 var key = MatcherUtils.toRefineryTuple(updateElement); 77 var key = MatcherUtils.toRefineryTuple(updateElement);
78 notifyChange(key, !isInsertion, isInsertion); 78 notifyChange(key, !isInsertion, isInsertion);
79 } 79 }
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/UnsafeFunctionalCursor.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/UnsafeFunctionalCursor.java
index b0b507fe..093ade96 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/UnsafeFunctionalCursor.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/matcher/UnsafeFunctionalCursor.java
@@ -5,7 +5,7 @@
5 */ 5 */
6package tools.refinery.store.query.viatra.internal.matcher; 6package tools.refinery.store.query.viatra.internal.matcher;
7 7
8import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; 8import tools.refinery.viatra.runtime.matchers.tuple.ITuple;
9import tools.refinery.store.map.Cursor; 9import tools.refinery.store.map.Cursor;
10import tools.refinery.store.tuple.Tuple; 10import tools.refinery.store.tuple.Tuple;
11 11
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/AssumptionEvaluator.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/CheckEvaluator.java
index cf127291..ada154d4 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/AssumptionEvaluator.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/CheckEvaluator.java
@@ -5,11 +5,11 @@
5 */ 5 */
6package tools.refinery.store.query.viatra.internal.pquery; 6package tools.refinery.store.query.viatra.internal.pquery;
7 7
8import org.eclipse.viatra.query.runtime.matchers.psystem.IValueProvider; 8import tools.refinery.viatra.runtime.matchers.psystem.IValueProvider;
9import tools.refinery.store.query.term.Term; 9import tools.refinery.store.query.term.Term;
10 10
11class AssumptionEvaluator extends TermEvaluator<Boolean> { 11class CheckEvaluator extends TermEvaluator<Boolean> {
12 public AssumptionEvaluator(Term<Boolean> term) { 12 public CheckEvaluator(Term<Boolean> term) {
13 super(term); 13 super(term);
14 } 14 }
15 15
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/Dnf2PQuery.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/Dnf2PQuery.java
index 5b0ea61d..492bd054 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/Dnf2PQuery.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/Dnf2PQuery.java
@@ -5,24 +5,7 @@
5 */ 5 */
6package tools.refinery.store.query.viatra.internal.pquery; 6package tools.refinery.store.query.viatra.internal.pquery;
7 7
8import org.eclipse.viatra.query.runtime.matchers.backend.IQueryBackendFactory; 8import tools.refinery.store.query.Constraint;
9import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint;
10import org.eclipse.viatra.query.runtime.matchers.context.IInputKey;
11import org.eclipse.viatra.query.runtime.matchers.psystem.PBody;
12import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable;
13import org.eclipse.viatra.query.runtime.matchers.psystem.aggregations.BoundAggregator;
14import org.eclipse.viatra.query.runtime.matchers.psystem.aggregations.IMultisetAggregationOperator;
15import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation;
16import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.*;
17import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.BinaryTransitiveClosure;
18import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.ConstantValue;
19import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall;
20import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint;
21import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter;
22import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection;
23import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery;
24import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple;
25import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples;
26import tools.refinery.store.query.dnf.Dnf; 9import tools.refinery.store.query.dnf.Dnf;
27import tools.refinery.store.query.dnf.DnfClause; 10import tools.refinery.store.query.dnf.DnfClause;
28import tools.refinery.store.query.dnf.SymbolicParameter; 11import tools.refinery.store.query.dnf.SymbolicParameter;
@@ -33,17 +16,33 @@ import tools.refinery.store.query.term.StatelessAggregator;
33import tools.refinery.store.query.term.Variable; 16import tools.refinery.store.query.term.Variable;
34import tools.refinery.store.query.view.AnySymbolView; 17import tools.refinery.store.query.view.AnySymbolView;
35import tools.refinery.store.util.CycleDetectingMapper; 18import tools.refinery.store.util.CycleDetectingMapper;
36 19import tools.refinery.viatra.runtime.matchers.backend.IQueryBackendFactory;
37import java.util.*; 20import tools.refinery.viatra.runtime.matchers.backend.QueryEvaluationHint;
21import tools.refinery.viatra.runtime.matchers.context.IInputKey;
22import tools.refinery.viatra.runtime.matchers.psystem.PBody;
23import tools.refinery.viatra.runtime.matchers.psystem.PVariable;
24import tools.refinery.viatra.runtime.matchers.psystem.aggregations.BoundAggregator;
25import tools.refinery.viatra.runtime.matchers.psystem.aggregations.IMultisetAggregationOperator;
26import tools.refinery.viatra.runtime.matchers.psystem.annotations.PAnnotation;
27import tools.refinery.viatra.runtime.matchers.psystem.basicdeferred.*;
28import tools.refinery.viatra.runtime.matchers.psystem.basicenumerables.*;
29import tools.refinery.viatra.runtime.matchers.psystem.basicenumerables.Connectivity;
30import tools.refinery.viatra.runtime.matchers.psystem.queries.PParameter;
31import tools.refinery.viatra.runtime.matchers.psystem.queries.PParameterDirection;
32import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery;
33import tools.refinery.viatra.runtime.matchers.tuple.Tuple;
34import tools.refinery.viatra.runtime.matchers.tuple.Tuples;
35
36import java.util.ArrayList;
37import java.util.HashMap;
38import java.util.List;
39import java.util.Map;
38import java.util.function.Function; 40import java.util.function.Function;
39import java.util.stream.Collectors;
40 41
41public class Dnf2PQuery { 42public class Dnf2PQuery {
42 private static final Object P_CONSTRAINT_LOCK = new Object();
43 private final CycleDetectingMapper<Dnf, RawPQuery> mapper = new CycleDetectingMapper<>(Dnf::name, 43 private final CycleDetectingMapper<Dnf, RawPQuery> mapper = new CycleDetectingMapper<>(Dnf::name,
44 this::doTranslate); 44 this::doTranslate);
45 private final QueryWrapperFactory wrapperFactory = new QueryWrapperFactory(this); 45 private final QueryWrapperFactory wrapperFactory = new QueryWrapperFactory(this);
46 private final Map<Dnf, QueryEvaluationHint> hintOverrides = new LinkedHashMap<>();
47 private Function<Dnf, QueryEvaluationHint> computeHint = dnf -> new QueryEvaluationHint(null, 46 private Function<Dnf, QueryEvaluationHint> computeHint = dnf -> new QueryEvaluationHint(null,
48 (IQueryBackendFactory) null); 47 (IQueryBackendFactory) null);
49 48
@@ -59,36 +58,15 @@ public class Dnf2PQuery {
59 return wrapperFactory.getSymbolViews(); 58 return wrapperFactory.getSymbolViews();
60 } 59 }
61 60
62 public void hint(Dnf dnf, QueryEvaluationHint hint) {
63 hintOverrides.compute(dnf, (ignoredKey, existingHint) ->
64 existingHint == null ? hint : existingHint.overrideBy(hint));
65 }
66
67 private QueryEvaluationHint consumeHint(Dnf dnf) {
68 var defaultHint = computeHint.apply(dnf);
69 var existingHint = hintOverrides.remove(dnf);
70 return defaultHint.overrideBy(existingHint);
71 }
72
73 public void assertNoUnusedHints() {
74 if (hintOverrides.isEmpty()) {
75 return;
76 }
77 var unusedHints = hintOverrides.keySet().stream().map(Dnf::name).collect(Collectors.joining(", "));
78 throw new IllegalStateException(
79 "Unused query evaluation hints for %s. Hints must be set before a query is added to the engine"
80 .formatted(unusedHints));
81 }
82
83 private RawPQuery doTranslate(Dnf dnfQuery) { 61 private RawPQuery doTranslate(Dnf dnfQuery) {
84 var pQuery = new RawPQuery(dnfQuery.getUniqueName()); 62 var pQuery = new RawPQuery(dnfQuery.getUniqueName());
85 pQuery.setEvaluationHints(consumeHint(dnfQuery)); 63 pQuery.setEvaluationHints(computeHint.apply(dnfQuery));
86 64
87 Map<SymbolicParameter, PParameter> parameters = new HashMap<>(); 65 Map<SymbolicParameter, PParameter> parameters = new HashMap<>();
88 List<PParameter> parameterList = new ArrayList<>(); 66 List<PParameter> parameterList = new ArrayList<>();
89 for (var parameter : dnfQuery.getSymbolicParameters()) { 67 for (var parameter : dnfQuery.getSymbolicParameters()) {
90 var direction = switch (parameter.getDirection()) { 68 var direction = switch (parameter.getDirection()) {
91 case OUT -> parameter.isUnifiable() ? PParameterDirection.INOUT : PParameterDirection.OUT; 69 case OUT -> PParameterDirection.INOUT;
92 case IN -> throw new IllegalArgumentException("Query %s with input parameter %s is not supported" 70 case IN -> throw new IllegalArgumentException("Query %s with input parameter %s is not supported"
93 .formatted(dnfQuery, parameter.getVariable())); 71 .formatted(dnfQuery, parameter.getVariable()));
94 }; 72 };
@@ -110,22 +88,17 @@ public class Dnf2PQuery {
110 pQuery.addAnnotation(functionalDependencyAnnotation); 88 pQuery.addAnnotation(functionalDependencyAnnotation);
111 } 89 }
112 90
113 // The constructor of {@link org.eclipse.viatra.query.runtime.matchers.psystem.BasePConstraint} mutates 91 for (DnfClause clause : dnfQuery.getClauses()) {
114 // global static state (<code>nextID</code>) without locking. Therefore, we need to synchronize before creating 92 PBody body = new PBody(pQuery);
115 // any query literals to avoid a data race. 93 List<ExportedParameter> parameterExports = new ArrayList<>();
116 synchronized (P_CONSTRAINT_LOCK) { 94 for (var parameter : dnfQuery.getSymbolicParameters()) {
117 for (DnfClause clause : dnfQuery.getClauses()) { 95 PVariable pVar = body.getOrCreateVariableByName(parameter.getVariable().getUniqueName());
118 PBody body = new PBody(pQuery); 96 parameterExports.add(new ExportedParameter(body, pVar, parameters.get(parameter)));
119 List<ExportedParameter> parameterExports = new ArrayList<>(); 97 }
120 for (var parameter : dnfQuery.getSymbolicParameters()) { 98 body.setSymbolicParameters(parameterExports);
121 PVariable pVar = body.getOrCreateVariableByName(parameter.getVariable().getUniqueName()); 99 pQuery.addBody(body);
122 parameterExports.add(new ExportedParameter(body, pVar, parameters.get(parameter))); 100 for (Literal literal : clause.literals()) {
123 } 101 translateLiteral(literal, body);
124 body.setSymbolicParameters(parameterExports);
125 pQuery.addBody(body);
126 for (Literal literal : clause.literals()) {
127 translateLiteral(literal, body);
128 }
129 } 102 }
130 } 103 }
131 104
@@ -141,21 +114,23 @@ public class Dnf2PQuery {
141 translateConstantLiteral(constantLiteral, body); 114 translateConstantLiteral(constantLiteral, body);
142 } else if (literal instanceof AssignLiteral<?> assignLiteral) { 115 } else if (literal instanceof AssignLiteral<?> assignLiteral) {
143 translateAssignLiteral(assignLiteral, body); 116 translateAssignLiteral(assignLiteral, body);
144 } else if (literal instanceof AssumeLiteral assumeLiteral) { 117 } else if (literal instanceof CheckLiteral checkLiteral) {
145 translateAssumeLiteral(assumeLiteral, body); 118 translateCheckLiteral(checkLiteral, body);
146 } else if (literal instanceof CountLiteral countLiteral) { 119 } else if (literal instanceof CountLiteral countLiteral) {
147 translateCountLiteral(countLiteral, body); 120 translateCountLiteral(countLiteral, body);
148 } else if (literal instanceof AggregationLiteral<?, ?> aggregationLiteral) { 121 } else if (literal instanceof AggregationLiteral<?, ?> aggregationLiteral) {
149 translateAggregationLiteral(aggregationLiteral, body); 122 translateAggregationLiteral(aggregationLiteral, body);
123 } else if (literal instanceof RepresentativeElectionLiteral representativeElectionLiteral) {
124 translateRepresentativeElectionLiteral(representativeElectionLiteral, body);
150 } else { 125 } else {
151 throw new IllegalArgumentException("Unknown literal: " + literal.toString()); 126 throw new IllegalArgumentException("Unknown literal: " + literal.toString());
152 } 127 }
153 } 128 }
154 129
155 private void translateEquivalenceLiteral(EquivalenceLiteral equivalenceLiteral, PBody body) { 130 private void translateEquivalenceLiteral(EquivalenceLiteral equivalenceLiteral, PBody body) {
156 PVariable varSource = body.getOrCreateVariableByName(equivalenceLiteral.left().getUniqueName()); 131 PVariable varSource = body.getOrCreateVariableByName(equivalenceLiteral.getLeft().getUniqueName());
157 PVariable varTarget = body.getOrCreateVariableByName(equivalenceLiteral.right().getUniqueName()); 132 PVariable varTarget = body.getOrCreateVariableByName(equivalenceLiteral.getRight().getUniqueName());
158 if (equivalenceLiteral.positive()) { 133 if (equivalenceLiteral.isPositive()) {
159 new Equality(body, varSource, varTarget); 134 new Equality(body, varSource, varTarget);
160 } else { 135 } else {
161 new Inequality(body, varSource, varTarget); 136 new Inequality(body, varSource, varTarget);
@@ -180,15 +155,7 @@ public class Dnf2PQuery {
180 } 155 }
181 case TRANSITIVE -> { 156 case TRANSITIVE -> {
182 var substitution = translateSubstitution(callLiteral.getArguments(), body); 157 var substitution = translateSubstitution(callLiteral.getArguments(), body);
183 var constraint = callLiteral.getTarget(); 158 var pattern = wrapConstraintWithIdentityArguments(callLiteral.getTarget());
184 PQuery pattern;
185 if (constraint instanceof Dnf dnf) {
186 pattern = translate(dnf);
187 } else if (constraint instanceof AnySymbolView symbolView) {
188 pattern = wrapperFactory.wrapSymbolViewIdentityArguments(symbolView);
189 } else {
190 throw new IllegalArgumentException("Unknown Constraint: " + constraint);
191 }
192 new BinaryTransitiveClosure(body, substitution, pattern); 159 new BinaryTransitiveClosure(body, substitution, pattern);
193 } 160 }
194 case NEGATIVE -> { 161 case NEGATIVE -> {
@@ -201,6 +168,16 @@ public class Dnf2PQuery {
201 } 168 }
202 } 169 }
203 170
171 private PQuery wrapConstraintWithIdentityArguments(Constraint constraint) {
172 if (constraint instanceof Dnf dnf) {
173 return translate(dnf);
174 } else if (constraint instanceof AnySymbolView symbolView) {
175 return wrapperFactory.wrapSymbolViewIdentityArguments(symbolView);
176 } else {
177 throw new IllegalArgumentException("Unknown Constraint: " + constraint);
178 }
179 }
180
204 private static Tuple translateSubstitution(List<Variable> substitution, PBody body) { 181 private static Tuple translateSubstitution(List<Variable> substitution, PBody body) {
205 int arity = substitution.size(); 182 int arity = substitution.size();
206 Object[] variables = new Object[arity]; 183 Object[] variables = new Object[arity];
@@ -212,13 +189,13 @@ public class Dnf2PQuery {
212 } 189 }
213 190
214 private void translateConstantLiteral(ConstantLiteral constantLiteral, PBody body) { 191 private void translateConstantLiteral(ConstantLiteral constantLiteral, PBody body) {
215 var variable = body.getOrCreateVariableByName(constantLiteral.variable().getUniqueName()); 192 var variable = body.getOrCreateVariableByName(constantLiteral.getVariable().getUniqueName());
216 new ConstantValue(body, variable, constantLiteral.nodeId()); 193 new ConstantValue(body, variable, tools.refinery.store.tuple.Tuple.of(constantLiteral.getNodeId()));
217 } 194 }
218 195
219 private <T> void translateAssignLiteral(AssignLiteral<T> assignLiteral, PBody body) { 196 private <T> void translateAssignLiteral(AssignLiteral<T> assignLiteral, PBody body) {
220 var variable = body.getOrCreateVariableByName(assignLiteral.variable().getUniqueName()); 197 var variable = body.getOrCreateVariableByName(assignLiteral.getVariable().getUniqueName());
221 var term = assignLiteral.term(); 198 var term = assignLiteral.getTerm();
222 if (term instanceof ConstantTerm<T> constantTerm) { 199 if (term instanceof ConstantTerm<T> constantTerm) {
223 new ConstantValue(body, variable, constantTerm.getValue()); 200 new ConstantValue(body, variable, constantTerm.getValue());
224 } else { 201 } else {
@@ -227,8 +204,8 @@ public class Dnf2PQuery {
227 } 204 }
228 } 205 }
229 206
230 private void translateAssumeLiteral(AssumeLiteral assumeLiteral, PBody body) { 207 private void translateCheckLiteral(CheckLiteral checkLiteral, PBody body) {
231 var evaluator = new AssumptionEvaluator(assumeLiteral.term()); 208 var evaluator = new CheckEvaluator(checkLiteral.getTerm());
232 new ExpressionEvaluation(body, evaluator, null); 209 new ExpressionEvaluation(body, evaluator, null);
233 } 210 }
234 211
@@ -263,4 +240,14 @@ public class Dnf2PQuery {
263 new AggregatorConstraint(boundAggregator, body, substitution, wrappedCall.pattern(), resultVariable, 240 new AggregatorConstraint(boundAggregator, body, substitution, wrappedCall.pattern(), resultVariable,
264 aggregatedColumn); 241 aggregatedColumn);
265 } 242 }
243
244 private void translateRepresentativeElectionLiteral(RepresentativeElectionLiteral literal, PBody body) {
245 var substitution = translateSubstitution(literal.getArguments(), body);
246 var pattern = wrapConstraintWithIdentityArguments(literal.getTarget());
247 var connectivity = switch (literal.getConnectivity()) {
248 case WEAK -> Connectivity.WEAK;
249 case STRONG -> Connectivity.STRONG;
250 };
251 new RepresentativeElectionConstraint(body, substitution, pattern, connectivity);
252 }
266} 253}
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/QueryWrapperFactory.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/QueryWrapperFactory.java
index 2b7280f2..d21131e5 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/QueryWrapperFactory.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/QueryWrapperFactory.java
@@ -5,17 +5,17 @@
5 */ 5 */
6package tools.refinery.store.query.viatra.internal.pquery; 6package tools.refinery.store.query.viatra.internal.pquery;
7 7
8import org.eclipse.viatra.query.runtime.matchers.context.IInputKey; 8import tools.refinery.viatra.runtime.matchers.context.IInputKey;
9import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; 9import tools.refinery.viatra.runtime.matchers.psystem.PBody;
10import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; 10import tools.refinery.viatra.runtime.matchers.psystem.PVariable;
11import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; 11import tools.refinery.viatra.runtime.matchers.psystem.basicdeferred.ExportedParameter;
12import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall; 12import tools.refinery.viatra.runtime.matchers.psystem.basicenumerables.PositivePatternCall;
13import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; 13import tools.refinery.viatra.runtime.matchers.psystem.basicenumerables.TypeConstraint;
14import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; 14import tools.refinery.viatra.runtime.matchers.psystem.queries.PParameter;
15import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PQuery; 15import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery;
16import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; 16import tools.refinery.viatra.runtime.matchers.psystem.queries.PVisibility;
17import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; 17import tools.refinery.viatra.runtime.matchers.tuple.Tuple;
18import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; 18import tools.refinery.viatra.runtime.matchers.tuple.Tuples;
19import tools.refinery.store.query.Constraint; 19import tools.refinery.store.query.Constraint;
20import tools.refinery.store.query.dnf.Dnf; 20import tools.refinery.store.query.dnf.Dnf;
21import tools.refinery.store.query.dnf.DnfUtils; 21import tools.refinery.store.query.dnf.DnfUtils;
@@ -33,7 +33,7 @@ class QueryWrapperFactory {
33 private final Dnf2PQuery dnf2PQuery; 33 private final Dnf2PQuery dnf2PQuery;
34 private final Map<AnySymbolView, SymbolViewWrapper> view2WrapperMap = new LinkedHashMap<>(); 34 private final Map<AnySymbolView, SymbolViewWrapper> view2WrapperMap = new LinkedHashMap<>();
35 private final CycleDetectingMapper<RemappedConstraint, RawPQuery> wrapConstraint = new CycleDetectingMapper<>( 35 private final CycleDetectingMapper<RemappedConstraint, RawPQuery> wrapConstraint = new CycleDetectingMapper<>(
36 RemappedConstraint::toString, this::doWrapConstraint); 36 this::doWrapConstraint);
37 37
38 QueryWrapperFactory(Dnf2PQuery dnf2PQuery) { 38 QueryWrapperFactory(Dnf2PQuery dnf2PQuery) {
39 this.dnf2PQuery = dnf2PQuery; 39 this.dnf2PQuery = dnf2PQuery;
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/RawPQuery.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/RawPQuery.java
index 255738c5..06644bf2 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/RawPQuery.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/RawPQuery.java
@@ -5,14 +5,14 @@
5 */ 5 */
6package tools.refinery.store.query.viatra.internal.pquery; 6package tools.refinery.store.query.viatra.internal.pquery;
7 7
8import org.eclipse.viatra.query.runtime.api.GenericQuerySpecification; 8import tools.refinery.viatra.runtime.api.GenericQuerySpecification;
9import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; 9import tools.refinery.viatra.runtime.api.ViatraQueryEngine;
10import org.eclipse.viatra.query.runtime.api.scope.QueryScope; 10import tools.refinery.viatra.runtime.api.scope.QueryScope;
11import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; 11import tools.refinery.viatra.runtime.matchers.psystem.PBody;
12import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; 12import tools.refinery.viatra.runtime.matchers.psystem.annotations.PAnnotation;
13import org.eclipse.viatra.query.runtime.matchers.psystem.queries.BasePQuery; 13import tools.refinery.viatra.runtime.matchers.psystem.queries.BasePQuery;
14import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; 14import tools.refinery.viatra.runtime.matchers.psystem.queries.PParameter;
15import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; 15import tools.refinery.viatra.runtime.matchers.psystem.queries.PVisibility;
16import tools.refinery.store.query.viatra.internal.RelationalScope; 16import tools.refinery.store.query.viatra.internal.RelationalScope;
17import tools.refinery.store.query.viatra.internal.matcher.RawPatternMatcher; 17import tools.refinery.store.query.viatra.internal.matcher.RawPatternMatcher;
18 18
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/StatefulMultisetAggregator.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/StatefulMultisetAggregator.java
index 461416f7..ba99cf9a 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/StatefulMultisetAggregator.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/StatefulMultisetAggregator.java
@@ -5,7 +5,7 @@
5 */ 5 */
6package tools.refinery.store.query.viatra.internal.pquery; 6package tools.refinery.store.query.viatra.internal.pquery;
7 7
8import org.eclipse.viatra.query.runtime.matchers.psystem.aggregations.IMultisetAggregationOperator; 8import tools.refinery.viatra.runtime.matchers.psystem.aggregations.IMultisetAggregationOperator;
9import tools.refinery.store.query.term.StatefulAggregate; 9import tools.refinery.store.query.term.StatefulAggregate;
10import tools.refinery.store.query.term.StatefulAggregator; 10import tools.refinery.store.query.term.StatefulAggregator;
11 11
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/StatelessMultisetAggregator.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/StatelessMultisetAggregator.java
index 49175d75..bf2c2f4f 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/StatelessMultisetAggregator.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/StatelessMultisetAggregator.java
@@ -5,7 +5,7 @@
5 */ 5 */
6package tools.refinery.store.query.viatra.internal.pquery; 6package tools.refinery.store.query.viatra.internal.pquery;
7 7
8import org.eclipse.viatra.query.runtime.matchers.psystem.aggregations.IMultisetAggregationOperator; 8import tools.refinery.viatra.runtime.matchers.psystem.aggregations.IMultisetAggregationOperator;
9import tools.refinery.store.query.term.StatelessAggregator; 9import tools.refinery.store.query.term.StatelessAggregator;
10 10
11import java.util.stream.Stream; 11import java.util.stream.Stream;
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/SymbolViewWrapper.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/SymbolViewWrapper.java
index a777613e..a774404e 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/SymbolViewWrapper.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/SymbolViewWrapper.java
@@ -5,7 +5,7 @@
5 */ 5 */
6package tools.refinery.store.query.viatra.internal.pquery; 6package tools.refinery.store.query.viatra.internal.pquery;
7 7
8import org.eclipse.viatra.query.runtime.matchers.context.common.BaseInputKeyWrapper; 8import tools.refinery.viatra.runtime.matchers.context.common.BaseInputKeyWrapper;
9import tools.refinery.store.query.view.AnySymbolView; 9import tools.refinery.store.query.view.AnySymbolView;
10 10
11public class SymbolViewWrapper extends BaseInputKeyWrapper<AnySymbolView> { 11public class SymbolViewWrapper extends BaseInputKeyWrapper<AnySymbolView> {
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 1187f57a..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 */
6package tools.refinery.store.query.viatra.internal.pquery; 6package tools.refinery.store.query.viatra.internal.pquery;
7 7
8import org.eclipse.viatra.query.runtime.matchers.psystem.IExpressionEvaluator;
9import org.eclipse.viatra.query.runtime.matchers.psystem.IValueProvider;
10import tools.refinery.store.query.term.Term; 8import tools.refinery.store.query.term.Term;
11import tools.refinery.store.query.term.Variable; 9import tools.refinery.store.query.term.Variable;
10import tools.refinery.viatra.runtime.matchers.psystem.IExpressionEvaluator;
11import tools.refinery.viatra.runtime.matchers.psystem.IValueProvider;
12 12
13import java.util.stream.Collectors; 13import java.util.stream.Collectors;
14 14
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/ValueProviderBasedValuation.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/ValueProviderBasedValuation.java
index 62cb8b3a..b9ae8ab2 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/ValueProviderBasedValuation.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/ValueProviderBasedValuation.java
@@ -5,7 +5,7 @@
5 */ 5 */
6package tools.refinery.store.query.viatra.internal.pquery; 6package tools.refinery.store.query.viatra.internal.pquery;
7 7
8import org.eclipse.viatra.query.runtime.matchers.psystem.IValueProvider; 8import tools.refinery.viatra.runtime.matchers.psystem.IValueProvider;
9import tools.refinery.store.query.term.DataVariable; 9import tools.refinery.store.query.term.DataVariable;
10import tools.refinery.store.query.valuation.Valuation; 10import tools.refinery.store.query.valuation.Valuation;
11 11
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/update/ModelUpdateListener.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/update/ModelUpdateListener.java
index 986bb0b1..e1bc9efc 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/update/ModelUpdateListener.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/update/ModelUpdateListener.java
@@ -5,9 +5,9 @@
5 */ 5 */
6package tools.refinery.store.query.viatra.internal.update; 6package tools.refinery.store.query.viatra.internal.update;
7 7
8import org.eclipse.viatra.query.runtime.matchers.context.IInputKey; 8import tools.refinery.viatra.runtime.matchers.context.IInputKey;
9import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContextListener; 9import tools.refinery.viatra.runtime.matchers.context.IQueryRuntimeContextListener;
10import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; 10import tools.refinery.viatra.runtime.matchers.tuple.ITuple;
11import tools.refinery.store.query.viatra.internal.ViatraModelQueryAdapterImpl; 11import tools.refinery.store.query.viatra.internal.ViatraModelQueryAdapterImpl;
12import tools.refinery.store.query.view.AnySymbolView; 12import tools.refinery.store.query.view.AnySymbolView;
13import tools.refinery.store.query.view.SymbolView; 13import tools.refinery.store.query.view.SymbolView;
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/update/RelationViewFilter.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/update/RelationViewFilter.java
index efdbfcbe..73c4a3f9 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/update/RelationViewFilter.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/update/RelationViewFilter.java
@@ -5,10 +5,10 @@
5 */ 5 */
6package tools.refinery.store.query.viatra.internal.update; 6package tools.refinery.store.query.viatra.internal.update;
7 7
8import org.eclipse.viatra.query.runtime.matchers.context.IInputKey; 8import tools.refinery.viatra.runtime.matchers.context.IInputKey;
9import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContextListener; 9import tools.refinery.viatra.runtime.matchers.context.IQueryRuntimeContextListener;
10import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; 10import tools.refinery.viatra.runtime.matchers.tuple.ITuple;
11import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; 11import tools.refinery.viatra.runtime.matchers.tuple.Tuple;
12 12
13import java.util.Arrays; 13import java.util.Arrays;
14import java.util.Objects; 14import java.util.Objects;
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/update/SymbolViewUpdateListener.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/update/SymbolViewUpdateListener.java
index f1a2ac7c..d0cdda72 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/update/SymbolViewUpdateListener.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/update/SymbolViewUpdateListener.java
@@ -5,10 +5,10 @@
5 */ 5 */
6package tools.refinery.store.query.viatra.internal.update; 6package tools.refinery.store.query.viatra.internal.update;
7 7
8import org.eclipse.viatra.query.runtime.matchers.context.IInputKey; 8import tools.refinery.viatra.runtime.matchers.context.IInputKey;
9import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContextListener; 9import tools.refinery.viatra.runtime.matchers.context.IQueryRuntimeContextListener;
10import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; 10import tools.refinery.viatra.runtime.matchers.tuple.ITuple;
11import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; 11import tools.refinery.viatra.runtime.matchers.tuple.Tuple;
12import tools.refinery.store.model.Interpretation; 12import tools.refinery.store.model.Interpretation;
13import tools.refinery.store.model.InterpretationListener; 13import tools.refinery.store.model.InterpretationListener;
14import tools.refinery.store.query.viatra.internal.ViatraModelQueryAdapterImpl; 14import tools.refinery.store.query.viatra.internal.ViatraModelQueryAdapterImpl;
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 45d35571..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 */
6package tools.refinery.store.query.viatra.internal.update; 6package tools.refinery.store.query.viatra.internal.update;
7 7
8import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples;
9import tools.refinery.store.model.Interpretation; 8import tools.refinery.store.model.Interpretation;
10import tools.refinery.store.query.viatra.internal.ViatraModelQueryAdapterImpl; 9import tools.refinery.store.query.viatra.internal.ViatraModelQueryAdapterImpl;
11import tools.refinery.store.query.view.SymbolView; 10import tools.refinery.store.query.view.SymbolView;
12import tools.refinery.store.tuple.Tuple; 11import tools.refinery.store.tuple.Tuple;
12import tools.refinery.viatra.runtime.matchers.tuple.Tuples;
13 13
14import java.util.Arrays; 14import 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/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/update/TuplePreservingViewUpdateListener.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/update/TuplePreservingViewUpdateListener.java
index c18dbafb..7dbd50b3 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/update/TuplePreservingViewUpdateListener.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/update/TuplePreservingViewUpdateListener.java
@@ -5,7 +5,7 @@
5 */ 5 */
6package tools.refinery.store.query.viatra.internal.update; 6package tools.refinery.store.query.viatra.internal.update;
7 7
8import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; 8import tools.refinery.viatra.runtime.matchers.tuple.Tuples;
9import tools.refinery.store.model.Interpretation; 9import tools.refinery.store.model.Interpretation;
10import tools.refinery.store.query.viatra.internal.ViatraModelQueryAdapterImpl; 10import tools.refinery.store.query.viatra.internal.ViatraModelQueryAdapterImpl;
11import tools.refinery.store.query.view.TuplePreservingView; 11import tools.refinery.store.query.view.TuplePreservingView;