aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store-query-viatra/src/main
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/src/main
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/src/main')
-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
3 files changed, 110 insertions, 112 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}