diff options
author | 2022-10-19 12:22:14 -0400 | |
---|---|---|
committer | 2022-11-05 19:41:16 +0100 | |
commit | f7e6301423e380e86dd4bd42409e2c4c9d6aade0 (patch) | |
tree | c5c95c2cdc4e83c6c5514b238bbd3e31c1d09048 /subprojects/store-query-viatra/src/main | |
parent | refactor(frontend): minor theme improvements (diff) | |
download | refinery-f7e6301423e380e86dd4bd42409e2c4c9d6aade0.tar.gz refinery-f7e6301423e380e86dd4bd42409e2c4c9d6aade0.tar.zst refinery-f7e6301423e380e86dd4bd42409e2c4c9d6aade0.zip |
refactor: DNF query builder
Diffstat (limited to 'subprojects/store-query-viatra/src/main')
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; | |||
5 | import tools.refinery.store.model.ModelStore; | 5 | import tools.refinery.store.model.ModelStore; |
6 | import tools.refinery.store.model.ModelStoreImpl; | 6 | import tools.refinery.store.model.ModelStoreImpl; |
7 | import tools.refinery.store.model.representation.DataRepresentation; | 7 | import tools.refinery.store.model.representation.DataRepresentation; |
8 | import tools.refinery.store.query.QueryableModel; | 8 | import tools.refinery.store.query.*; |
9 | import tools.refinery.store.query.QueryableModelStore; | 9 | import tools.refinery.store.query.atom.DNFAtom; |
10 | import tools.refinery.store.query.building.*; | 10 | import tools.refinery.store.query.atom.DNFCallAtom; |
11 | import tools.refinery.store.query.atom.EquivalenceAtom; | ||
12 | import tools.refinery.store.query.atom.RelationViewAtom; | ||
11 | import tools.refinery.store.query.viatra.internal.RawPatternMatcher; | 13 | import tools.refinery.store.query.viatra.internal.RawPatternMatcher; |
12 | import tools.refinery.store.query.viatra.internal.ViatraQueryableModel; | 14 | import tools.refinery.store.query.viatra.internal.ViatraQueryableModel; |
13 | import tools.refinery.store.query.viatra.internal.pquery.DNF2PQuery; | 15 | import 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; | |||
12 | import tools.refinery.store.model.representation.Relation; | 12 | import tools.refinery.store.model.representation.Relation; |
13 | import tools.refinery.store.query.QueryableModel; | 13 | import tools.refinery.store.query.QueryableModel; |
14 | import tools.refinery.store.query.QueryableModelStore; | 14 | import tools.refinery.store.query.QueryableModelStore; |
15 | import tools.refinery.store.query.building.DNFPredicate; | 15 | import tools.refinery.store.query.DNF; |
16 | import tools.refinery.store.tuple.Tuple; | 16 | import tools.refinery.store.tuple.Tuple; |
17 | import tools.refinery.store.tuple.TupleLike; | 17 | import 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 | |||
11 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; | 11 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; |
12 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; | 12 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; |
13 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | 13 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; |
14 | import tools.refinery.store.query.building.*; | 14 | import tools.refinery.store.query.*; |
15 | import tools.refinery.store.query.atom.DNFAtom; | ||
16 | import tools.refinery.store.query.atom.EquivalenceAtom; | ||
17 | import tools.refinery.store.query.atom.DNFCallAtom; | ||
18 | import tools.refinery.store.query.atom.RelationViewAtom; | ||
15 | import tools.refinery.store.query.view.RelationView; | 19 | import tools.refinery.store.query.view.RelationView; |
16 | 20 | ||
17 | import java.util.*; | 21 | import java.util.*; |
18 | import java.util.stream.Collectors; | 22 | import java.util.stream.Collectors; |
19 | 23 | ||
20 | public class DNF2PQuery { | 24 | public 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 | } |