aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store-query-viatra
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2023-02-02 16:33:45 +0100
committerLibravatar Kristóf Marussy <kristof@marussy.com>2023-02-02 16:33:45 +0100
commita69beacc266ba4462377cecb010a437cf6a12428 (patch)
tree01de8ad0ea53e6fbc9e446c7344340e96fd6eebd /subprojects/store-query-viatra
parentrefactor: VIATRA adapter fixes (diff)
downloadrefinery-a69beacc266ba4462377cecb010a437cf6a12428.tar.gz
refinery-a69beacc266ba4462377cecb010a437cf6a12428.tar.zst
refinery-a69beacc266ba4462377cecb010a437cf6a12428.zip
feat: model query functional dependencies
Diffstat (limited to 'subprojects/store-query-viatra')
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/ViatraModelQueryBuilder.java2
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/RelationalScope.java13
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraModelQueryAdapterImpl.java2
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraModelQueryBuilderImpl.java4
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraModelQueryStoreAdapterImpl.java14
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/DummyBaseIndexer.java3
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalEngineContext.java10
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalQueryMetaContext.java66
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalRuntimeContext.java8
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/DNF2PQuery.java23
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/RawPQuery.java6
-rw-r--r--subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/internal/cardinality/UpperCardinalitySumAggregationOperatorStreamTest.java17
12 files changed, 124 insertions, 44 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 ee445a79..efc6146c 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
@@ -29,7 +29,7 @@ public interface ViatraModelQueryBuilder extends ModelQueryBuilder {
29 } 29 }
30 30
31 @Override 31 @Override
32 default ViatraModelQueryBuilder queries(Collection<? extends DNF> queries) { 32 default ViatraModelQueryBuilder queries(Collection<DNF> queries) {
33 ModelQueryBuilder.super.queries(queries); 33 ModelQueryBuilder.super.queries(queries);
34 return this; 34 return this;
35 } 35 }
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 21dcaf15..b4d43ef8 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
@@ -5,26 +5,25 @@ import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine;
5import org.eclipse.viatra.query.runtime.api.scope.IEngineContext; 5import org.eclipse.viatra.query.runtime.api.scope.IEngineContext;
6import org.eclipse.viatra.query.runtime.api.scope.IIndexingErrorListener; 6import org.eclipse.viatra.query.runtime.api.scope.IIndexingErrorListener;
7import org.eclipse.viatra.query.runtime.api.scope.QueryScope; 7import org.eclipse.viatra.query.runtime.api.scope.QueryScope;
8import org.eclipse.viatra.query.runtime.matchers.context.IInputKey;
8import tools.refinery.store.model.Model; 9import tools.refinery.store.model.Model;
9import tools.refinery.store.query.viatra.internal.context.RelationalEngineContext; 10import tools.refinery.store.query.viatra.internal.context.RelationalEngineContext;
10import tools.refinery.store.query.viatra.internal.update.ModelUpdateListener;
11import tools.refinery.store.query.view.AnyRelationView; 11import tools.refinery.store.query.view.AnyRelationView;
12 12
13import java.util.Collection; 13import java.util.Map;
14 14
15public class RelationalScope extends QueryScope { 15public class RelationalScope extends QueryScope {
16 private final Model model; 16 private final Model model;
17 private final Map<AnyRelationView, IInputKey> relationViews;
17 18
18 private final ModelUpdateListener updateListener; 19 public RelationalScope(Model model, Map<AnyRelationView, IInputKey> relationViews) {
19
20 public RelationalScope(Model model, Collection<AnyRelationView> relationViews) {
21 this.model = model; 20 this.model = model;
22 updateListener = new ModelUpdateListener(model, relationViews); 21 this.relationViews = relationViews;
23 } 22 }
24 23
25 @Override 24 @Override
26 protected IEngineContext createEngineContext(ViatraQueryEngine engine, IIndexingErrorListener errorListener, 25 protected IEngineContext createEngineContext(ViatraQueryEngine engine, IIndexingErrorListener errorListener,
27 Logger logger) { 26 Logger logger) {
28 return new RelationalEngineContext(model, updateListener); 27 return new RelationalEngineContext(model, relationViews);
29 } 28 }
30} 29}
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 3c276935..810d2c32 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
@@ -30,7 +30,7 @@ public class ViatraModelQueryAdapterImpl implements ModelQueryAdapter {
30 ViatraModelQueryAdapterImpl(Model model, ViatraModelQueryStoreAdapterImpl storeAdapter) { 30 ViatraModelQueryAdapterImpl(Model model, ViatraModelQueryStoreAdapterImpl storeAdapter) {
31 this.model = model; 31 this.model = model;
32 this.storeAdapter = storeAdapter; 32 this.storeAdapter = storeAdapter;
33 var scope = new RelationalScope(model, storeAdapter.getRelationViews()); 33 var scope = new RelationalScope(model, storeAdapter.getInputKeys());
34 queryEngine = (ViatraQueryEngineImpl) AdvancedViatraQueryEngine.createUnmanagedEngine(scope); 34 queryEngine = (ViatraQueryEngineImpl) AdvancedViatraQueryEngine.createUnmanagedEngine(scope);
35 35
36 try { 36 try {
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 5105c9a7..9f1e55b1 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
@@ -92,7 +92,7 @@ public class ViatraModelQueryBuilderImpl extends AbstractModelAdapterBuilder imp
92 throw new IllegalArgumentException( 92 throw new IllegalArgumentException(
93 "Cannot specify hint for %s, because it was not added to the query engine".formatted(dnf.name())); 93 "Cannot specify hint for %s, because it was not added to the query engine".formatted(dnf.name()));
94 } 94 }
95 pQuery.setEvaluationHints(queryEvaluationHint); 95 pQuery.setEvaluationHints(pQuery.getEvaluationHints().overrideBy(queryEvaluationHint));
96 return this; 96 return this;
97 } 97 }
98 98
@@ -105,7 +105,7 @@ public class ViatraModelQueryBuilderImpl extends AbstractModelAdapterBuilder imp
105 105
106 private void validateSymbols(ModelStore store) { 106 private void validateSymbols(ModelStore store) {
107 var symbols = store.getSymbols(); 107 var symbols = store.getSymbols();
108 for (var relationView : dnf2PQuery.getRelationViews()) { 108 for (var relationView : dnf2PQuery.getRelationViews().keySet()) {
109 var symbol = relationView.getSymbol(); 109 var symbol = relationView.getSymbol();
110 if (!symbols.contains(symbol)) { 110 if (!symbols.contains(symbol)) {
111 throw new IllegalArgumentException("Cannot query relation view %s: symbol %s is not in the model" 111 throw new IllegalArgumentException("Cannot query relation view %s: symbol %s is not in the model"
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 d77b7f4b..69f1f146 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
@@ -2,6 +2,7 @@ package tools.refinery.store.query.viatra.internal;
2 2
3import org.eclipse.viatra.query.runtime.api.IQuerySpecification; 3import org.eclipse.viatra.query.runtime.api.IQuerySpecification;
4import org.eclipse.viatra.query.runtime.api.ViatraQueryEngineOptions; 4import org.eclipse.viatra.query.runtime.api.ViatraQueryEngineOptions;
5import org.eclipse.viatra.query.runtime.matchers.context.IInputKey;
5import tools.refinery.store.model.Model; 6import tools.refinery.store.model.Model;
6import tools.refinery.store.model.ModelStore; 7import tools.refinery.store.model.ModelStore;
7import tools.refinery.store.query.DNF; 8import tools.refinery.store.query.DNF;
@@ -15,15 +16,15 @@ import java.util.Map;
15public class ViatraModelQueryStoreAdapterImpl implements ViatraModelQueryStoreAdapter { 16public class ViatraModelQueryStoreAdapterImpl implements ViatraModelQueryStoreAdapter {
16 private final ModelStore store; 17 private final ModelStore store;
17 private final ViatraQueryEngineOptions engineOptions; 18 private final ViatraQueryEngineOptions engineOptions;
18 private final Collection<AnyRelationView> relationViews; 19 private final Map<AnyRelationView, IInputKey> inputKeys;
19 private final Map<DNF, IQuerySpecification<RawPatternMatcher>> querySpecifications; 20 private final Map<DNF, IQuerySpecification<RawPatternMatcher>> querySpecifications;
20 21
21 ViatraModelQueryStoreAdapterImpl(ModelStore store, ViatraQueryEngineOptions engineOptions, 22 ViatraModelQueryStoreAdapterImpl(ModelStore store, ViatraQueryEngineOptions engineOptions,
22 Collection<AnyRelationView> relationViews, 23 Map<AnyRelationView, IInputKey> inputKeys,
23 Map<DNF, IQuerySpecification<RawPatternMatcher>> querySpecifications) { 24 Map<DNF, IQuerySpecification<RawPatternMatcher>> querySpecifications) {
24 this.store = store; 25 this.store = store;
25 this.engineOptions = engineOptions; 26 this.engineOptions = engineOptions;
26 this.relationViews = relationViews; 27 this.inputKeys = inputKeys;
27 this.querySpecifications = querySpecifications; 28 this.querySpecifications = querySpecifications;
28 } 29 }
29 30
@@ -32,9 +33,12 @@ public class ViatraModelQueryStoreAdapterImpl implements ViatraModelQueryStoreAd
32 return store; 33 return store;
33 } 34 }
34 35
35 @Override
36 public Collection<AnyRelationView> getRelationViews() { 36 public Collection<AnyRelationView> getRelationViews() {
37 return relationViews; 37 return inputKeys.keySet();
38 }
39
40 Map<AnyRelationView, IInputKey> getInputKeys() {
41 return inputKeys;
38 } 42 }
39 43
40 @Override 44 @Override
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 29f0536c..2a24b67c 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
@@ -12,6 +12,9 @@ import java.util.concurrent.Callable;
12 * Copied from <code>org.eclipse.viatra.query.runtime.tabular.TabularEngineContext</code> 12 * Copied from <code>org.eclipse.viatra.query.runtime.tabular.TabularEngineContext</code>
13 */ 13 */
14public class DummyBaseIndexer implements IBaseIndex { 14public class DummyBaseIndexer implements IBaseIndex {
15 DummyBaseIndexer() {
16 }
17
15 @Override 18 @Override
16 public <V> V coalesceTraversals(Callable<V> callable) throws InvocationTargetException { 19 public <V> V coalesceTraversals(Callable<V> callable) throws InvocationTargetException {
17 try { 20 try {
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 4eb8898b..3bad01b9 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
@@ -2,17 +2,19 @@ package tools.refinery.store.query.viatra.internal.context;
2 2
3import org.eclipse.viatra.query.runtime.api.scope.IBaseIndex; 3import org.eclipse.viatra.query.runtime.api.scope.IBaseIndex;
4import org.eclipse.viatra.query.runtime.api.scope.IEngineContext; 4import org.eclipse.viatra.query.runtime.api.scope.IEngineContext;
5import org.eclipse.viatra.query.runtime.matchers.context.IInputKey;
5import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContext; 6import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContext;
6
7import tools.refinery.store.model.Model; 7import tools.refinery.store.model.Model;
8import tools.refinery.store.query.viatra.internal.update.ModelUpdateListener; 8import tools.refinery.store.query.view.AnyRelationView;
9
10import java.util.Map;
9 11
10public class RelationalEngineContext implements IEngineContext { 12public class RelationalEngineContext implements IEngineContext {
11 private final IBaseIndex baseIndex = new DummyBaseIndexer(); 13 private final IBaseIndex baseIndex = new DummyBaseIndexer();
12 private final RelationalRuntimeContext runtimeContext; 14 private final RelationalRuntimeContext runtimeContext;
13 15
14 public RelationalEngineContext(Model model, ModelUpdateListener updateListener) { 16 public RelationalEngineContext(Model model, Map< AnyRelationView, IInputKey> inputKeys) {
15 runtimeContext = new RelationalRuntimeContext(model, updateListener); 17 runtimeContext = new RelationalRuntimeContext(model, inputKeys);
16 } 18 }
17 19
18 @Override 20 @Override
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 81046b2a..cba3fa08 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
@@ -4,24 +4,29 @@ import org.eclipse.viatra.query.runtime.matchers.context.AbstractQueryMetaContex
4import org.eclipse.viatra.query.runtime.matchers.context.IInputKey; 4import org.eclipse.viatra.query.runtime.matchers.context.IInputKey;
5import org.eclipse.viatra.query.runtime.matchers.context.InputKeyImplication; 5import org.eclipse.viatra.query.runtime.matchers.context.InputKeyImplication;
6import tools.refinery.store.query.viatra.internal.pquery.RelationViewWrapper; 6import tools.refinery.store.query.viatra.internal.pquery.RelationViewWrapper;
7import tools.refinery.store.query.view.AnyRelationView;
7 8
8import java.util.Collection; 9import java.util.*;
9import java.util.Map;
10import java.util.Set;
11 10
12/** 11/**
13 * The meta context information for String scopes. 12 * The meta context information for String scopes.
14 */ 13 */
15public class RelationalQueryMetaContext extends AbstractQueryMetaContext { 14public class RelationalQueryMetaContext extends AbstractQueryMetaContext {
15 private final Map<AnyRelationView, IInputKey> inputKeys;
16
17 RelationalQueryMetaContext(Map<AnyRelationView, IInputKey> inputKeys) {
18 this.inputKeys = inputKeys;
19 }
20
16 @Override 21 @Override
17 public boolean isEnumerable(IInputKey key) { 22 public boolean isEnumerable(IInputKey key) {
18 ensureValidKey(key); 23 checkKey(key);
19 return key.isEnumerable(); 24 return key.isEnumerable();
20 } 25 }
21 26
22 @Override 27 @Override
23 public boolean isStateless(IInputKey key) { 28 public boolean isStateless(IInputKey key) {
24 ensureValidKey(key); 29 checkKey(key);
25 return true; 30 return true;
26 } 31 }
27 32
@@ -32,19 +37,58 @@ public class RelationalQueryMetaContext extends AbstractQueryMetaContext {
32 37
33 @Override 38 @Override
34 public Collection<InputKeyImplication> getImplications(IInputKey implyingKey) { 39 public Collection<InputKeyImplication> getImplications(IInputKey implyingKey) {
35 ensureValidKey(implyingKey); 40 var relationView = checkKey(implyingKey);
36 return Set.of(); 41 var relationViewImplications = relationView.getImpliedRelationViews();
42 var inputKeyImplications = new HashSet<InputKeyImplication>(relationViewImplications.size());
43 for (var relationViewImplication : relationViewImplications) {
44 if (!relationView.equals(relationViewImplication.implyingRelationView())) {
45 throw new IllegalArgumentException("Relation view %s returned unrelated implication %s".formatted(
46 relationView, relationViewImplication));
47 }
48 var impliedInputKey = inputKeys.get(relationViewImplication.impliedRelationView());
49 // Ignore implications not relevant for any queries included in the model.
50 if (impliedInputKey != null) {
51 inputKeyImplications.add(new InputKeyImplication(implyingKey, impliedInputKey,
52 relationViewImplication.impliedIndices()));
53 }
54 }
55 return inputKeyImplications;
37 } 56 }
38 57
39 @Override 58 @Override
40 public Map<Set<Integer>, Set<Integer>> getFunctionalDependencies(IInputKey key) { 59 public Map<Set<Integer>, Set<Integer>> getFunctionalDependencies(IInputKey key) {
41 ensureValidKey(key); 60 var relationView = checkKey(key);
42 return Map.of(); 61 var functionalDependencies = relationView.getFunctionalDependencies();
62 var flattened = new HashMap<Set<Integer>, Set<Integer>>(functionalDependencies.size());
63 for (var functionalDependency : functionalDependencies) {
64 var forEach = functionalDependency.forEach();
65 checkValidIndices(relationView, forEach);
66 var unique = functionalDependency.unique();
67 checkValidIndices(relationView, unique);
68 var existing = flattened.get(forEach);
69 if (existing == null) {
70 flattened.put(forEach, new HashSet<>(unique));
71 } else {
72 existing.addAll(unique);
73 }
74 }
75 return flattened;
76 }
77
78 private static void checkValidIndices(AnyRelationView relationView, Collection<Integer> indices) {
79 indices.stream().filter(relationView::invalidIndex).findAny().ifPresent(i -> {
80 throw new IllegalArgumentException("Index %d is invalid for %s".formatted(i, relationView));
81 });
43 } 82 }
44 83
45 public void ensureValidKey(IInputKey key) { 84 public AnyRelationView checkKey(IInputKey key) {
46 if (!(key instanceof RelationViewWrapper)) { 85 if (!(key instanceof RelationViewWrapper wrapper)) {
47 throw new IllegalArgumentException("The input key %s is not a valid input key".formatted(key)); 86 throw new IllegalArgumentException("The input key %s is not a valid input key".formatted(key));
48 } 87 }
88 var relationView = wrapper.getWrappedKey();
89 if (!inputKeys.containsKey(relationView)) {
90 throw new IllegalArgumentException("The input key %s is not present in the model".formatted(key));
91 }
92 return relationView;
49 } 93 }
50} 94}
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 9c1d966c..71ab5cb4 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
@@ -13,6 +13,7 @@ import tools.refinery.store.query.view.AnyRelationView;
13 13
14import java.lang.reflect.InvocationTargetException; 14import java.lang.reflect.InvocationTargetException;
15import java.util.Iterator; 15import java.util.Iterator;
16import java.util.Map;
16import java.util.Optional; 17import java.util.Optional;
17import java.util.concurrent.Callable; 18import java.util.concurrent.Callable;
18 19
@@ -20,15 +21,16 @@ import static tools.refinery.store.util.CollectionsUtil.filter;
20import static tools.refinery.store.util.CollectionsUtil.map; 21import static tools.refinery.store.util.CollectionsUtil.map;
21 22
22public class RelationalRuntimeContext implements IQueryRuntimeContext { 23public class RelationalRuntimeContext implements IQueryRuntimeContext {
23 private final RelationalQueryMetaContext metaContext = new RelationalQueryMetaContext(); 24 private final RelationalQueryMetaContext metaContext;
24 25
25 private final ModelUpdateListener modelUpdateListener; 26 private final ModelUpdateListener modelUpdateListener;
26 27
27 private final Model model; 28 private final Model model;
28 29
29 public RelationalRuntimeContext(Model model, ModelUpdateListener relationUpdateListener) { 30 RelationalRuntimeContext(Model model, Map<AnyRelationView, IInputKey> inputKeys) {
30 this.model = model; 31 this.model = model;
31 this.modelUpdateListener = relationUpdateListener; 32 metaContext = new RelationalQueryMetaContext(inputKeys);
33 modelUpdateListener = new ModelUpdateListener(model, inputKeys.keySet());
32 } 34 }
33 35
34 @Override 36 @Override
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 f2cb8d8d..60f1bcae 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
@@ -1,8 +1,10 @@
1package tools.refinery.store.query.viatra.internal.pquery; 1package tools.refinery.store.query.viatra.internal.pquery;
2 2
3import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; 3import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint;
4import org.eclipse.viatra.query.runtime.matchers.context.IInputKey;
4import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; 5import org.eclipse.viatra.query.runtime.matchers.psystem.PBody;
5import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; 6import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable;
7import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation;
6import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality; 8import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality;
7import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; 9import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter;
8import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Inequality; 10import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Inequality;
@@ -35,6 +37,8 @@ public class DNF2PQuery {
35 37
36 private final Map<AnyRelationView, RelationViewWrapper> view2WrapperMap = new LinkedHashMap<>(); 38 private final Map<AnyRelationView, RelationViewWrapper> view2WrapperMap = new LinkedHashMap<>();
37 39
40 private final Map<AnyRelationView, RawPQuery> view2EmbeddedMap = new HashMap<>();
41
38 private Function<DNF, QueryEvaluationHint> computeHint = dnf -> new QueryEvaluationHint(null, 42 private Function<DNF, QueryEvaluationHint> computeHint = dnf -> new QueryEvaluationHint(null,
39 QueryEvaluationHint.BackendRequirement.UNSPECIFIED); 43 QueryEvaluationHint.BackendRequirement.UNSPECIFIED);
40 44
@@ -63,8 +67,8 @@ public class DNF2PQuery {
63 return pQuery; 67 return pQuery;
64 } 68 }
65 69
66 public Collection<AnyRelationView> getRelationViews() { 70 public Map<AnyRelationView, IInputKey> getRelationViews() {
67 return Collections.unmodifiableCollection(view2WrapperMap.keySet()); 71 return Collections.unmodifiableMap(view2WrapperMap);
68 } 72 }
69 73
70 public RawPQuery getAlreadyTranslated(DNF dnfQuery) { 74 public RawPQuery getAlreadyTranslated(DNF dnfQuery) {
@@ -86,6 +90,17 @@ public class DNF2PQuery {
86 } 90 }
87 pQuery.setParameters(parameterList); 91 pQuery.setParameters(parameterList);
88 92
93 for (var functionalDependency : dnfQuery.getFunctionalDependencies()) {
94 var functionalDependencyAnnotation = new PAnnotation("FunctionalDependency");
95 for (var forEachVariable : functionalDependency.forEach()) {
96 functionalDependencyAnnotation.addAttribute("forEach", forEachVariable.getUniqueName());
97 }
98 for (var uniqueVariable : functionalDependency.unique()) {
99 functionalDependencyAnnotation.addAttribute("unique", uniqueVariable.getUniqueName());
100 }
101 pQuery.addAnnotation(functionalDependencyAnnotation);
102 }
103
89 // The constructor of {@link org.eclipse.viatra.query.runtime.matchers.psystem.BasePConstraint} mutates 104 // The constructor of {@link org.eclipse.viatra.query.runtime.matchers.psystem.BasePConstraint} mutates
90 // global static state (<code>nextID</code>) without locking. Therefore, we need to synchronize before creating 105 // global static state (<code>nextID</code>) without locking. Therefore, we need to synchronize before creating
91 // any query constraints to avoid a data race. 106 // any query constraints to avoid a data race.
@@ -159,6 +174,10 @@ public class DNF2PQuery {
159 } 174 }
160 175
161 private RawPQuery translateEmbeddedRelationViewPQuery(AnyRelationView relationView) { 176 private RawPQuery translateEmbeddedRelationViewPQuery(AnyRelationView relationView) {
177 return view2EmbeddedMap.computeIfAbsent(relationView, this::doTranslateEmbeddedRelationViewPQuery);
178 }
179
180 private RawPQuery doTranslateEmbeddedRelationViewPQuery(AnyRelationView relationView) {
162 var embeddedPQuery = new RawPQuery(DNFUtils.generateUniqueName(relationView.name()), PVisibility.EMBEDDED); 181 var embeddedPQuery = new RawPQuery(DNFUtils.generateUniqueName(relationView.name()), PVisibility.EMBEDDED);
163 var body = new PBody(embeddedPQuery); 182 var body = new PBody(embeddedPQuery);
164 int arity = relationView.arity(); 183 int arity = relationView.arity();
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 830495b2..71b74396 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
@@ -4,6 +4,7 @@ import org.eclipse.viatra.query.runtime.api.GenericQuerySpecification;
4import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; 4import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine;
5import org.eclipse.viatra.query.runtime.api.scope.QueryScope; 5import org.eclipse.viatra.query.runtime.api.scope.QueryScope;
6import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; 6import org.eclipse.viatra.query.runtime.matchers.psystem.PBody;
7import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation;
7import org.eclipse.viatra.query.runtime.matchers.psystem.queries.BasePQuery; 8import org.eclipse.viatra.query.runtime.matchers.psystem.queries.BasePQuery;
8import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; 9import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter;
9import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; 10import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility;
@@ -37,6 +38,11 @@ public class RawPQuery extends BasePQuery {
37 } 38 }
38 39
39 @Override 40 @Override
41 public void addAnnotation(PAnnotation annotation) {
42 super.addAnnotation(annotation);
43 }
44
45 @Override
40 public List<PParameter> getParameters() { 46 public List<PParameter> getParameters() {
41 return parameters; 47 return parameters;
42 } 48 }
diff --git a/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/internal/cardinality/UpperCardinalitySumAggregationOperatorStreamTest.java b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/internal/cardinality/UpperCardinalitySumAggregationOperatorStreamTest.java
index 69491fda..c529117e 100644
--- a/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/internal/cardinality/UpperCardinalitySumAggregationOperatorStreamTest.java
+++ b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/internal/cardinality/UpperCardinalitySumAggregationOperatorStreamTest.java
@@ -6,6 +6,7 @@ import org.junit.jupiter.params.provider.MethodSource;
6import tools.refinery.store.representation.cardinality.UpperCardinalities; 6import tools.refinery.store.representation.cardinality.UpperCardinalities;
7import tools.refinery.store.representation.cardinality.UpperCardinality; 7import tools.refinery.store.representation.cardinality.UpperCardinality;
8 8
9import java.util.List;
9import java.util.stream.Stream; 10import java.util.stream.Stream;
10 11
11import static org.hamcrest.MatcherAssert.assertThat; 12import static org.hamcrest.MatcherAssert.assertThat;
@@ -14,32 +15,32 @@ import static org.hamcrest.Matchers.equalTo;
14class UpperCardinalitySumAggregationOperatorStreamTest { 15class UpperCardinalitySumAggregationOperatorStreamTest {
15 @ParameterizedTest 16 @ParameterizedTest
16 @MethodSource 17 @MethodSource
17 void testStream(Stream<UpperCardinality> stream, UpperCardinality expected) { 18 void testStream(List<UpperCardinality> list, UpperCardinality expected) {
18 var result = UpperCardinalitySumAggregationOperator.INSTANCE.aggregateStream(stream); 19 var result = UpperCardinalitySumAggregationOperator.INSTANCE.aggregateStream(list.stream());
19 assertThat(result, equalTo(expected)); 20 assertThat(result, equalTo(expected));
20 } 21 }
21 22
22 static Stream<Arguments> testStream() { 23 static Stream<Arguments> testStream() {
23 return Stream.of( 24 return Stream.of(
24 Arguments.of(Stream.of(), UpperCardinalities.ZERO), 25 Arguments.of(List.of(), UpperCardinalities.ZERO),
25 Arguments.of(Stream.of(UpperCardinality.of(3)), UpperCardinality.of(3)), 26 Arguments.of(List.of(UpperCardinality.of(3)), UpperCardinality.of(3)),
26 Arguments.of( 27 Arguments.of(
27 Stream.of( 28 List.of(
28 UpperCardinality.of(2), 29 UpperCardinality.of(2),
29 UpperCardinality.of(3) 30 UpperCardinality.of(3)
30 ), 31 ),
31 UpperCardinality.of(5) 32 UpperCardinality.of(5)
32 ), 33 ),
33 Arguments.of(Stream.of(UpperCardinalities.UNBOUNDED), UpperCardinalities.UNBOUNDED), 34 Arguments.of(List.of(UpperCardinalities.UNBOUNDED), UpperCardinalities.UNBOUNDED),
34 Arguments.of( 35 Arguments.of(
35 Stream.of( 36 List.of(
36 UpperCardinalities.UNBOUNDED, 37 UpperCardinalities.UNBOUNDED,
37 UpperCardinalities.UNBOUNDED 38 UpperCardinalities.UNBOUNDED
38 ), 39 ),
39 UpperCardinalities.UNBOUNDED 40 UpperCardinalities.UNBOUNDED
40 ), 41 ),
41 Arguments.of( 42 Arguments.of(
42 Stream.of( 43 List.of(
43 UpperCardinalities.UNBOUNDED, 44 UpperCardinalities.UNBOUNDED,
44 UpperCardinality.of(3) 45 UpperCardinality.of(3)
45 ), 46 ),