aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--store/src/main/java/tools/refinery/store/query/internal/DNF2PQuery.java184
-rw-r--r--store/src/test/java/tools/refinery/store/query/test/QueryTest.java351
2 files changed, 535 insertions, 0 deletions
diff --git a/store/src/main/java/tools/refinery/store/query/internal/DNF2PQuery.java b/store/src/main/java/tools/refinery/store/query/internal/DNF2PQuery.java
new file mode 100644
index 00000000..c9c8245b
--- /dev/null
+++ b/store/src/main/java/tools/refinery/store/query/internal/DNF2PQuery.java
@@ -0,0 +1,184 @@
1package tools.refinery.store.query.internal;
2
3import java.util.ArrayList;
4import java.util.HashMap;
5import java.util.InputMismatchException;
6import java.util.LinkedHashSet;
7import java.util.List;
8import java.util.Map;
9import java.util.Set;
10
11import org.eclipse.viatra.query.runtime.api.GenericPatternMatcher;
12import org.eclipse.viatra.query.runtime.api.GenericQuerySpecification;
13import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine;
14import org.eclipse.viatra.query.runtime.api.scope.QueryScope;
15import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint;
16import org.eclipse.viatra.query.runtime.matchers.psystem.PBody;
17import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable;
18import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality;
19import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter;
20import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Inequality;
21import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.NegativePatternCall;
22import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.BinaryTransitiveClosure;
23import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall;
24import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint;
25import org.eclipse.viatra.query.runtime.matchers.psystem.queries.BasePQuery;
26import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter;
27import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility;
28import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples;
29
30import tools.refinery.store.query.RelationalScope;
31import tools.refinery.store.query.building.DNFAnd;
32import tools.refinery.store.query.building.DNFAtom;
33import tools.refinery.store.query.building.DNFPredicate;
34import tools.refinery.store.query.building.EquivalenceAtom;
35import tools.refinery.store.query.building.PredicateAtom;
36import tools.refinery.store.query.building.RelationAtom;
37import tools.refinery.store.query.building.Variable;
38
39public class DNF2PQuery {
40 private static Map<DNFPredicate, SimplePQuery> DNF2PQueryMap = new HashMap<>();
41
42 public static SimplePQuery translate(DNFPredicate predicate) {
43 SimplePQuery query = DNF2PQueryMap.get(predicate);
44 if (query != null) {
45 return query;
46 }
47 query = new DNF2PQuery().new SimplePQuery(predicate.getName());
48 Map<Variable, PParameter> parameters = new HashMap<>();
49
50 predicate.getVariables().forEach(variable -> parameters.put(variable, new PParameter(variable.getName())));
51 query.setParameter(new ArrayList<>(parameters.values()));
52 for (DNFAnd clause : predicate.getClauses()) {
53 PBody body = new PBody(query);
54 List<ExportedParameter> symbolicParameters = new ArrayList<>();
55 parameters.forEach((variable, parameter) -> {
56 PVariable pVar = body.getOrCreateVariableByName(variable.getName());
57 symbolicParameters.add(new ExportedParameter(body, pVar, parameter));
58 });
59 body.setSymbolicParameters(symbolicParameters);
60 query.addBody(body);
61 for (DNFAtom constraint : clause.getConstraints()) {
62 translateDNFAtom(constraint, body);
63 }
64 }
65 DNF2PQueryMap.put(predicate, query);
66 return query;
67 }
68
69 private static void translateDNFAtom(DNFAtom constraint, PBody body) {
70 if (constraint instanceof EquivalenceAtom equivalence) {
71 translateEquivalenceAtom(equivalence, body);
72 }
73 if (constraint instanceof RelationAtom relation) {
74 translateRelationAtom(relation, body);
75 }
76 if (constraint instanceof PredicateAtom predicate) {
77 translatePredicateAtom(predicate, body);
78 }
79 }
80
81 private static void translateEquivalenceAtom(EquivalenceAtom equivalence, PBody body) {
82 PVariable varSource = body.getOrCreateVariableByName(equivalence.getLeft().getName());
83 PVariable varTarget = body.getOrCreateVariableByName(equivalence.getRight().getName());
84 if (equivalence.isPositive())
85 new Equality(body, varSource, varTarget);
86 else
87 new Inequality(body, varSource, varTarget);
88 }
89
90 private static void translateRelationAtom(RelationAtom relation, PBody body) {
91 if (relation.getSubstitution().size() != relation.getView().getArity()) {
92 throw new IllegalArgumentException("Arity (" + relation.getView().getArity()
93 + ") does not match parameter numbers (" + relation.getSubstitution().size() + ")");
94 }
95 Object[] variables = new Object[relation.getSubstitution().size()];
96 for (int i = 0; i < relation.getSubstitution().size(); i++) {
97 variables[i] = body.getOrCreateVariableByName(relation.getSubstitution().get(i).getName());
98 }
99 new TypeConstraint(body, Tuples.flatTupleOf(variables), relation.getView());
100 }
101
102 private static void translatePredicateAtom(PredicateAtom predicate, PBody body) {
103 Object[] variables = new Object[predicate.getSubstitution().size()];
104 for (int i = 0; i < predicate.getSubstitution().size(); i++) {
105 variables[i] = body.getOrCreateVariableByName(predicate.getSubstitution().get(i).getName());
106 }
107 if (predicate.isPositive()) {
108 if (predicate.isTransitive()) {
109 if (predicate.getSubstitution().size() != 2) {
110 throw new IllegalArgumentException("Transitive Predicate Atoms must be binary.");
111 }
112 new BinaryTransitiveClosure(body, Tuples.flatTupleOf(variables),
113 DNF2PQuery.translate(predicate.getReferred()));
114 } else {
115 new PositivePatternCall(body, Tuples.flatTupleOf(variables),
116 DNF2PQuery.translate(predicate.getReferred()));
117 }
118 } else {
119 if (predicate.isTransitive()) {
120 throw new InputMismatchException("Transitive Predicate Atoms cannot be negative.");
121 } else {
122 new NegativePatternCall(body, Tuples.flatTupleOf(variables),
123 DNF2PQuery.translate(predicate.getReferred()));
124 }
125 }
126 }
127
128 public class SimplePQuery extends BasePQuery {
129
130 private String fullyQualifiedName;
131 private List<PParameter> parameters;
132 private LinkedHashSet<PBody> bodies = new LinkedHashSet<>();
133
134 public SimplePQuery(String name) {
135 super(PVisibility.PUBLIC);
136 fullyQualifiedName = name;
137 }
138
139 @Override
140 public String getFullyQualifiedName() {
141 return fullyQualifiedName;
142 }
143
144 public void setParameter(List<PParameter> parameters) {
145 this.parameters = parameters;
146 }
147
148 @Override
149 public List<PParameter> getParameters() {
150 return parameters;
151 }
152
153 public void addBody(PBody body) {
154 bodies.add(body);
155 }
156
157 @Override
158 protected Set<PBody> doGetContainedBodies() {
159 setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED));
160 return bodies;
161 }
162
163 public GenericQuerySpecification<GenericPatternMatcher> build() {
164 return new GenericQuerySpecification<GenericPatternMatcher>(this) {
165
166 @Override
167 public Class<? extends QueryScope> getPreferredScopeClass() {
168 return RelationalScope.class;
169 }
170
171 @Override
172 protected GenericPatternMatcher instantiate(ViatraQueryEngine engine) {
173 return defaultInstantiate(engine);
174 }
175
176 @Override
177 public GenericPatternMatcher instantiate() {
178 return new GenericPatternMatcher(this);
179 }
180
181 };
182 }
183 }
184} \ No newline at end of file
diff --git a/store/src/test/java/tools/refinery/store/query/test/QueryTest.java b/store/src/test/java/tools/refinery/store/query/test/QueryTest.java
index 38aa130a..b1014700 100644
--- a/store/src/test/java/tools/refinery/store/query/test/QueryTest.java
+++ b/store/src/test/java/tools/refinery/store/query/test/QueryTest.java
@@ -4,7 +4,10 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
4import static org.junit.jupiter.api.Assertions.assertFalse; 4import static org.junit.jupiter.api.Assertions.assertFalse;
5import static org.junit.jupiter.api.Assertions.assertTrue; 5import static org.junit.jupiter.api.Assertions.assertTrue;
6 6
7import java.util.Arrays;
7import java.util.Collection; 8import java.util.Collection;
9import java.util.HashSet;
10import java.util.List;
8import java.util.Set; 11import java.util.Set;
9 12
10import org.eclipse.viatra.query.runtime.api.AdvancedViatraQueryEngine; 13import org.eclipse.viatra.query.runtime.api.AdvancedViatraQueryEngine;
@@ -12,6 +15,7 @@ import org.eclipse.viatra.query.runtime.api.GenericPatternMatch;
12import org.eclipse.viatra.query.runtime.api.GenericPatternMatcher; 15import org.eclipse.viatra.query.runtime.api.GenericPatternMatcher;
13import org.eclipse.viatra.query.runtime.api.GenericQuerySpecification; 16import org.eclipse.viatra.query.runtime.api.GenericQuerySpecification;
14import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; 17import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine;
18import org.junit.jupiter.api.Disabled;
15import org.junit.jupiter.api.Test; 19import org.junit.jupiter.api.Test;
16 20
17import tools.refinery.store.model.Model; 21import tools.refinery.store.model.Model;
@@ -21,6 +25,13 @@ import tools.refinery.store.model.Tuple;
21import tools.refinery.store.model.representation.Relation; 25import tools.refinery.store.model.representation.Relation;
22import tools.refinery.store.model.representation.TruthValue; 26import tools.refinery.store.model.representation.TruthValue;
23import tools.refinery.store.query.RelationalScope; 27import tools.refinery.store.query.RelationalScope;
28import tools.refinery.store.query.building.DNFAnd;
29import tools.refinery.store.query.building.DNFPredicate;
30import tools.refinery.store.query.building.EquivalenceAtom;
31import tools.refinery.store.query.building.PredicateAtom;
32import tools.refinery.store.query.building.RelationAtom;
33import tools.refinery.store.query.building.Variable;
34import tools.refinery.store.query.internal.DNF2PQuery;
24import tools.refinery.store.query.internal.PredicateTranslator; 35import tools.refinery.store.query.internal.PredicateTranslator;
25import tools.refinery.store.query.view.FilteredRelationView; 36import tools.refinery.store.query.view.FilteredRelationView;
26import tools.refinery.store.query.view.FunctionalRelationView; 37import tools.refinery.store.query.view.FunctionalRelationView;
@@ -87,4 +98,344 @@ class QueryTest {
87 System.out.println(personMatch); 98 System.out.println(personMatch);
88 } 99 }
89 } 100 }
101
102 @Test
103 @Disabled
104 void typeConstraintTest() {
105 Relation<Boolean> person = new Relation<>("Person", 1, false);
106 Relation<Boolean> asset = new Relation<>("Asset", 1, false);
107 RelationView<Boolean> persionView = new KeyOnlyRelationView(person);
108
109 List<Variable> parameters = Arrays.asList(new Variable("p1"));
110 RelationAtom personRelationAtom = new RelationAtom(persionView, parameters);
111 DNFAnd clause = new DNFAnd(new HashSet<>(parameters), Arrays.asList(personRelationAtom));
112 DNFPredicate predicate = new DNFPredicate("TypeConstraint", parameters, Arrays.asList(clause));
113 GenericQuerySpecification<GenericPatternMatcher> query = DNF2PQuery.translate(predicate).build();
114
115 ModelStore store = new ModelStoreImpl(Set.of(person, asset));
116 Model model = store.createModel();
117
118 model.put(person, Tuple.of(0), true);
119 model.put(person, Tuple.of(1), true);
120 model.put(asset, Tuple.of(1), true);
121 model.put(asset, Tuple.of(2), true);
122
123 RelationalScope scope = new RelationalScope(model, Set.of(persionView));
124
125 ViatraQueryEngine engine = AdvancedViatraQueryEngine.on(scope);
126 GenericPatternMatcher matcher = engine.getMatcher(query);
127
128 assertEquals(2, matcher.countMatches());
129 }
130
131 @Test
132 @Disabled
133 void relationConstraintTest() {
134 Relation<Boolean> person = new Relation<Boolean>("Person", 1, false);
135 Relation<TruthValue> friend = new Relation<>("friend", 2, TruthValue.FALSE);
136 RelationView<Boolean> persionView = new KeyOnlyRelationView(person);
137 RelationView<TruthValue> friendMustView = new FilteredRelationView<TruthValue>(friend, (k, v) -> v.must());
138
139 Variable p1 = new Variable("p1");
140 Variable p2 = new Variable("p2");
141 List<Variable> parameters = Arrays.asList(p1, p2);
142
143 RelationAtom personRelationAtom1 = new RelationAtom(persionView, Arrays.asList(p1));
144 RelationAtom personRelationAtom2 = new RelationAtom(persionView, Arrays.asList(p2));
145 RelationAtom friendRelationAtom = new RelationAtom(friendMustView, Arrays.asList(p1, p2));
146 DNFAnd clause = new DNFAnd(new HashSet<>(parameters),
147 Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom));
148 DNFPredicate predicate = new DNFPredicate("RelationConstraint", parameters, Arrays.asList(clause));
149
150 GenericQuerySpecification<GenericPatternMatcher> query = DNF2PQuery.translate(predicate).build();
151
152 ModelStore store = new ModelStoreImpl(Set.of(person, friend));
153 Model model = store.createModel();
154
155 model.put(person, Tuple.of(0), true);
156 model.put(person, Tuple.of(1), true);
157 model.put(person, Tuple.of(2), true);
158 model.put(friend, Tuple.of(0, 1), TruthValue.TRUE);
159 model.put(friend, Tuple.of(1, 0), TruthValue.TRUE);
160 model.put(friend, Tuple.of(1, 2), TruthValue.TRUE);
161
162 RelationalScope scope = new RelationalScope(model, Set.of(persionView, friendMustView));
163
164 ViatraQueryEngine engine = AdvancedViatraQueryEngine.on(scope);
165 GenericPatternMatcher matcher = engine.getMatcher(query);
166
167 assertEquals(3, matcher.countMatches());
168 }
169
170 @Test
171 @Disabled
172 void patternCallTest() {
173 Relation<Boolean> person = new Relation<Boolean>("Person", 1, false);
174 Relation<TruthValue> friend = new Relation<>("friend", 2, TruthValue.FALSE);
175 RelationView<Boolean> persionView = new KeyOnlyRelationView(person);
176 RelationView<TruthValue> friendMustView = new FilteredRelationView<TruthValue>(friend, (k, v) -> v.must());
177
178 Variable p1 = new Variable("p1");
179 Variable p2 = new Variable("p2");
180 List<Variable> parameters = Arrays.asList(p1, p2);
181
182 RelationAtom personRelationAtom1 = new RelationAtom(persionView, Arrays.asList(p1));
183 RelationAtom personRelationAtom2 = new RelationAtom(persionView, Arrays.asList(p2));
184 RelationAtom friendRelationAtom = new RelationAtom(friendMustView, Arrays.asList(p1, p2));
185 DNFAnd clause = new DNFAnd(new HashSet<>(parameters),
186 Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom));
187 DNFPredicate friendPredicate = new DNFPredicate("RelationConstraint", parameters, Arrays.asList(clause));
188
189 Variable p3 = new Variable("p3");
190 Variable p4 = new Variable("p4");
191 List<Variable> substitution = Arrays.asList(p3, p4);
192 RelationAtom personRelationAtom3 = new RelationAtom(persionView, Arrays.asList(p3));
193 RelationAtom personRelationAtom4 = new RelationAtom(persionView, Arrays.asList(p4));
194 PredicateAtom friendPredicateAtom = new PredicateAtom(true, false, friendPredicate, substitution);
195 DNFAnd patternCallClause = new DNFAnd(new HashSet<>(substitution),
196 Arrays.asList(personRelationAtom3, personRelationAtom4, friendPredicateAtom));
197 DNFPredicate predicate = new DNFPredicate("PatternCall", substitution, Arrays.asList(patternCallClause));
198
199 GenericQuerySpecification<GenericPatternMatcher> query = DNF2PQuery.translate(predicate).build();
200
201 ModelStore store = new ModelStoreImpl(Set.of(person, friend));
202 Model model = store.createModel();
203
204 model.put(person, Tuple.of(0), true);
205 model.put(person, Tuple.of(1), true);
206 model.put(person, Tuple.of(2), true);
207 model.put(friend, Tuple.of(0, 1), TruthValue.TRUE);
208 model.put(friend, Tuple.of(1, 0), TruthValue.TRUE);
209 model.put(friend, Tuple.of(1, 2), TruthValue.TRUE);
210
211 RelationalScope scope = new RelationalScope(model, Set.of(persionView, friendMustView));
212
213 ViatraQueryEngine engine = AdvancedViatraQueryEngine.on(scope);
214 GenericPatternMatcher matcher = engine.getMatcher(query);
215
216 assertEquals(3, matcher.countMatches());
217 }
218
219 @Test
220 @Disabled
221 void negativePatternCallTest() {
222 Relation<Boolean> person = new Relation<Boolean>("Person", 1, false);
223 Relation<TruthValue> friend = new Relation<>("friend", 2, TruthValue.FALSE);
224 RelationView<Boolean> persionView = new KeyOnlyRelationView(person);
225 RelationView<TruthValue> friendMustView = new FilteredRelationView<TruthValue>(friend, (k, v) -> v.must());
226
227 Variable p1 = new Variable("p1");
228 Variable p2 = new Variable("p2");
229 List<Variable> parameters = Arrays.asList(p1, p2);
230
231 RelationAtom personRelationAtom1 = new RelationAtom(persionView, Arrays.asList(p1));
232 RelationAtom personRelationAtom2 = new RelationAtom(persionView, Arrays.asList(p2));
233 RelationAtom friendRelationAtom = new RelationAtom(friendMustView, Arrays.asList(p1, p2));
234 DNFAnd clause = new DNFAnd(new HashSet<>(parameters),
235 Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom));
236 DNFPredicate friendPredicate = new DNFPredicate("RelationConstraint", parameters, Arrays.asList(clause));
237
238 Variable p3 = new Variable("p3");
239 Variable p4 = new Variable("p4");
240 List<Variable> substitution = Arrays.asList(p3, p4);
241 RelationAtom personRelationAtom3 = new RelationAtom(persionView, Arrays.asList(p3));
242 RelationAtom personRelationAtom4 = new RelationAtom(persionView, Arrays.asList(p4));
243 PredicateAtom friendPredicateAtom = new PredicateAtom(false, false, friendPredicate, substitution);
244 DNFAnd negativePatternCallClause = new DNFAnd(new HashSet<>(substitution),
245 Arrays.asList(personRelationAtom3, personRelationAtom4, friendPredicateAtom));
246 DNFPredicate predicate = new DNFPredicate("NegativePatternCall", substitution,
247 Arrays.asList(negativePatternCallClause));
248
249 GenericQuerySpecification<GenericPatternMatcher> query = DNF2PQuery.translate(predicate).build();
250
251 ModelStore store = new ModelStoreImpl(Set.of(person, friend));
252 Model model = store.createModel();
253
254 model.put(person, Tuple.of(0), true);
255 model.put(person, Tuple.of(1), true);
256 model.put(person, Tuple.of(2), true);
257 model.put(friend, Tuple.of(0, 1), TruthValue.TRUE);
258 model.put(friend, Tuple.of(1, 0), TruthValue.TRUE);
259 model.put(friend, Tuple.of(1, 2), TruthValue.TRUE);
260
261 RelationalScope scope = new RelationalScope(model, Set.of(persionView, friendMustView));
262
263 ViatraQueryEngine engine = AdvancedViatraQueryEngine.on(scope);
264 GenericPatternMatcher matcher = engine.getMatcher(query);
265
266 assertEquals(6, matcher.countMatches());
267 }
268
269 @Test
270 @Disabled
271 void equalityTest() {
272 Relation<Boolean> person = new Relation<Boolean>("Person", 1, false);
273 RelationView<Boolean> persionView = new KeyOnlyRelationView(person);
274
275 Variable p1 = new Variable("p1");
276 Variable p2 = new Variable("p2");
277 List<Variable> parameters = Arrays.asList(p1, p2);
278
279 RelationAtom personRelationAtom1 = new RelationAtom(persionView, Arrays.asList(p1));
280 RelationAtom personRelationAtom2 = new RelationAtom(persionView, Arrays.asList(p2));
281 EquivalenceAtom equivalenceAtom = new EquivalenceAtom(true, p1, p2);
282 DNFAnd clause = new DNFAnd(new HashSet<>(parameters),
283 Arrays.asList(personRelationAtom1, personRelationAtom2, equivalenceAtom));
284 DNFPredicate predicate = new DNFPredicate("Equality", parameters, Arrays.asList(clause));
285
286 GenericQuerySpecification<GenericPatternMatcher> query = DNF2PQuery.translate(predicate).build();
287
288 ModelStore store = new ModelStoreImpl(Set.of(person));
289 Model model = store.createModel();
290
291 model.put(person, Tuple.of(0), true);
292 model.put(person, Tuple.of(1), true);
293 model.put(person, Tuple.of(2), true);
294
295 RelationalScope scope = new RelationalScope(model, Set.of(persionView));
296
297 ViatraQueryEngine engine = AdvancedViatraQueryEngine.on(scope);
298 GenericPatternMatcher matcher = engine.getMatcher(query);
299
300 assertEquals(3, matcher.countMatches());
301 }
302
303 @Test
304 @Disabled
305 void inequalityTest() {
306 Relation<Boolean> person = new Relation<Boolean>("Person", 1, false);
307 Relation<TruthValue> friend = new Relation<>("friend", 2, TruthValue.FALSE);
308 RelationView<Boolean> persionView = new KeyOnlyRelationView(person);
309 RelationView<TruthValue> friendMustView = new FilteredRelationView<TruthValue>(friend, (k, v) -> v.must());
310
311 Variable p1 = new Variable("p1");
312 Variable p2 = new Variable("p2");
313 Variable p3 = new Variable("p3");
314 List<Variable> parameters = Arrays.asList(p1, p2, p3);
315
316 RelationAtom personRelationAtom1 = new RelationAtom(persionView, Arrays.asList(p1));
317 RelationAtom personRelationAtom2 = new RelationAtom(persionView, Arrays.asList(p2));
318 RelationAtom friendRelationAtom1 = new RelationAtom(friendMustView, Arrays.asList(p1, p3));
319 RelationAtom friendRelationAtom2 = new RelationAtom(friendMustView, Arrays.asList(p2, p3));
320 EquivalenceAtom inequivalenceAtom = new EquivalenceAtom(false, p1, p2);
321 DNFAnd clause = new DNFAnd(new HashSet<>(parameters), Arrays.asList(personRelationAtom1, personRelationAtom2,
322 friendRelationAtom1, friendRelationAtom2, inequivalenceAtom));
323 DNFPredicate predicate = new DNFPredicate("Inequality", parameters, Arrays.asList(clause));
324
325 GenericQuerySpecification<GenericPatternMatcher> query = DNF2PQuery.translate(predicate).build();
326
327 ModelStore store = new ModelStoreImpl(Set.of(person, friend));
328 Model model = store.createModel();
329
330 model.put(person, Tuple.of(0), true);
331 model.put(person, Tuple.of(1), true);
332 model.put(person, Tuple.of(2), true);
333 model.put(friend, Tuple.of(0, 2), TruthValue.TRUE);
334 model.put(friend, Tuple.of(1, 2), TruthValue.TRUE);
335
336 RelationalScope scope = new RelationalScope(model, Set.of(persionView, friendMustView));
337
338 ViatraQueryEngine engine = AdvancedViatraQueryEngine.on(scope);
339 GenericPatternMatcher matcher = engine.getMatcher(query);
340
341 assertEquals(2, matcher.countMatches());
342 }
343
344 @Test
345 @Disabled
346 void transitivePatternCallTest() {
347 Relation<Boolean> person = new Relation<Boolean>("Person", 1, false);
348 Relation<TruthValue> friend = new Relation<>("friend", 2, TruthValue.FALSE);
349 RelationView<Boolean> persionView = new KeyOnlyRelationView(person);
350 RelationView<TruthValue> friendMustView = new FilteredRelationView<TruthValue>(friend, (k, v) -> v.must());
351
352 Variable p1 = new Variable("p1");
353 Variable p2 = new Variable("p2");
354 List<Variable> parameters = Arrays.asList(p1, p2);
355
356 RelationAtom personRelationAtom1 = new RelationAtom(persionView, Arrays.asList(p1));
357 RelationAtom personRelationAtom2 = new RelationAtom(persionView, Arrays.asList(p2));
358 RelationAtom friendRelationAtom = new RelationAtom(friendMustView, Arrays.asList(p1, p2));
359 DNFAnd clause = new DNFAnd(new HashSet<>(parameters),
360 Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom));
361 DNFPredicate friendPredicate = new DNFPredicate("RelationConstraint", parameters, Arrays.asList(clause));
362
363 Variable p3 = new Variable("p3");
364 Variable p4 = new Variable("p4");
365 List<Variable> substitution = Arrays.asList(p3, p4);
366 RelationAtom personRelationAtom3 = new RelationAtom(persionView, Arrays.asList(p3));
367 RelationAtom personRelationAtom4 = new RelationAtom(persionView, Arrays.asList(p4));
368 PredicateAtom friendPredicateAtom = new PredicateAtom(true, true, friendPredicate, substitution);
369 DNFAnd patternCallClause = new DNFAnd(new HashSet<>(substitution),
370 Arrays.asList(personRelationAtom3, personRelationAtom4, friendPredicateAtom));
371 DNFPredicate predicate = new DNFPredicate("TransitivePatternCall", substitution,
372 Arrays.asList(patternCallClause));
373
374 GenericQuerySpecification<GenericPatternMatcher> query = DNF2PQuery.translate(predicate).build();
375
376 ModelStore store = new ModelStoreImpl(Set.of(person, friend));
377 Model model = store.createModel();
378
379 model.put(person, Tuple.of(0), true);
380 model.put(person, Tuple.of(1), true);
381 model.put(person, Tuple.of(2), true);
382 model.put(friend, Tuple.of(0, 1), TruthValue.TRUE);
383 model.put(friend, Tuple.of(1, 2), TruthValue.TRUE);
384
385 RelationalScope scope = new RelationalScope(model, Set.of(persionView, friendMustView));
386
387 ViatraQueryEngine engine = AdvancedViatraQueryEngine.on(scope);
388 GenericPatternMatcher matcher = engine.getMatcher(query);
389
390 assertEquals(3, matcher.countMatches());
391 }
392
393 @Test
394 @Disabled
395 void orTest() {
396 Relation<Boolean> person = new Relation<>("Person", 1, false);
397 Relation<Boolean> animal = new Relation<>("Animal", 1, false);
398 Relation<TruthValue> friend = new Relation<>("friend", 2, TruthValue.FALSE);
399 RelationView<Boolean> persionView = new KeyOnlyRelationView(person);
400 RelationView<Boolean> animalView = new KeyOnlyRelationView(animal);
401 RelationView<TruthValue> friendMustView = new FilteredRelationView<TruthValue>(friend, (k, v) -> v.must());
402
403 Variable p1 = new Variable("p1");
404 Variable p2 = new Variable("p2");
405 List<Variable> parameters = Arrays.asList(p1, p2);
406
407 RelationAtom personRelationAtom1 = new RelationAtom(persionView, Arrays.asList(p1));
408 RelationAtom personRelationAtom2 = new RelationAtom(persionView, Arrays.asList(p2));
409 RelationAtom friendRelationAtom1 = new RelationAtom(friendMustView, Arrays.asList(p1, p2));
410 DNFAnd clause1 = new DNFAnd(new HashSet<>(parameters),
411 Arrays.asList(personRelationAtom1, personRelationAtom2, friendRelationAtom1));
412
413 RelationAtom animalRelationAtom1 = new RelationAtom(animalView, Arrays.asList(p1));
414 RelationAtom animalRelationAtom2 = new RelationAtom(animalView, Arrays.asList(p2));
415 RelationAtom friendRelationAtom2 = new RelationAtom(friendMustView, Arrays.asList(p1, p2));
416 DNFAnd clause2 = new DNFAnd(new HashSet<>(parameters),
417 Arrays.asList(animalRelationAtom1, animalRelationAtom2, friendRelationAtom2));
418
419 DNFPredicate predicate = new DNFPredicate("Or", parameters, Arrays.asList(clause1, clause2));
420 GenericQuerySpecification<GenericPatternMatcher> query = DNF2PQuery.translate(predicate).build();
421
422 ModelStore store = new ModelStoreImpl(Set.of(person, animal, friend));
423 Model model = store.createModel();
424
425 model.put(person, Tuple.of(0), true);
426 model.put(person, Tuple.of(1), true);
427 model.put(animal, Tuple.of(2), true);
428 model.put(animal, Tuple.of(3), true);
429 model.put(friend, Tuple.of(0, 1), TruthValue.TRUE);
430 model.put(friend, Tuple.of(0, 2), TruthValue.TRUE);
431 model.put(friend, Tuple.of(2, 3), TruthValue.TRUE);
432 model.put(friend, Tuple.of(3, 0), TruthValue.TRUE);
433
434 RelationalScope scope = new RelationalScope(model, Set.of(persionView, animalView, friendMustView));
435
436 ViatraQueryEngine engine = AdvancedViatraQueryEngine.on(scope);
437 GenericPatternMatcher matcher = engine.getMatcher(query);
438
439 assertEquals(2, matcher.countMatches());
440 }
90} \ No newline at end of file 441} \ No newline at end of file