aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store-query-viatra
diff options
context:
space:
mode:
authorLibravatar Kristóf Marussy <kristof@marussy.com>2022-10-19 12:22:14 -0400
committerLibravatar Kristóf Marussy <kristof@marussy.com>2022-11-05 19:41:16 +0100
commitf7e6301423e380e86dd4bd42409e2c4c9d6aade0 (patch)
treec5c95c2cdc4e83c6c5514b238bbd3e31c1d09048 /subprojects/store-query-viatra
parentrefactor(frontend): minor theme improvements (diff)
downloadrefinery-f7e6301423e380e86dd4bd42409e2c4c9d6aade0.tar.gz
refinery-f7e6301423e380e86dd4bd42409e2c4c9d6aade0.tar.zst
refinery-f7e6301423e380e86dd4bd42409e2c4c9d6aade0.zip
refactor: DNF query builder
Diffstat (limited to 'subprojects/store-query-viatra')
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/ViatraQueryableModelStore.java58
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraQueryableModel.java38
-rw-r--r--subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/pquery/DNF2PQuery.java126
-rw-r--r--subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/tests/QueryTest.java229
-rw-r--r--subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/tests/QueryTransactionTest.java20
5 files changed, 233 insertions, 238 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 a63abc3a..702eb659 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
@@ -5,9 +5,11 @@ import tools.refinery.store.model.ModelDiffCursor;
5import tools.refinery.store.model.ModelStore; 5import tools.refinery.store.model.ModelStore;
6import tools.refinery.store.model.ModelStoreImpl; 6import tools.refinery.store.model.ModelStoreImpl;
7import tools.refinery.store.model.representation.DataRepresentation; 7import tools.refinery.store.model.representation.DataRepresentation;
8import tools.refinery.store.query.QueryableModel; 8import tools.refinery.store.query.*;
9import tools.refinery.store.query.QueryableModelStore; 9import tools.refinery.store.query.atom.DNFAtom;
10import tools.refinery.store.query.building.*; 10import tools.refinery.store.query.atom.DNFCallAtom;
11import tools.refinery.store.query.atom.EquivalenceAtom;
12import tools.refinery.store.query.atom.RelationViewAtom;
11import tools.refinery.store.query.viatra.internal.RawPatternMatcher; 13import tools.refinery.store.query.viatra.internal.RawPatternMatcher;
12import tools.refinery.store.query.viatra.internal.ViatraQueryableModel; 14import tools.refinery.store.query.viatra.internal.ViatraQueryableModel;
13import tools.refinery.store.query.viatra.internal.pquery.DNF2PQuery; 15import tools.refinery.store.query.viatra.internal.pquery.DNF2PQuery;
@@ -23,10 +25,10 @@ public class ViatraQueryableModelStore implements QueryableModelStore {
23 25
24 protected final Set<RelationView<?>> relationViews; 26 protected final Set<RelationView<?>> relationViews;
25 27
26 protected final Map<DNFPredicate, GenericQuerySpecification<RawPatternMatcher>> predicates; 28 protected final Map<DNF, GenericQuerySpecification<RawPatternMatcher>> predicates;
27 29
28 public ViatraQueryableModelStore(ModelStore store, Set<RelationView<?>> relationViews, 30 public ViatraQueryableModelStore(ModelStore store, Set<RelationView<?>> relationViews,
29 Set<DNFPredicate> predicates) { 31 Set<DNF> predicates) {
30 this.store = store; 32 this.store = store;
31 validateViews(store.getDataRepresentations(), relationViews); 33 validateViews(store.getDataRepresentations(), relationViews);
32 this.relationViews = Collections.unmodifiableSet(relationViews); 34 this.relationViews = Collections.unmodifiableSet(relationViews);
@@ -35,7 +37,7 @@ public class ViatraQueryableModelStore implements QueryableModelStore {
35 } 37 }
36 38
37 public ViatraQueryableModelStore(Set<DataRepresentation<?, ?>> dataRepresentations, 39 public ViatraQueryableModelStore(Set<DataRepresentation<?, ?>> dataRepresentations,
38 Set<RelationView<?>> relationViews, Set<DNFPredicate> predicates) { 40 Set<RelationView<?>> relationViews, Set<DNF> predicates) {
39 this(new ModelStoreImpl(dataRepresentations), relationViews, predicates); 41 this(new ModelStoreImpl(dataRepresentations), relationViews, predicates);
40 } 42 }
41 43
@@ -49,44 +51,46 @@ public class ViatraQueryableModelStore implements QueryableModelStore {
49 } 51 }
50 } 52 }
51 53
52 private void validatePredicates(Set<RelationView<?>> relationViews, Set<DNFPredicate> predicates) { 54 private void validatePredicates(Set<RelationView<?>> relationViews, Set<DNF> predicates) {
53 for (DNFPredicate dnfPredicate : predicates) { 55 for (DNF dnfPredicate : predicates) {
54 for (DNFAnd clause : dnfPredicate.getClauses()) { 56 for (DNFAnd clause : dnfPredicate.getClauses()) {
55 for (DNFAtom atom : clause.getConstraints()) { 57 for (DNFAtom atom : clause.constraints()) {
56 if (atom instanceof RelationAtom relationAtom) { 58 if (atom instanceof RelationViewAtom relationViewAtom) {
57 validateRelationAtom(relationViews, dnfPredicate, relationAtom); 59 validateRelationAtom(relationViews, dnfPredicate, relationViewAtom);
58 } else if (atom instanceof PredicateAtom predicateAtom) { 60 } else if (atom instanceof DNFCallAtom queryCallAtom) {
59 validatePredicateAtom(predicates, dnfPredicate, predicateAtom); 61 validatePredicateAtom(predicates, dnfPredicate, queryCallAtom);
62 } else if (!(atom instanceof EquivalenceAtom)) {
63 throw new IllegalArgumentException("Unknown constraint: " + atom.toString());
60 } 64 }
61 } 65 }
62 } 66 }
63 } 67 }
64 } 68 }
65 69
66 private void validateRelationAtom(Set<RelationView<?>> relationViews, DNFPredicate dnfPredicate, 70 private void validateRelationAtom(Set<RelationView<?>> relationViews, DNF dnfPredicate,
67 RelationAtom relationAtom) { 71 RelationViewAtom relationViewAtom) {
68 if (!relationViews.contains(relationAtom.view())) { 72 if (!relationViews.contains(relationViewAtom.getTarget())) {
69 throw new IllegalArgumentException( 73 throw new IllegalArgumentException(
70 "%s %s contains reference to a view %s that is not in the model.".formatted( 74 "%s %s contains reference to a view %s that is not in the model.".formatted(
71 DNFPredicate.class.getSimpleName(), dnfPredicate.getUniqueName(), 75 DNF.class.getSimpleName(), dnfPredicate.getUniqueName(),
72 relationAtom.view().getName())); 76 relationViewAtom.getTarget().getName()));
73 } 77 }
74 } 78 }
75 79
76 private void validatePredicateAtom(Set<DNFPredicate> predicates, DNFPredicate dnfPredicate, 80 private void validatePredicateAtom(Set<DNF> predicates, DNF dnfPredicate,
77 PredicateAtom predicateAtom) { 81 DNFCallAtom queryCallAtom) {
78 if (!predicates.contains(predicateAtom.getReferred())) { 82 if (!predicates.contains(queryCallAtom.getTarget())) {
79 throw new IllegalArgumentException( 83 throw new IllegalArgumentException(
80 "%s %s contains reference to a predicate %s that is not in the model.".formatted( 84 "%s %s contains reference to a predicate %s that is not in the model.".formatted(
81 DNFPredicate.class.getSimpleName(), dnfPredicate.getUniqueName(), 85 DNF.class.getSimpleName(), dnfPredicate.getUniqueName(),
82 predicateAtom.getReferred().getName())); 86 queryCallAtom.getTarget().getName()));
83 } 87 }
84 } 88 }
85 89
86 private Map<DNFPredicate, GenericQuerySpecification<RawPatternMatcher>> initPredicates(Set<DNFPredicate> predicates) { 90 private Map<DNF, GenericQuerySpecification<RawPatternMatcher>> initPredicates(Set<DNF> predicates) {
87 Map<DNFPredicate, GenericQuerySpecification<RawPatternMatcher>> result = new HashMap<>(); 91 Map<DNF, GenericQuerySpecification<RawPatternMatcher>> result = new HashMap<>();
88 var dnf2PQuery = new DNF2PQuery(); 92 var dnf2PQuery = new DNF2PQuery();
89 for (DNFPredicate dnfPredicate : predicates) { 93 for (DNF dnfPredicate : predicates) {
90 GenericQuerySpecification<RawPatternMatcher> query = dnf2PQuery.translate(dnfPredicate).build(); 94 GenericQuerySpecification<RawPatternMatcher> query = dnf2PQuery.translate(dnfPredicate).build();
91 result.put(dnfPredicate, query); 95 result.put(dnfPredicate, query);
92 } 96 }
@@ -105,7 +109,7 @@ public class ViatraQueryableModelStore implements QueryableModelStore {
105 } 109 }
106 110
107 @Override 111 @Override
108 public Set<DNFPredicate> getPredicates() { 112 public Set<DNF> getPredicates() {
109 return predicates.keySet(); 113 return predicates.keySet();
110 } 114 }
111 115
diff --git a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraQueryableModel.java b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraQueryableModel.java
index 1c15e8f9..cd9fb180 100644
--- a/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraQueryableModel.java
+++ b/subprojects/store-query-viatra/src/main/java/tools/refinery/store/query/viatra/internal/ViatraQueryableModel.java
@@ -12,7 +12,7 @@ import tools.refinery.store.model.representation.DataRepresentation;
12import tools.refinery.store.model.representation.Relation; 12import tools.refinery.store.model.representation.Relation;
13import tools.refinery.store.query.QueryableModel; 13import tools.refinery.store.query.QueryableModel;
14import tools.refinery.store.query.QueryableModelStore; 14import tools.refinery.store.query.QueryableModelStore;
15import tools.refinery.store.query.building.DNFPredicate; 15import tools.refinery.store.query.DNF;
16import tools.refinery.store.tuple.Tuple; 16import tools.refinery.store.tuple.Tuple;
17import tools.refinery.store.tuple.TupleLike; 17import tools.refinery.store.tuple.TupleLike;
18 18
@@ -27,16 +27,16 @@ public class ViatraQueryableModel implements QueryableModel {
27 27
28 protected final Model model; 28 protected final Model model;
29 29
30 protected final Map<DNFPredicate, GenericQuerySpecification<RawPatternMatcher>> predicates2PQuery; 30 protected final Map<DNF, GenericQuerySpecification<RawPatternMatcher>> predicates2PQuery;
31 31
32 protected RelationalScope scope; 32 protected RelationalScope scope;
33 33
34 protected AdvancedViatraQueryEngine engine; 34 protected AdvancedViatraQueryEngine engine;
35 35
36 protected Map<DNFPredicate, RawPatternMatcher> predicate2Matcher; 36 protected Map<DNF, RawPatternMatcher> predicate2Matcher;
37 37
38 public ViatraQueryableModel(QueryableModelStore store, Model model, 38 public ViatraQueryableModel(QueryableModelStore store, Model model,
39 Map<DNFPredicate, GenericQuerySpecification<RawPatternMatcher>> predicates2PQuery) { 39 Map<DNF, GenericQuerySpecification<RawPatternMatcher>> predicates2PQuery) {
40 this.store = store; 40 this.store = store;
41 this.model = model; 41 this.model = model;
42 this.predicates2PQuery = predicates2PQuery; 42 this.predicates2PQuery = predicates2PQuery;
@@ -49,15 +49,15 @@ public class ViatraQueryableModel implements QueryableModel {
49 this.predicate2Matcher = initMatchers(this.engine, this.predicates2PQuery); 49 this.predicate2Matcher = initMatchers(this.engine, this.predicates2PQuery);
50 } 50 }
51 51
52 private Map<DNFPredicate, RawPatternMatcher> initMatchers( 52 private Map<DNF, RawPatternMatcher> initMatchers(
53 AdvancedViatraQueryEngine engine, 53 AdvancedViatraQueryEngine engine,
54 Map<DNFPredicate, GenericQuerySpecification<RawPatternMatcher>> predicates2pQuery) { 54 Map<DNF, GenericQuerySpecification<RawPatternMatcher>> predicates2pQuery) {
55 // 1. prepare group 55 // 1. prepare group
56 IQueryGroup queryGroup = GenericQueryGroup.of(Set.copyOf(predicates2pQuery.values())); 56 IQueryGroup queryGroup = GenericQueryGroup.of(Set.copyOf(predicates2pQuery.values()));
57 engine.prepareGroup(queryGroup, null); 57 engine.prepareGroup(queryGroup, null);
58 58
59 // 2. then get all matchers 59 // 2. then get all matchers
60 Map<DNFPredicate, RawPatternMatcher> result = new HashMap<>(); 60 Map<DNF, RawPatternMatcher> result = new HashMap<>();
61 for (var entry : predicates2pQuery.entrySet()) { 61 for (var entry : predicates2pQuery.entrySet()) {
62 var matcher = engine.getMatcher(entry.getValue()); 62 var matcher = engine.getMatcher(entry.getValue());
63 result.put(entry.getKey(), matcher); 63 result.put(entry.getKey(), matcher);
@@ -71,7 +71,7 @@ public class ViatraQueryableModel implements QueryableModel {
71 } 71 }
72 72
73 @Override 73 @Override
74 public Set<DNFPredicate> getPredicates() { 74 public Set<DNF> getPredicates() {
75 return store.getPredicates(); 75 return store.getPredicates();
76 } 76 }
77 77
@@ -117,7 +117,7 @@ public class ViatraQueryableModel implements QueryableModel {
117 return model.getSize(representation); 117 return model.getSize(representation);
118 } 118 }
119 119
120 protected RawPatternMatcher getMatcher(DNFPredicate predicate) { 120 protected RawPatternMatcher getMatcher(DNF predicate) {
121 var result = this.predicate2Matcher.get(predicate); 121 var result = this.predicate2Matcher.get(predicate);
122 if (result == null) { 122 if (result == null) {
123 throw new IllegalArgumentException("Model does not contain predicate %s".formatted(predicate.getName())); 123 throw new IllegalArgumentException("Model does not contain predicate %s".formatted(predicate.getName()));
@@ -125,8 +125,8 @@ public class ViatraQueryableModel implements QueryableModel {
125 return result; 125 return result;
126 } 126 }
127 127
128 protected void validateParameters(DNFPredicate predicate, Tuple parameters) { 128 protected void validateParameters(DNF predicate, Tuple parameters) {
129 int predicateArity = predicate.getVariables().size(); 129 int predicateArity = predicate.getParameters().size();
130 int parameterArity = parameters.getSize(); 130 int parameterArity = parameters.getSize();
131 if (parameterArity != predicateArity) { 131 if (parameterArity != predicateArity) {
132 throw new IllegalArgumentException( 132 throw new IllegalArgumentException(
@@ -136,45 +136,45 @@ public class ViatraQueryableModel implements QueryableModel {
136 } 136 }
137 137
138 @Override 138 @Override
139 public boolean hasResult(DNFPredicate predicate) { 139 public boolean hasResult(DNF predicate) {
140 return getMatcher(predicate).hasResult(); 140 return getMatcher(predicate).hasResult();
141 } 141 }
142 142
143 @Override 143 @Override
144 public boolean hasResult(DNFPredicate predicate, Tuple parameters) { 144 public boolean hasResult(DNF predicate, Tuple parameters) {
145 validateParameters(predicate, parameters); 145 validateParameters(predicate, parameters);
146 return getMatcher(predicate).hasResult(parameters); 146 return getMatcher(predicate).hasResult(parameters);
147 } 147 }
148 148
149 @Override 149 @Override
150 public Optional<TupleLike> oneResult(DNFPredicate predicate) { 150 public Optional<TupleLike> oneResult(DNF predicate) {
151 return getMatcher(predicate).oneResult(); 151 return getMatcher(predicate).oneResult();
152 } 152 }
153 153
154 @Override 154 @Override
155 public Optional<TupleLike> oneResult(DNFPredicate predicate, Tuple parameters) { 155 public Optional<TupleLike> oneResult(DNF predicate, Tuple parameters) {
156 validateParameters(predicate, parameters); 156 validateParameters(predicate, parameters);
157 return getMatcher(predicate).oneResult(parameters); 157 return getMatcher(predicate).oneResult(parameters);
158 } 158 }
159 159
160 @Override 160 @Override
161 public Stream<TupleLike> allResults(DNFPredicate predicate) { 161 public Stream<TupleLike> allResults(DNF predicate) {
162 return getMatcher(predicate).allResults(); 162 return getMatcher(predicate).allResults();
163 } 163 }
164 164
165 @Override 165 @Override
166 public Stream<TupleLike> allResults(DNFPredicate predicate, Tuple parameters) { 166 public Stream<TupleLike> allResults(DNF predicate, Tuple parameters) {
167 validateParameters(predicate, parameters); 167 validateParameters(predicate, parameters);
168 return getMatcher(predicate).allResults(parameters); 168 return getMatcher(predicate).allResults(parameters);
169 } 169 }
170 170
171 @Override 171 @Override
172 public int countResults(DNFPredicate predicate) { 172 public int countResults(DNF predicate) {
173 return getMatcher(predicate).countResults(); 173 return getMatcher(predicate).countResults();
174 } 174 }
175 175
176 @Override 176 @Override
177 public int countResults(DNFPredicate predicate, Tuple parameters) { 177 public int countResults(DNF predicate, Tuple parameters) {
178 validateParameters(predicate, parameters); 178 validateParameters(predicate, parameters);
179 return getMatcher(predicate).countResults(parameters); 179 return getMatcher(predicate).countResults(parameters);
180 180
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 b6468e76..e3c586a0 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
@@ -11,130 +11,124 @@ import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.Positi
11import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; 11import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint;
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.*;
15import tools.refinery.store.query.atom.DNFAtom;
16import tools.refinery.store.query.atom.EquivalenceAtom;
17import tools.refinery.store.query.atom.DNFCallAtom;
18import tools.refinery.store.query.atom.RelationViewAtom;
15import tools.refinery.store.query.view.RelationView; 19import tools.refinery.store.query.view.RelationView;
16 20
17import java.util.*; 21import java.util.*;
18import java.util.stream.Collectors; 22import java.util.stream.Collectors;
19 23
20public class DNF2PQuery { 24public class DNF2PQuery {
21 private final Set<DNFPredicate> translating = new LinkedHashSet<>(); 25 private final Set<DNF> translating = new LinkedHashSet<>();
22 26
23 private final Map<DNFPredicate, SimplePQuery> dnf2PQueryMap = new HashMap<>(); 27 private final Map<DNF, SimplePQuery> dnf2PQueryMap = new HashMap<>();
24 28
25 private final Map<RelationView<?>, RelationViewWrapper> view2WrapperMap = new HashMap<>(); 29 private final Map<RelationView<?>, RelationViewWrapper> view2WrapperMap = new HashMap<>();
26 30
27 public SimplePQuery translate(DNFPredicate predicate) { 31 public SimplePQuery translate(DNF dnfQuery) {
28 if (translating.contains(predicate)) { 32 if (translating.contains(dnfQuery)) {
29 var path = translating.stream().map(DNFPredicate::getName).collect(Collectors.joining(" -> ")); 33 var path = translating.stream().map(DNF::getName).collect(Collectors.joining(" -> "));
30 throw new IllegalStateException("Circular reference %s -> %s detected".formatted(path, 34 throw new IllegalStateException("Circular reference %s -> %s detected".formatted(path,
31 predicate.getName())); 35 dnfQuery.getName()));
32 } 36 }
33 // We can't use computeIfAbsent here, because translating referenced queries calls this method in a reentrant 37 // 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. 38 // way, which would cause a ConcurrentModificationException with computeIfAbsent.
35 var pQuery = dnf2PQueryMap.get(predicate); 39 var pQuery = dnf2PQueryMap.get(dnfQuery);
36 if (pQuery == null) { 40 if (pQuery == null) {
37 translating.add(predicate); 41 translating.add(dnfQuery);
38 try { 42 try {
39 pQuery = doTranslate(predicate); 43 pQuery = doTranslate(dnfQuery);
40 dnf2PQueryMap.put(predicate, pQuery); 44 dnf2PQueryMap.put(dnfQuery, pQuery);
41 } finally { 45 } finally {
42 translating.remove(predicate); 46 translating.remove(dnfQuery);
43 } 47 }
44 } 48 }
45 return pQuery; 49 return pQuery;
46 } 50 }
47 51
48 private SimplePQuery doTranslate(DNFPredicate predicate) { 52 private SimplePQuery doTranslate(DNF dnfQuery) {
49 var query = new SimplePQuery(predicate.getName()); 53 var pQuery = new SimplePQuery(dnfQuery.getUniqueName());
50 54
51 Map<Variable, PParameter> parameters = new HashMap<>(); 55 Map<Variable, PParameter> parameters = new HashMap<>();
52 for (Variable variable : predicate.getVariables()) { 56 for (Variable variable : dnfQuery.getParameters()) {
53 parameters.put(variable, new PParameter(variable.getName())); 57 parameters.put(variable, new PParameter(variable.getUniqueName()));
54 } 58 }
55 59
56 List<PParameter> parameterList = new ArrayList<>(); 60 List<PParameter> parameterList = new ArrayList<>();
57 for (var param : predicate.getVariables()) { 61 for (var param : dnfQuery.getParameters()) {
58 parameterList.add(parameters.get(param)); 62 parameterList.add(parameters.get(param));
59 } 63 }
60 query.setParameters(parameterList); 64 pQuery.setParameters(parameterList);
61 65
62 for (DNFAnd clause : predicate.getClauses()) { 66 for (DNFAnd clause : dnfQuery.getClauses()) {
63 PBody body = new PBody(query); 67 PBody body = new PBody(pQuery);
64 List<ExportedParameter> symbolicParameters = new ArrayList<>(); 68 List<ExportedParameter> symbolicParameters = new ArrayList<>();
65 for (var param : predicate.getVariables()) { 69 for (var param : dnfQuery.getParameters()) {
66 PVariable pVar = body.getOrCreateVariableByName(param.getName()); 70 PVariable pVar = body.getOrCreateVariableByName(param.getUniqueName());
67 symbolicParameters.add(new ExportedParameter(body, pVar, parameters.get(param))); 71 symbolicParameters.add(new ExportedParameter(body, pVar, parameters.get(param)));
68 } 72 }
69 body.setSymbolicParameters(symbolicParameters); 73 body.setSymbolicParameters(symbolicParameters);
70 query.addBody(body); 74 pQuery.addBody(body);
71 for (DNFAtom constraint : clause.getConstraints()) { 75 for (DNFAtom constraint : clause.constraints()) {
72 translateDNFAtom(constraint, body); 76 translateDNFAtom(constraint, body);
73 } 77 }
74 } 78 }
75 79
76 return query; 80 return pQuery;
77 } 81 }
78 82
79 private void translateDNFAtom(DNFAtom constraint, PBody body) { 83 private void translateDNFAtom(DNFAtom constraint, PBody body) {
80 if (constraint instanceof EquivalenceAtom equivalence) { 84 if (constraint instanceof EquivalenceAtom equivalenceAtom) {
81 translateEquivalenceAtom(equivalence, body); 85 translateEquivalenceAtom(equivalenceAtom, body);
82 } 86 } else if (constraint instanceof RelationViewAtom relationViewAtom) {
83 if (constraint instanceof RelationAtom relation) { 87 translateRelationViewAtom(relationViewAtom, body);
84 translateRelationAtom(relation, body); 88 } else if (constraint instanceof DNFCallAtom dnfCallAtom) {
85 } 89 translateDNFCallAtom(dnfCallAtom, body);
86 if (constraint instanceof PredicateAtom predicate) { 90 } else {
87 translatePredicateAtom(predicate, body); 91 throw new IllegalArgumentException("Unknown constraint: " + constraint.toString());
88 } 92 }
89 } 93 }
90 94
91 private void translateEquivalenceAtom(EquivalenceAtom equivalence, PBody body) { 95 private void translateEquivalenceAtom(EquivalenceAtom equivalence, PBody body) {
92 PVariable varSource = body.getOrCreateVariableByName(equivalence.getLeft().getName()); 96 PVariable varSource = body.getOrCreateVariableByName(equivalence.left().getUniqueName());
93 PVariable varTarget = body.getOrCreateVariableByName(equivalence.getRight().getName()); 97 PVariable varTarget = body.getOrCreateVariableByName(equivalence.right().getUniqueName());
94 if (equivalence.isPositive()) 98 if (equivalence.positive()) {
95 new Equality(body, varSource, varTarget); 99 new Equality(body, varSource, varTarget);
96 else 100 } else {
97 new Inequality(body, varSource, varTarget); 101 new Inequality(body, varSource, varTarget);
102 }
98 } 103 }
99 104
100 private void translateRelationAtom(RelationAtom relation, PBody body) { 105 private void translateRelationViewAtom(RelationViewAtom relationViewAtom, PBody body) {
101 if (relation.substitution().size() != relation.view().getArity()) { 106 int arity = relationViewAtom.getSubstitution().size();
102 throw new IllegalArgumentException("Arity (%d) does not match parameter numbers (%d)".formatted( 107 Object[] variables = new Object[arity];
103 relation.view().getArity(), relation.substitution().size())); 108 for (int i = 0; i < arity; i++) {
104 } 109 var variable = relationViewAtom.getSubstitution().get(i);
105 Object[] variables = new Object[relation.substitution().size()]; 110 variables[i] = body.getOrCreateVariableByName(variable.getUniqueName());
106 for (int i = 0; i < relation.substitution().size(); i++) {
107 variables[i] = body.getOrCreateVariableByName(relation.substitution().get(i).getName());
108 } 111 }
109 new TypeConstraint(body, Tuples.flatTupleOf(variables), wrapView(relation.view())); 112 new TypeConstraint(body, Tuples.flatTupleOf(variables), wrapView(relationViewAtom.getTarget()));
110 } 113 }
111 114
112 private RelationViewWrapper wrapView(RelationView<?> relationView) { 115 private RelationViewWrapper wrapView(RelationView<?> relationView) {
113 return view2WrapperMap.computeIfAbsent(relationView, RelationViewWrapper::new); 116 return view2WrapperMap.computeIfAbsent(relationView, RelationViewWrapper::new);
114 } 117 }
115 118
116 private void translatePredicateAtom(PredicateAtom predicate, PBody body) { 119 private void translateDNFCallAtom(DNFCallAtom queryCallAtom, PBody body) {
117 Object[] variables = new Object[predicate.getSubstitution().size()]; 120 int arity = queryCallAtom.getSubstitution().size();
118 for (int i = 0; i < predicate.getSubstitution().size(); i++) { 121 Object[] variables = new Object[arity];
119 variables[i] = body.getOrCreateVariableByName(predicate.getSubstitution().get(i).getName()); 122 for (int i = 0; i < arity; i++) {
123 var variable = queryCallAtom.getSubstitution().get(i);
124 variables[i] = body.getOrCreateVariableByName(variable.getUniqueName());
120 } 125 }
121 var variablesTuple = Tuples.flatTupleOf(variables); 126 var variablesTuple = Tuples.flatTupleOf(variables);
122 var translatedReferred = translate(predicate.getReferred()); 127 var translatedReferred = translate(queryCallAtom.getTarget());
123 if (predicate.isPositive()) { 128 switch (queryCallAtom.getKind()) {
124 if (predicate.isTransitive()) { 129 case POSITIVE -> new PositivePatternCall(body, variablesTuple, translatedReferred);
125 if (predicate.getSubstitution().size() != 2) { 130 case TRANSITIVE -> new BinaryTransitiveClosure(body, variablesTuple, translatedReferred);
126 throw new IllegalArgumentException("Transitive Predicate Atoms must be binary."); 131 case NEGATIVE -> new NegativePatternCall(body, variablesTuple, translatedReferred);
127 }
128 new BinaryTransitiveClosure(body, variablesTuple, translatedReferred);
129 } else {
130 new PositivePatternCall(body, variablesTuple, translatedReferred);
131 }
132 } else {
133 if (predicate.isTransitive()) {
134 throw new IllegalArgumentException("Transitive Predicate Atoms cannot be negative.");
135 } else {
136 new NegativePatternCall(body, variablesTuple, translatedReferred);
137 }
138 } 132 }
139 } 133 }
140} 134}
diff --git a/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/tests/QueryTest.java b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/tests/QueryTest.java
index d6213b02..8984cb2c 100644
--- a/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/tests/QueryTest.java
+++ b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/tests/QueryTest.java
@@ -3,9 +3,11 @@ package tools.refinery.store.query.viatra.tests;
3import org.junit.jupiter.api.Test; 3import org.junit.jupiter.api.Test;
4import tools.refinery.store.model.representation.Relation; 4import tools.refinery.store.model.representation.Relation;
5import tools.refinery.store.model.representation.TruthValue; 5import tools.refinery.store.model.representation.TruthValue;
6import tools.refinery.store.query.QueryableModel; 6import tools.refinery.store.query.*;
7import tools.refinery.store.query.QueryableModelStore; 7import tools.refinery.store.query.atom.CallKind;
8import tools.refinery.store.query.building.*; 8import tools.refinery.store.query.atom.EquivalenceAtom;
9import tools.refinery.store.query.atom.DNFCallAtom;
10import tools.refinery.store.query.atom.RelationViewAtom;
9import tools.refinery.store.query.viatra.ViatraQueryableModelStore; 11import tools.refinery.store.query.viatra.ViatraQueryableModelStore;
10import tools.refinery.store.query.view.FilteredRelationView; 12import tools.refinery.store.query.view.FilteredRelationView;
11import tools.refinery.store.query.view.KeyOnlyRelationView; 13import tools.refinery.store.query.view.KeyOnlyRelationView;
@@ -25,10 +27,11 @@ class QueryTest {
25 Relation<Boolean> asset = new Relation<>("Asset", 1, false); 27 Relation<Boolean> asset = new Relation<>("Asset", 1, false);
26 RelationView<Boolean> personView = new KeyOnlyRelationView(person); 28 RelationView<Boolean> personView = new KeyOnlyRelationView(person);
27 29
28 List<Variable> parameters = List.of(new Variable("p1")); 30 var p1 = new Variable("p1");
29 RelationAtom personRelationAtom = new RelationAtom(personView, parameters); 31 DNF predicate = DNF.builder("TypeConstraint")
30 DNFAnd clause = new DNFAnd(Collections.emptySet(), List.of(personRelationAtom)); 32 .parameters(p1)
31 DNFPredicate predicate = new DNFPredicate("TypeConstraint", parameters, List.of(clause)); 33 .clause(new RelationViewAtom(personView, p1))
34 .build();
32 35
33 QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, asset), Set.of(personView), 36 QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, asset), Set.of(personView),
34 Set.of(predicate)); 37 Set.of(predicate));
@@ -54,14 +57,14 @@ class QueryTest {
54 57
55 Variable p1 = new Variable("p1"); 58 Variable p1 = new Variable("p1");
56 Variable p2 = new Variable("p2"); 59 Variable p2 = new Variable("p2");
57 List<Variable> parameters = Arrays.asList(p1, p2); 60 DNF predicate = DNF.builder("RelationConstraint")
58 61 .parameters(p1, p2)
59 RelationAtom personRelationAtom1 = new RelationAtom(personView, List.of(p1)); 62 .clause(
60 RelationAtom personRelationAtom2 = new RelationAtom(personView, List.of(p2)); 63 new RelationViewAtom(personView, p1),
61 RelationAtom friendRelationAtom = new RelationAtom(friendMustView, Arrays.asList(p1, p2)); 64 new RelationViewAtom(personView, p1),
62 DNFAnd clause = new DNFAnd(Collections.emptySet(), 65 new RelationViewAtom(friendMustView, p1, p2)
63 Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom)); 66 )
64 DNFPredicate predicate = new DNFPredicate("RelationConstraint", parameters, List.of(clause)); 67 .build();
65 68
66 QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, friend), 69 QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, friend),
67 Set.of(personView, friendMustView), Set.of(predicate)); 70 Set.of(personView, friendMustView), Set.of(predicate));
@@ -93,15 +96,15 @@ class QueryTest {
93 96
94 Variable p1 = new Variable("p1"); 97 Variable p1 = new Variable("p1");
95 Variable p2 = new Variable("p2"); 98 Variable p2 = new Variable("p2");
96 List<Variable> parameters = Arrays.asList(p1, p2); 99 DNF predicate = DNF.builder("RelationConstraint")
97 100 .parameters(p1, p2)
98 RelationAtom personRelationAtom1 = new RelationAtom(personView, List.of(p1)); 101 .clause(
99 RelationAtom personRelationAtom2 = new RelationAtom(personView, List.of(p2)); 102 new RelationViewAtom(personView, p1),
100 RelationAtom friendRelationAtom1 = new RelationAtom(friendMustView, Arrays.asList(p1, p2)); 103 new RelationViewAtom(personView, p2),
101 RelationAtom friendRelationAtom2 = new RelationAtom(friendMustView, Arrays.asList(p2, p1)); 104 new RelationViewAtom(friendMustView, p1, p2),
102 DNFAnd clause = new DNFAnd(Collections.emptySet(), 105 new RelationViewAtom(friendMustView, p2, p1)
103 Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom1, friendRelationAtom2)); 106 )
104 DNFPredicate predicate = new DNFPredicate("RelationConstraint", parameters, List.of(clause)); 107 .build();
105 108
106 QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, friend), 109 QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, friend),
107 Set.of(personView, friendMustView), Set.of(predicate)); 110 Set.of(personView, friendMustView), Set.of(predicate));
@@ -141,14 +144,14 @@ class QueryTest {
141 144
142 Variable p1 = new Variable("p1"); 145 Variable p1 = new Variable("p1");
143 Variable p2 = new Variable("p2"); 146 Variable p2 = new Variable("p2");
144 List<Variable> parameters = List.of(p1); 147 DNF predicate = DNF.builder("RelationConstraint")
145 148 .parameters(p1)
146 RelationAtom personRelationAtom1 = new RelationAtom(personView, List.of(p1)); 149 .clause(
147 RelationAtom personRelationAtom2 = new RelationAtom(personView, List.of(p2)); 150 new RelationViewAtom(personView, p1),
148 RelationAtom friendRelationAtom = new RelationAtom(friendMustView, Arrays.asList(p1, p2)); 151 new RelationViewAtom(personView, p2),
149 DNFAnd clause = new DNFAnd(Set.of(p2), 152 new RelationViewAtom(friendMustView, p1, p2)
150 Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom)); 153 )
151 DNFPredicate predicate = new DNFPredicate("RelationConstraint", parameters, List.of(clause)); 154 .build();
152 155
153 QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, friend), 156 QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, friend),
154 Set.of(personView, friendMustView), Set.of(predicate)); 157 Set.of(personView, friendMustView), Set.of(predicate));
@@ -182,24 +185,19 @@ class QueryTest {
182 185
183 Variable p1 = new Variable("p1"); 186 Variable p1 = new Variable("p1");
184 Variable p2 = new Variable("p2"); 187 Variable p2 = new Variable("p2");
185 List<Variable> parameters = Arrays.asList(p1, p2); 188 DNF predicate = DNF.builder("Or")
186 189 .parameters(p1, p2)
187 // Person-Person friendship 190 .clause(
188 RelationAtom personRelationAtom1 = new RelationAtom(personView, List.of(p1)); 191 new RelationViewAtom(personView, p1),
189 RelationAtom personRelationAtom2 = new RelationAtom(personView, List.of(p2)); 192 new RelationViewAtom(personView, p2),
190 RelationAtom friendRelationAtom1 = new RelationAtom(friendMustView, Arrays.asList(p1, p2)); 193 new RelationViewAtom(friendMustView, p1, p2)
191 DNFAnd clause1 = new DNFAnd(Collections.emptySet(), 194 )
192 Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom1)); 195 .clause(
193 196 new RelationViewAtom(animalView, p1),
194 // Animal-Animal friendship 197 new RelationViewAtom(animalView, p2),
195 RelationAtom animalRelationAtom1 = new RelationAtom(animalView, List.of(p1)); 198 new RelationViewAtom(friendMustView, p1, p2)
196 RelationAtom animalRelationAtom2 = new RelationAtom(animalView, List.of(p2)); 199 )
197 RelationAtom friendRelationAtom2 = new RelationAtom(friendMustView, Arrays.asList(p1, p2)); 200 .build();
198 DNFAnd clause2 = new DNFAnd(Collections.emptySet(),
199 Arrays.asList(animalRelationAtom1, animalRelationAtom2, friendRelationAtom2));
200
201 // No friendship between species
202 DNFPredicate predicate = new DNFPredicate("Or", parameters, Arrays.asList(clause1, clause2));
203 201
204 QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, animal, friend), 202 QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, animal, friend),
205 Set.of(personView, animalView, friendMustView), Set.of(predicate)); 203 Set.of(personView, animalView, friendMustView), Set.of(predicate));
@@ -226,14 +224,14 @@ class QueryTest {
226 224
227 Variable p1 = new Variable("p1"); 225 Variable p1 = new Variable("p1");
228 Variable p2 = new Variable("p2"); 226 Variable p2 = new Variable("p2");
229 List<Variable> parameters = Arrays.asList(p1, p2); 227 DNF predicate = DNF.builder("Equality")
230 228 .parameters(p1, p2)
231 RelationAtom personRelationAtom1 = new RelationAtom(personView, List.of(p1)); 229 .clause(
232 RelationAtom personRelationAtom2 = new RelationAtom(personView, List.of(p2)); 230 new RelationViewAtom(personView, p1),
233 EquivalenceAtom equivalenceAtom = new EquivalenceAtom(true, p1, p2); 231 new RelationViewAtom(personView, p2),
234 DNFAnd clause = new DNFAnd(Collections.emptySet(), 232 new EquivalenceAtom(p1, p2)
235 Arrays.asList(personRelationAtom1, personRelationAtom2, equivalenceAtom)); 233 )
236 DNFPredicate predicate = new DNFPredicate("Equality", parameters, List.of(clause)); 234 .build();
237 235
238 QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person), Set.of(personView), Set.of(predicate)); 236 QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person), Set.of(personView), Set.of(predicate));
239 QueryableModel model = store.createModel(); 237 QueryableModel model = store.createModel();
@@ -258,16 +256,16 @@ class QueryTest {
258 Variable p1 = new Variable("p1"); 256 Variable p1 = new Variable("p1");
259 Variable p2 = new Variable("p2"); 257 Variable p2 = new Variable("p2");
260 Variable p3 = new Variable("p3"); 258 Variable p3 = new Variable("p3");
261 List<Variable> parameters = Arrays.asList(p1, p2, p3); 259 DNF predicate = DNF.builder("Inequality")
262 260 .parameters(p1, p2, p3)
263 RelationAtom personRelationAtom1 = new RelationAtom(personView, List.of(p1)); 261 .clause(
264 RelationAtom personRelationAtom2 = new RelationAtom(personView, List.of(p2)); 262 new RelationViewAtom(personView, p1),
265 RelationAtom friendRelationAtom1 = new RelationAtom(friendMustView, Arrays.asList(p1, p3)); 263 new RelationViewAtom(personView, p2),
266 RelationAtom friendRelationAtom2 = new RelationAtom(friendMustView, Arrays.asList(p2, p3)); 264 new RelationViewAtom(friendMustView, p1, p3),
267 EquivalenceAtom inequivalenceAtom = new EquivalenceAtom(false, p1, p2); 265 new RelationViewAtom(friendMustView, p2, p3),
268 DNFAnd clause = new DNFAnd(Collections.emptySet(), Arrays.asList(personRelationAtom1, personRelationAtom2, 266 new EquivalenceAtom(false, p1, p2)
269 friendRelationAtom1, friendRelationAtom2, inequivalenceAtom)); 267 )
270 DNFPredicate predicate = new DNFPredicate("Inequality", parameters, List.of(clause)); 268 .build();
271 269
272 QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, friend), 270 QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, friend),
273 Set.of(personView, friendMustView), Set.of(predicate)); 271 Set.of(personView, friendMustView), Set.of(predicate));
@@ -294,24 +292,25 @@ class QueryTest {
294 292
295 Variable p1 = new Variable("p1"); 293 Variable p1 = new Variable("p1");
296 Variable p2 = new Variable("p2"); 294 Variable p2 = new Variable("p2");
297 List<Variable> parameters = Arrays.asList(p1, p2); 295 DNF friendPredicate = DNF.builder("RelationConstraint")
298 296 .parameters(p1, p2)
299 RelationAtom personRelationAtom1 = new RelationAtom(personView, List.of(p1)); 297 .clause(
300 RelationAtom personRelationAtom2 = new RelationAtom(personView, List.of(p2)); 298 new RelationViewAtom(personView, p1),
301 RelationAtom friendRelationAtom = new RelationAtom(friendMustView, Arrays.asList(p1, p2)); 299 new RelationViewAtom(personView, p2),
302 DNFAnd clause = new DNFAnd(Collections.emptySet(), 300 new RelationViewAtom(friendMustView, p1, p2)
303 Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom)); 301 )
304 DNFPredicate friendPredicate = new DNFPredicate("RelationConstraint", parameters, List.of(clause)); 302 .build();
305 303
306 Variable p3 = new Variable("p3"); 304 Variable p3 = new Variable("p3");
307 Variable p4 = new Variable("p4"); 305 Variable p4 = new Variable("p4");
308 List<Variable> substitution = Arrays.asList(p3, p4); 306 DNF predicate = DNF.builder("PositivePatternCall")
309 RelationAtom personRelationAtom3 = new RelationAtom(personView, List.of(p3)); 307 .parameters(p3, p4)
310 RelationAtom personRelationAtom4 = new RelationAtom(personView, List.of(p4)); 308 .clause(
311 PredicateAtom friendPredicateAtom = new PredicateAtom(true, false, friendPredicate, substitution); 309 new RelationViewAtom(personView, p3),
312 DNFAnd patternCallClause = new DNFAnd(Collections.emptySet(), 310 new RelationViewAtom(personView, p4),
313 Arrays.asList(personRelationAtom3, personRelationAtom4, friendPredicateAtom)); 311 new DNFCallAtom(friendPredicate, p3, p4)
314 DNFPredicate predicate = new DNFPredicate("PatternCall", substitution, List.of(patternCallClause)); 312 )
313 .build();
315 314
316 QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, friend), 315 QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, friend),
317 Set.of(personView, friendMustView), Set.of(friendPredicate, predicate)); 316 Set.of(personView, friendMustView), Set.of(friendPredicate, predicate));
@@ -339,25 +338,25 @@ class QueryTest {
339 338
340 Variable p1 = new Variable("p1"); 339 Variable p1 = new Variable("p1");
341 Variable p2 = new Variable("p2"); 340 Variable p2 = new Variable("p2");
342 List<Variable> parameters = Arrays.asList(p1, p2); 341 DNF friendPredicate = DNF.builder("RelationConstraint")
343 342 .parameters(p1, p2)
344 RelationAtom personRelationAtom1 = new RelationAtom(personView, List.of(p1)); 343 .clause(
345 RelationAtom personRelationAtom2 = new RelationAtom(personView, List.of(p2)); 344 new RelationViewAtom(personView, p1),
346 RelationAtom friendRelationAtom = new RelationAtom(friendMustView, Arrays.asList(p1, p2)); 345 new RelationViewAtom(personView, p2),
347 DNFAnd clause = new DNFAnd(Collections.emptySet(), 346 new RelationViewAtom(friendMustView, p1, p2)
348 Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom)); 347 )
349 DNFPredicate friendPredicate = new DNFPredicate("RelationConstraint", parameters, List.of(clause)); 348 .build();
350 349
351 Variable p3 = new Variable("p3"); 350 Variable p3 = new Variable("p3");
352 Variable p4 = new Variable("p4"); 351 Variable p4 = new Variable("p4");
353 List<Variable> substitution = Arrays.asList(p3, p4); 352 DNF predicate = DNF.builder("NegativePatternCall")
354 RelationAtom personRelationAtom3 = new RelationAtom(personView, List.of(p3)); 353 .parameters(p3, p4)
355 RelationAtom personRelationAtom4 = new RelationAtom(personView, List.of(p4)); 354 .clause(
356 PredicateAtom friendPredicateAtom = new PredicateAtom(false, false, friendPredicate, substitution); 355 new RelationViewAtom(personView, p3),
357 DNFAnd negativePatternCallClause = new DNFAnd(Collections.emptySet(), 356 new RelationViewAtom(personView, p4),
358 Arrays.asList(personRelationAtom3, personRelationAtom4, friendPredicateAtom)); 357 new DNFCallAtom(CallKind.NEGATIVE, friendPredicate, p3, p4)
359 DNFPredicate predicate = new DNFPredicate("NegativePatternCall", substitution, 358 )
360 List.of(negativePatternCallClause)); 359 .build();
361 360
362 QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, friend), 361 QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, friend),
363 Set.of(personView, friendMustView), Set.of(friendPredicate, predicate)); 362 Set.of(personView, friendMustView), Set.of(friendPredicate, predicate));
@@ -384,25 +383,25 @@ class QueryTest {
384 383
385 Variable p1 = new Variable("p1"); 384 Variable p1 = new Variable("p1");
386 Variable p2 = new Variable("p2"); 385 Variable p2 = new Variable("p2");
387 List<Variable> parameters = Arrays.asList(p1, p2); 386 DNF friendPredicate = DNF.builder("RelationConstraint")
388 387 .parameters(p1, p2)
389 RelationAtom personRelationAtom1 = new RelationAtom(personView, List.of(p1)); 388 .clause(
390 RelationAtom personRelationAtom2 = new RelationAtom(personView, List.of(p2)); 389 new RelationViewAtom(personView, p1),
391 RelationAtom friendRelationAtom = new RelationAtom(friendMustView, Arrays.asList(p1, p2)); 390 new RelationViewAtom(personView, p2),
392 DNFAnd clause = new DNFAnd(Collections.emptySet(), 391 new RelationViewAtom(friendMustView, p1, p2)
393 Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom)); 392 )
394 DNFPredicate friendPredicate = new DNFPredicate("RelationConstraint", parameters, List.of(clause)); 393 .build();
395 394
396 Variable p3 = new Variable("p3"); 395 Variable p3 = new Variable("p3");
397 Variable p4 = new Variable("p4"); 396 Variable p4 = new Variable("p4");
398 List<Variable> substitution = Arrays.asList(p3, p4); 397 DNF predicate = DNF.builder("TransitivePatternCall")
399 RelationAtom personRelationAtom3 = new RelationAtom(personView, List.of(p3)); 398 .parameters(p3, p4)
400 RelationAtom personRelationAtom4 = new RelationAtom(personView, List.of(p4)); 399 .clause(
401 PredicateAtom friendPredicateAtom = new PredicateAtom(true, true, friendPredicate, substitution); 400 new RelationViewAtom(personView, p3),
402 DNFAnd patternCallClause = new DNFAnd(Collections.emptySet(), 401 new RelationViewAtom(personView, p4),
403 Arrays.asList(personRelationAtom3, personRelationAtom4, friendPredicateAtom)); 402 new DNFCallAtom(CallKind.TRANSITIVE, friendPredicate, p3, p4)
404 DNFPredicate predicate = new DNFPredicate("TransitivePatternCall", substitution, 403 )
405 List.of(patternCallClause)); 404 .build();
406 405
407 QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, friend), 406 QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, friend),
408 Set.of(personView, friendMustView), Set.of(friendPredicate, predicate)); 407 Set.of(personView, friendMustView), Set.of(friendPredicate, predicate));
diff --git a/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/tests/QueryTransactionTest.java b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/tests/QueryTransactionTest.java
index f57bca2b..a555f024 100644
--- a/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/tests/QueryTransactionTest.java
+++ b/subprojects/store-query-viatra/src/test/java/tools/refinery/store/query/viatra/tests/QueryTransactionTest.java
@@ -1,20 +1,17 @@
1package tools.refinery.store.query.viatra.tests; 1package tools.refinery.store.query.viatra.tests;
2 2
3import org.junit.jupiter.api.Test; 3import org.junit.jupiter.api.Test;
4import tools.refinery.store.tuple.Tuple;
5import tools.refinery.store.model.representation.Relation; 4import tools.refinery.store.model.representation.Relation;
5import tools.refinery.store.query.DNF;
6import tools.refinery.store.query.QueryableModel; 6import tools.refinery.store.query.QueryableModel;
7import tools.refinery.store.query.QueryableModelStore; 7import tools.refinery.store.query.QueryableModelStore;
8import tools.refinery.store.query.building.DNFAnd; 8import tools.refinery.store.query.Variable;
9import tools.refinery.store.query.building.DNFPredicate; 9import tools.refinery.store.query.atom.RelationViewAtom;
10import tools.refinery.store.query.building.RelationAtom;
11import tools.refinery.store.query.building.Variable;
12import tools.refinery.store.query.viatra.ViatraQueryableModelStore; 10import tools.refinery.store.query.viatra.ViatraQueryableModelStore;
13import tools.refinery.store.query.view.KeyOnlyRelationView; 11import tools.refinery.store.query.view.KeyOnlyRelationView;
14import tools.refinery.store.query.view.RelationView; 12import tools.refinery.store.query.view.RelationView;
13import tools.refinery.store.tuple.Tuple;
15 14
16import java.util.Collections;
17import java.util.List;
18import java.util.Set; 15import java.util.Set;
19 16
20import static org.junit.jupiter.api.Assertions.assertEquals; 17import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -26,10 +23,11 @@ class QueryTransactionTest {
26 Relation<Boolean> asset = new Relation<>("Asset", 1, false); 23 Relation<Boolean> asset = new Relation<>("Asset", 1, false);
27 RelationView<Boolean> personView = new KeyOnlyRelationView(person); 24 RelationView<Boolean> personView = new KeyOnlyRelationView(person);
28 25
29 List<Variable> parameters = List.of(new Variable("p1")); 26 var p1 = new Variable("p1");
30 RelationAtom personRelationAtom = new RelationAtom(personView, parameters); 27 DNF predicate = DNF.builder("TypeConstraint")
31 DNFAnd clause = new DNFAnd(Collections.emptySet(), List.of(personRelationAtom)); 28 .parameters(p1)
32 DNFPredicate predicate = new DNFPredicate("TypeConstraint", parameters, List.of(clause)); 29 .clause(new RelationViewAtom(personView, p1))
30 .build();
33 31
34 QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, asset), Set.of(personView), 32 QueryableModelStore store = new ViatraQueryableModelStore(Set.of(person, asset), Set.of(personView),
35 Set.of(predicate)); 33 Set.of(predicate));