aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store-query-viatra
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2022-09-26 01:42:58 +0200
committerLibravatar Kristóf Marussy <kristof@marussy.com>2022-10-03 20:06:52 +0200
commit1be64083c2c38eedeffc7cea9f51afbed4d46d28 (patch)
tree75c67f3c09cb8f61809291b58188320c7cde995c /subprojects/store-query-viatra
parentrefactor: move viatra into a separate subproject (diff)
downloadrefinery-1be64083c2c38eedeffc7cea9f51afbed4d46d28.tar.gz
refinery-1be64083c2c38eedeffc7cea9f51afbed4d46d28.tar.zst
refinery-1be64083c2c38eedeffc7cea9f51afbed4d46d28.zip
refactor: remove viatra dependency from store
Diffstat (limited to 'subprojects/store-query-viatra')
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/ViatraQueryableModelStore.java31
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalEngineContext.java1
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalQueryMetaContext.java11
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/context/RelationalRuntimeContext.java10
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/DNF2PQuery.java78
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/RelationViewWrapper.java30
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ModelUpdateListener.java14
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdate.java6
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdateBuffer.java1
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdateTranslator.java20
10 files changed, 136 insertions, 66 deletions
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/ViatraQueryableModelStore.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/ViatraQueryableModelStore.java
index 5a02ca08..a63abc3a 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/ViatraQueryableModelStore.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/ViatraQueryableModelStore.java
@@ -8,10 +8,9 @@ import tools.refinery.store.model.representation.DataRepresentation;
8import tools.refinery.store.query.QueryableModel; 8import tools.refinery.store.query.QueryableModel;
9import tools.refinery.store.query.QueryableModelStore; 9import tools.refinery.store.query.QueryableModelStore;
10import tools.refinery.store.query.building.*; 10import tools.refinery.store.query.building.*;
11import tools.refinery.store.query.viatra.internal.RawPatternMatcher;
11import tools.refinery.store.query.viatra.internal.ViatraQueryableModel; 12import tools.refinery.store.query.viatra.internal.ViatraQueryableModel;
12import tools.refinery.store.query.viatra.internal.pquery.DNF2PQuery; 13import tools.refinery.store.query.viatra.internal.pquery.DNF2PQuery;
13import tools.refinery.store.query.viatra.internal.RawPatternMatcher;
14import tools.refinery.store.query.viatra.internal.pquery.SimplePQuery;
15import tools.refinery.store.query.view.RelationView; 14import tools.refinery.store.query.view.RelationView;
16 15
17import java.util.Collections; 16import java.util.Collections;
@@ -21,7 +20,9 @@ import java.util.Set;
21 20
22public class ViatraQueryableModelStore implements QueryableModelStore { 21public class ViatraQueryableModelStore implements QueryableModelStore {
23 protected final ModelStore store; 22 protected final ModelStore store;
23
24 protected final Set<RelationView<?>> relationViews; 24 protected final Set<RelationView<?>> relationViews;
25
25 protected final Map<DNFPredicate, GenericQuerySpecification<RawPatternMatcher>> predicates; 26 protected final Map<DNFPredicate, GenericQuerySpecification<RawPatternMatcher>> predicates;
26 27
27 public ViatraQueryableModelStore(ModelStore store, Set<RelationView<?>> relationViews, 28 public ViatraQueryableModelStore(ModelStore store, Set<RelationView<?>> relationViews,
@@ -41,9 +42,9 @@ public class ViatraQueryableModelStore implements QueryableModelStore {
41 private void validateViews(Set<DataRepresentation<?, ?>> dataRepresentations, Set<RelationView<?>> relationViews) { 42 private void validateViews(Set<DataRepresentation<?, ?>> dataRepresentations, Set<RelationView<?>> relationViews) {
42 for (RelationView<?> relationView : relationViews) { 43 for (RelationView<?> relationView : relationViews) {
43 if (!dataRepresentations.contains(relationView.getRepresentation())) { 44 if (!dataRepresentations.contains(relationView.getRepresentation())) {
44 throw new IllegalArgumentException( 45 throw new IllegalArgumentException("%s %s added to %s without a referred representation.".formatted(
45 DataRepresentation.class.getSimpleName() + " " + relationView.getStringID() + " added to " 46 DataRepresentation.class.getSimpleName(), relationView.getName(),
46 + QueryableModelStore.class.getSimpleName() + " without a referred representation."); 47 QueryableModelStore.class.getSimpleName()));
47 } 48 }
48 } 49 }
49 } 50 }
@@ -65,10 +66,10 @@ public class ViatraQueryableModelStore implements QueryableModelStore {
65 private void validateRelationAtom(Set<RelationView<?>> relationViews, DNFPredicate dnfPredicate, 66 private void validateRelationAtom(Set<RelationView<?>> relationViews, DNFPredicate dnfPredicate,
66 RelationAtom relationAtom) { 67 RelationAtom relationAtom) {
67 if (!relationViews.contains(relationAtom.view())) { 68 if (!relationViews.contains(relationAtom.view())) {
68 throw new IllegalArgumentException(DNFPredicate.class.getSimpleName() + " " 69 throw new IllegalArgumentException(
69 + dnfPredicate.getUniqueName() + " contains reference to a view of " 70 "%s %s contains reference to a view %s that is not in the model.".formatted(
70 + relationAtom.view().getRepresentation().getName() 71 DNFPredicate.class.getSimpleName(), dnfPredicate.getUniqueName(),
71 + " that is not in the model."); 72 relationAtom.view().getName()));
72 } 73 }
73 } 74 }
74 75
@@ -76,19 +77,17 @@ public class ViatraQueryableModelStore implements QueryableModelStore {
76 PredicateAtom predicateAtom) { 77 PredicateAtom predicateAtom) {
77 if (!predicates.contains(predicateAtom.getReferred())) { 78 if (!predicates.contains(predicateAtom.getReferred())) {
78 throw new IllegalArgumentException( 79 throw new IllegalArgumentException(
79 DNFPredicate.class.getSimpleName() + " " + dnfPredicate.getUniqueName() 80 "%s %s contains reference to a predicate %s that is not in the model.".formatted(
80 + " contains reference to a predicate " 81 DNFPredicate.class.getSimpleName(), dnfPredicate.getUniqueName(),
81 + predicateAtom.getReferred().getName() 82 predicateAtom.getReferred().getName()));
82 + "that is not in the model.");
83 } 83 }
84 } 84 }
85 85
86 private Map<DNFPredicate, GenericQuerySpecification<RawPatternMatcher>> initPredicates(Set<DNFPredicate> predicates) { 86 private Map<DNFPredicate, GenericQuerySpecification<RawPatternMatcher>> initPredicates(Set<DNFPredicate> predicates) {
87 Map<DNFPredicate, GenericQuerySpecification<RawPatternMatcher>> result = new HashMap<>(); 87 Map<DNFPredicate, GenericQuerySpecification<RawPatternMatcher>> result = new HashMap<>();
88 Map<DNFPredicate, SimplePQuery> dnf2PQueryMap = new HashMap<>(); 88 var dnf2PQuery = new DNF2PQuery();
89 for (DNFPredicate dnfPredicate : predicates) { 89 for (DNFPredicate dnfPredicate : predicates) {
90 GenericQuerySpecification<RawPatternMatcher> query = 90 GenericQuerySpecification<RawPatternMatcher> query = dnf2PQuery.translate(dnfPredicate).build();
91 DNF2PQuery.translate(dnfPredicate, dnf2PQueryMap).build();
92 result.put(dnfPredicate, query); 91 result.put(dnfPredicate, query);
93 } 92 }
94 93
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 882734cb..d32d49ba 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
@@ -29,5 +29,4 @@ public class RelationalEngineContext implements IEngineContext {
29 public IQueryRuntimeContext getQueryRuntimeContext() { 29 public IQueryRuntimeContext getQueryRuntimeContext() {
30 return runtimeContext; 30 return runtimeContext;
31 } 31 }
32
33} 32}
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 64c23c61..eb3c6fbd 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
@@ -3,9 +3,11 @@ package tools.refinery.store.query.viatra.internal.context;
3import org.eclipse.viatra.query.runtime.matchers.context.AbstractQueryMetaContext; 3import org.eclipse.viatra.query.runtime.matchers.context.AbstractQueryMetaContext;
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.view.RelationView; 6import tools.refinery.store.query.viatra.internal.pquery.RelationViewWrapper;
7 7
8import java.util.*; 8import java.util.Collection;
9import java.util.Map;
10import java.util.Set;
9 11
10/** 12/**
11 * The meta context information for String scopes. 13 * The meta context information for String scopes.
@@ -36,9 +38,8 @@ public class RelationalQueryMetaContext extends AbstractQueryMetaContext {
36 } 38 }
37 39
38 public void ensureValidKey(IInputKey key) { 40 public void ensureValidKey(IInputKey key) {
39 if (key instanceof RelationView<?>) { 41 if (!(key instanceof RelationViewWrapper)) {
40 return; 42 throw new IllegalArgumentException("The input key %s is not a valid input key.".formatted(key));
41 } 43 }
42 throw new IllegalArgumentException("The input key %s is not a valid input key.".formatted(key));
43 } 44 }
44} 45}
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 0bd1b807..c007d630 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
@@ -7,6 +7,7 @@ import org.eclipse.viatra.query.runtime.matchers.tuple.TupleMask;
7import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; 7import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples;
8import org.eclipse.viatra.query.runtime.matchers.util.Accuracy; 8import org.eclipse.viatra.query.runtime.matchers.util.Accuracy;
9import tools.refinery.store.model.Model; 9import tools.refinery.store.model.Model;
10import tools.refinery.store.query.viatra.internal.pquery.RelationViewWrapper;
10import tools.refinery.store.query.viatra.internal.viewupdate.ModelUpdateListener; 11import tools.refinery.store.query.viatra.internal.viewupdate.ModelUpdateListener;
11import tools.refinery.store.query.view.RelationView; 12import tools.refinery.store.query.view.RelationView;
12 13
@@ -67,7 +68,8 @@ public class RelationalRuntimeContext implements IQueryRuntimeContext {
67 68
68 @SuppressWarnings("squid:S1452") 69 @SuppressWarnings("squid:S1452")
69 RelationView<?> checkKey(IInputKey key) { 70 RelationView<?> checkKey(IInputKey key) {
70 if (key instanceof RelationView<?> relationViewKey) { 71 if (key instanceof RelationViewWrapper wrappedKey) {
72 var relationViewKey = wrappedKey.getWrappedKey();
71 if (modelUpdateListener.containsRelationalView(relationViewKey)) { 73 if (modelUpdateListener.containsRelationalView(relationViewKey)) {
72 return relationViewKey; 74 return relationViewKey;
73 } else { 75 } else {
@@ -117,7 +119,7 @@ public class RelationalRuntimeContext implements IQueryRuntimeContext {
117 } 119 }
118 120
119 @Override 121 @Override
120 public Iterable<? extends Object> enumerateValues(IInputKey key, TupleMask seedMask, ITuple seed) { 122 public Iterable<?> enumerateValues(IInputKey key, TupleMask seedMask, ITuple seed) {
121 return enumerateTuples(key, seedMask, seed); 123 return enumerateTuples(key, seedMask, seed);
122 } 124 }
123 125
@@ -130,14 +132,14 @@ public class RelationalRuntimeContext implements IQueryRuntimeContext {
130 @Override 132 @Override
131 public void addUpdateListener(IInputKey key, Tuple seed, IQueryRuntimeContextListener listener) { 133 public void addUpdateListener(IInputKey key, Tuple seed, IQueryRuntimeContextListener listener) {
132 RelationView<?> relationalKey = checkKey(key); 134 RelationView<?> relationalKey = checkKey(key);
133 this.modelUpdateListener.addListener(relationalKey, seed, listener); 135 this.modelUpdateListener.addListener(key, relationalKey, seed, listener);
134 136
135 } 137 }
136 138
137 @Override 139 @Override
138 public void removeUpdateListener(IInputKey key, Tuple seed, IQueryRuntimeContextListener listener) { 140 public void removeUpdateListener(IInputKey key, Tuple seed, IQueryRuntimeContextListener listener) {
139 RelationView<?> relationalKey = checkKey(key); 141 RelationView<?> relationalKey = checkKey(key);
140 this.modelUpdateListener.removeListener(relationalKey, seed, listener); 142 this.modelUpdateListener.removeListener(key, relationalKey, seed, listener);
141 } 143 }
142 144
143 @Override 145 @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 c093be47..b6468e76 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
@@ -12,28 +12,53 @@ import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeCo
12import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; 12import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter;
13import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; 13import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples;
14import tools.refinery.store.query.building.*; 14import tools.refinery.store.query.building.*;
15import tools.refinery.store.query.view.RelationView;
15 16
16import java.util.*; 17import java.util.*;
18import java.util.stream.Collectors;
17 19
18public class DNF2PQuery { 20public class DNF2PQuery {
19 private DNF2PQuery() { 21 private final Set<DNFPredicate> translating = new LinkedHashSet<>();
20 throw new IllegalStateException("This is a static utility class and should not be instantiated directly"); 22
21 } 23 private final Map<DNFPredicate, SimplePQuery> dnf2PQueryMap = new HashMap<>();
22 24
23 public static SimplePQuery translate(DNFPredicate predicate, Map<DNFPredicate, SimplePQuery> dnf2PQueryMap) { 25 private final Map<RelationView<?>, RelationViewWrapper> view2WrapperMap = new HashMap<>();
24 SimplePQuery query = dnf2PQueryMap.get(predicate); 26
25 if (query != null) { 27 public SimplePQuery translate(DNFPredicate predicate) {
26 return query; 28 if (translating.contains(predicate)) {
29 var path = translating.stream().map(DNFPredicate::getName).collect(Collectors.joining(" -> "));
30 throw new IllegalStateException("Circular reference %s -> %s detected".formatted(path,
31 predicate.getName()));
27 } 32 }
28 query = new SimplePQuery(predicate.getName()); 33 // We can't use computeIfAbsent here, because translating referenced queries calls this method in a reentrant
34 // way, which would cause a ConcurrentModificationException with computeIfAbsent.
35 var pQuery = dnf2PQueryMap.get(predicate);
36 if (pQuery == null) {
37 translating.add(predicate);
38 try {
39 pQuery = doTranslate(predicate);
40 dnf2PQueryMap.put(predicate, pQuery);
41 } finally {
42 translating.remove(predicate);
43 }
44 }
45 return pQuery;
46 }
47
48 private SimplePQuery doTranslate(DNFPredicate predicate) {
49 var query = new SimplePQuery(predicate.getName());
50
29 Map<Variable, PParameter> parameters = new HashMap<>(); 51 Map<Variable, PParameter> parameters = new HashMap<>();
52 for (Variable variable : predicate.getVariables()) {
53 parameters.put(variable, new PParameter(variable.getName()));
54 }
30 55
31 predicate.getVariables().forEach(variable -> parameters.put(variable, new PParameter(variable.getName())));
32 List<PParameter> parameterList = new ArrayList<>(); 56 List<PParameter> parameterList = new ArrayList<>();
33 for (var param : predicate.getVariables()) { 57 for (var param : predicate.getVariables()) {
34 parameterList.add(parameters.get(param)); 58 parameterList.add(parameters.get(param));
35 } 59 }
36 query.setParameters(parameterList); 60 query.setParameters(parameterList);
61
37 for (DNFAnd clause : predicate.getClauses()) { 62 for (DNFAnd clause : predicate.getClauses()) {
38 PBody body = new PBody(query); 63 PBody body = new PBody(query);
39 List<ExportedParameter> symbolicParameters = new ArrayList<>(); 64 List<ExportedParameter> symbolicParameters = new ArrayList<>();
@@ -44,15 +69,14 @@ public class DNF2PQuery {
44 body.setSymbolicParameters(symbolicParameters); 69 body.setSymbolicParameters(symbolicParameters);
45 query.addBody(body); 70 query.addBody(body);
46 for (DNFAtom constraint : clause.getConstraints()) { 71 for (DNFAtom constraint : clause.getConstraints()) {
47 translateDNFAtom(constraint, body, dnf2PQueryMap); 72 translateDNFAtom(constraint, body);
48 } 73 }
49 } 74 }
50 dnf2PQueryMap.put(predicate, query); 75
51 return query; 76 return query;
52 } 77 }
53 78
54 private static void translateDNFAtom(DNFAtom constraint, PBody body, 79 private void translateDNFAtom(DNFAtom constraint, PBody body) {
55 Map<DNFPredicate, SimplePQuery> dnf2PQueryMap) {
56 if (constraint instanceof EquivalenceAtom equivalence) { 80 if (constraint instanceof EquivalenceAtom equivalence) {
57 translateEquivalenceAtom(equivalence, body); 81 translateEquivalenceAtom(equivalence, body);
58 } 82 }
@@ -60,11 +84,11 @@ public class DNF2PQuery {
60 translateRelationAtom(relation, body); 84 translateRelationAtom(relation, body);
61 } 85 }
62 if (constraint instanceof PredicateAtom predicate) { 86 if (constraint instanceof PredicateAtom predicate) {
63 translatePredicateAtom(predicate, body, dnf2PQueryMap); 87 translatePredicateAtom(predicate, body);
64 } 88 }
65 } 89 }
66 90
67 private static void translateEquivalenceAtom(EquivalenceAtom equivalence, PBody body) { 91 private void translateEquivalenceAtom(EquivalenceAtom equivalence, PBody body) {
68 PVariable varSource = body.getOrCreateVariableByName(equivalence.getLeft().getName()); 92 PVariable varSource = body.getOrCreateVariableByName(equivalence.getLeft().getName());
69 PVariable varTarget = body.getOrCreateVariableByName(equivalence.getRight().getName()); 93 PVariable varTarget = body.getOrCreateVariableByName(equivalence.getRight().getName());
70 if (equivalence.isPositive()) 94 if (equivalence.isPositive())
@@ -73,7 +97,7 @@ public class DNF2PQuery {
73 new Inequality(body, varSource, varTarget); 97 new Inequality(body, varSource, varTarget);
74 } 98 }
75 99
76 private static void translateRelationAtom(RelationAtom relation, PBody body) { 100 private void translateRelationAtom(RelationAtom relation, PBody body) {
77 if (relation.substitution().size() != relation.view().getArity()) { 101 if (relation.substitution().size() != relation.view().getArity()) {
78 throw new IllegalArgumentException("Arity (%d) does not match parameter numbers (%d)".formatted( 102 throw new IllegalArgumentException("Arity (%d) does not match parameter numbers (%d)".formatted(
79 relation.view().getArity(), relation.substitution().size())); 103 relation.view().getArity(), relation.substitution().size()));
@@ -82,32 +106,34 @@ public class DNF2PQuery {
82 for (int i = 0; i < relation.substitution().size(); i++) { 106 for (int i = 0; i < relation.substitution().size(); i++) {
83 variables[i] = body.getOrCreateVariableByName(relation.substitution().get(i).getName()); 107 variables[i] = body.getOrCreateVariableByName(relation.substitution().get(i).getName());
84 } 108 }
85 new TypeConstraint(body, Tuples.flatTupleOf(variables), relation.view()); 109 new TypeConstraint(body, Tuples.flatTupleOf(variables), wrapView(relation.view()));
110 }
111
112 private RelationViewWrapper wrapView(RelationView<?> relationView) {
113 return view2WrapperMap.computeIfAbsent(relationView, RelationViewWrapper::new);
86 } 114 }
87 115
88 private static void translatePredicateAtom(PredicateAtom predicate, PBody body, 116 private void translatePredicateAtom(PredicateAtom predicate, PBody body) {
89 Map<DNFPredicate, SimplePQuery> dnf2PQueryMap) {
90 Object[] variables = new Object[predicate.getSubstitution().size()]; 117 Object[] variables = new Object[predicate.getSubstitution().size()];
91 for (int i = 0; i < predicate.getSubstitution().size(); i++) { 118 for (int i = 0; i < predicate.getSubstitution().size(); i++) {
92 variables[i] = body.getOrCreateVariableByName(predicate.getSubstitution().get(i).getName()); 119 variables[i] = body.getOrCreateVariableByName(predicate.getSubstitution().get(i).getName());
93 } 120 }
121 var variablesTuple = Tuples.flatTupleOf(variables);
122 var translatedReferred = translate(predicate.getReferred());
94 if (predicate.isPositive()) { 123 if (predicate.isPositive()) {
95 if (predicate.isTransitive()) { 124 if (predicate.isTransitive()) {
96 if (predicate.getSubstitution().size() != 2) { 125 if (predicate.getSubstitution().size() != 2) {
97 throw new IllegalArgumentException("Transitive Predicate Atoms must be binary."); 126 throw new IllegalArgumentException("Transitive Predicate Atoms must be binary.");
98 } 127 }
99 new BinaryTransitiveClosure(body, Tuples.flatTupleOf(variables), 128 new BinaryTransitiveClosure(body, variablesTuple, translatedReferred);
100 DNF2PQuery.translate(predicate.getReferred(), dnf2PQueryMap));
101 } else { 129 } else {
102 new PositivePatternCall(body, Tuples.flatTupleOf(variables), 130 new PositivePatternCall(body, variablesTuple, translatedReferred);
103 DNF2PQuery.translate(predicate.getReferred(), dnf2PQueryMap));
104 } 131 }
105 } else { 132 } else {
106 if (predicate.isTransitive()) { 133 if (predicate.isTransitive()) {
107 throw new InputMismatchException("Transitive Predicate Atoms cannot be negative."); 134 throw new IllegalArgumentException("Transitive Predicate Atoms cannot be negative.");
108 } else { 135 } else {
109 new NegativePatternCall(body, Tuples.flatTupleOf(variables), 136 new NegativePatternCall(body, variablesTuple, translatedReferred);
110 DNF2PQuery.translate(predicate.getReferred(), dnf2PQueryMap));
111 } 137 }
112 } 138 }
113 } 139 }
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/RelationViewWrapper.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/RelationViewWrapper.java
new file mode 100644
index 00000000..2a4148dc
--- /dev/null
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/RelationViewWrapper.java
@@ -0,0 +1,30 @@
1package tools.refinery.store.query.viatra.internal.pquery;
2
3import org.eclipse.viatra.query.runtime.matchers.context.common.BaseInputKeyWrapper;
4import tools.refinery.store.query.view.RelationView;
5
6public class RelationViewWrapper extends BaseInputKeyWrapper<RelationView<?>> {
7 public RelationViewWrapper(RelationView<?> wrappedKey) {
8 super(wrappedKey);
9 }
10
11 @Override
12 public String getPrettyPrintableName() {
13 return wrappedKey.getName();
14 }
15
16 @Override
17 public String getStringID() {
18 return getPrettyPrintableName();
19 }
20
21 @Override
22 public int getArity() {
23 return wrappedKey.getArity();
24 }
25
26 @Override
27 public boolean isEnumerable() {
28 return true;
29 }
30}
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ModelUpdateListener.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ModelUpdateListener.java
index 25919888..5a0da315 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ModelUpdateListener.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ModelUpdateListener.java
@@ -1,5 +1,6 @@
1package tools.refinery.store.query.viatra.internal.viewupdate; 1package tools.refinery.store.query.viatra.internal.viewupdate;
2 2
3import org.eclipse.viatra.query.runtime.matchers.context.IInputKey;
3import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContextListener; 4import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContextListener;
4import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; 5import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple;
5import tools.refinery.store.model.Tuple; 6import tools.refinery.store.model.Tuple;
@@ -46,20 +47,23 @@ public class ModelUpdateListener {
46 return view2Buffers.containsKey(relationalKey); 47 return view2Buffers.containsKey(relationalKey);
47 } 48 }
48 49
49 public <D> void addListener(RelationView<D> relationView, ITuple seed, IQueryRuntimeContextListener listener) { 50 public <D> void addListener(IInputKey key, RelationView<D> relationView, ITuple seed,
51 IQueryRuntimeContextListener listener) {
50 if (view2Buffers.containsKey(relationView)) { 52 if (view2Buffers.containsKey(relationView)) {
51 ViewUpdateTranslator<D> updateListener = new ViewUpdateTranslator<>(relationView, seed, listener); 53 ViewUpdateTranslator<D> updateListener = new ViewUpdateTranslator<>(key, relationView, seed, listener);
52 ViewUpdateBuffer<D> updateBuffer = new ViewUpdateBuffer<>(updateListener); 54 ViewUpdateBuffer<D> updateBuffer = new ViewUpdateBuffer<>(updateListener);
53 view2Buffers.get(relationView).add(updateBuffer); 55 view2Buffers.get(relationView).add(updateBuffer);
54 } else 56 } else {
55 throw new IllegalArgumentException(); 57 throw new IllegalArgumentException();
58 }
56 } 59 }
57 60
58 public void removeListener(RelationView<?> relationView, ITuple seed, IQueryRuntimeContextListener listener) { 61 public void removeListener(IInputKey key, RelationView<?> relationView, ITuple seed,
62 IQueryRuntimeContextListener listener) {
59 if (view2Buffers.containsKey(relationView)) { 63 if (view2Buffers.containsKey(relationView)) {
60 Set<ViewUpdateBuffer<?>> buffers = this.view2Buffers.get(relationView); 64 Set<ViewUpdateBuffer<?>> buffers = this.view2Buffers.get(relationView);
61 for (var buffer : buffers) { 65 for (var buffer : buffers) {
62 if (buffer.getUpdateListener().equals(relationView, seed, listener)) { 66 if (buffer.getUpdateListener().equals(key, relationView, seed, listener)) {
63 // remove buffer and terminate immediately, or it will break iterator. 67 // remove buffer and terminate immediately, or it will break iterator.
64 buffers.remove(buffer); 68 buffers.remove(buffer);
65 return; 69 return;
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdate.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdate.java
index c727f046..b9406018 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdate.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdate.java
@@ -3,8 +3,7 @@ package tools.refinery.store.query.viatra.internal.viewupdate;
3import java.util.Arrays; 3import java.util.Arrays;
4import java.util.Objects; 4import java.util.Objects;
5 5
6record ViewUpdate (Object[] tuple, boolean isInsertion) { 6record ViewUpdate(Object[] tuple, boolean isInsertion) {
7
8 @Override 7 @Override
9 public int hashCode() { 8 public int hashCode() {
10 final int prime = 31; 9 final int prime = 31;
@@ -28,7 +27,6 @@ record ViewUpdate (Object[] tuple, boolean isInsertion) {
28 27
29 @Override 28 @Override
30 public String toString() { 29 public String toString() {
31 return "ViewUpdate [" + Arrays.toString(tuple) + "insertion= "+this.isInsertion+"]"; 30 return "ViewUpdate [" + Arrays.toString(tuple) + "insertion= " + this.isInsertion + "]";
32 } 31 }
33
34} 32}
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdateBuffer.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdateBuffer.java
index 5a4243f2..e13a9cb8 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdateBuffer.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdateBuffer.java
@@ -8,6 +8,7 @@ import java.util.List;
8 8
9public class ViewUpdateBuffer<D> { 9public class ViewUpdateBuffer<D> {
10 protected final ViewUpdateTranslator<D> updateListener; 10 protected final ViewUpdateTranslator<D> updateListener;
11
11 protected final List<ViewUpdate> buffer = new ArrayList<>(); 12 protected final List<ViewUpdate> buffer = new ArrayList<>();
12 13
13 public ViewUpdateBuffer(ViewUpdateTranslator<D> updateListener) { 14 public ViewUpdateBuffer(ViewUpdateTranslator<D> updateListener) {
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdateTranslator.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdateTranslator.java
index 2f7f9a9c..62a10e45 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdateTranslator.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/viewupdate/ViewUpdateTranslator.java
@@ -1,5 +1,6 @@
1package tools.refinery.store.query.viatra.internal.viewupdate; 1package tools.refinery.store.query.viatra.internal.viewupdate;
2 2
3import org.eclipse.viatra.query.runtime.matchers.context.IInputKey;
3import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContextListener; 4import org.eclipse.viatra.query.runtime.matchers.context.IQueryRuntimeContextListener;
4import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple; 5import org.eclipse.viatra.query.runtime.matchers.tuple.ITuple;
5import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; 6import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples;
@@ -9,29 +10,38 @@ import tools.refinery.store.query.view.RelationView;
9import java.util.Objects; 10import java.util.Objects;
10 11
11public class ViewUpdateTranslator<D> { 12public class ViewUpdateTranslator<D> {
13 private final IInputKey wrappedKey;
14
12 private final RelationView<D> key; 15 private final RelationView<D> key;
13 16
14 private final ITuple filter; 17 private final ITuple filter;
15 18
16 private final IQueryRuntimeContextListener listener; 19 private final IQueryRuntimeContextListener listener;
17 20
18 public ViewUpdateTranslator(RelationView<D> key, ITuple filter, IQueryRuntimeContextListener listener) { 21 public ViewUpdateTranslator(IInputKey wrappedKey, RelationView<D> key, ITuple filter,
22 IQueryRuntimeContextListener listener) {
19 super(); 23 super();
24 this.wrappedKey = wrappedKey;
20 this.key = key; 25 this.key = key;
21 this.filter = filter; 26 this.filter = filter;
22 this.listener = listener; 27 this.listener = listener;
23 } 28 }
24 29
25 public boolean equals(RelationView<?> relationView, ITuple seed, IQueryRuntimeContextListener listener) { 30 public boolean equals(IInputKey wrappedKey, RelationView<?> relationView, ITuple seed,
26 return key == relationView && filter.equals(seed) && this.listener == listener; 31 IQueryRuntimeContextListener listener) {
32 return this.wrappedKey == wrappedKey && key == relationView && filter.equals(seed) && this.listener == listener;
27 } 33 }
28 34
29 public void processChange(ViewUpdate change) { 35 public void processChange(ViewUpdate change) {
30 listener.update(key, Tuples.flatTupleOf(change.tuple()), change.isInsertion()); 36 listener.update(wrappedKey, Tuples.flatTupleOf(change.tuple()), change.isInsertion());
31 } 37 }
32 38
39 @SuppressWarnings("squid:S1168")
33 public Object[] isMatching(Tuple tuple, D value) { 40 public Object[] isMatching(Tuple tuple, D value) {
34 return isMatching(key.getWrappedKey().transform(tuple, value), filter); 41 if (!key.filter(tuple, value)) {
42 return null;
43 }
44 return isMatching(key.forwardMap(tuple, value), filter);
35 } 45 }
36 46
37 @SuppressWarnings("squid:S1168") 47 @SuppressWarnings("squid:S1168")