aboutsummaryrefslogtreecommitdiffstats
path: root/store/src/main
diff options
context:
space:
mode:
authorLibravatar Ficsor Attila <ficsorattila96@gmail.com>2021-10-12 23:35:43 +0200
committerLibravatar Ficsor Attila <ficsorattila96@gmail.com>2021-10-12 23:35:43 +0200
commit8a2a7efaaee2616beea139d816aafcdc57699aee (patch)
tree969ada77d54c82e37d5edc1ea096bfb6d76f7b2c /store/src/main
parentchore(web): bump Jetty version (diff)
downloadrefinery-8a2a7efaaee2616beea139d816aafcdc57699aee.tar.gz
refinery-8a2a7efaaee2616beea139d816aafcdc57699aee.tar.zst
refinery-8a2a7efaaee2616beea139d816aafcdc57699aee.zip
Add DNF to PQuery translator
Also added tests for the translator
Diffstat (limited to 'store/src/main')
-rw-r--r--store/src/main/java/tools/refinery/store/query/internal/DNF2PQuery.java184
1 files changed, 184 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