aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/PBodyCopier.java
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/PBodyCopier.java')
-rw-r--r--subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/PBodyCopier.java307
1 files changed, 307 insertions, 0 deletions
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/PBodyCopier.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/PBodyCopier.java
new file mode 100644
index 00000000..10ab19c8
--- /dev/null
+++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/psystem/rewriters/PBodyCopier.java
@@ -0,0 +1,307 @@
1/*******************************************************************************
2 * Copyright (c) 2010-2014, Marton Bur, Akos Horvath, Zoltan Ujhelyi, Istvan Rath and Daniel Varro
3 * Copyright (c) 2023 The Refinery Authors <https://refinery.tools>
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v. 2.0 which is available at
6 * http://www.eclipse.org/legal/epl-v20.html.
7 *
8 * SPDX-License-Identifier: EPL-2.0
9 *******************************************************************************/
10package tools.refinery.viatra.runtime.matchers.psystem.rewriters;
11
12import tools.refinery.viatra.runtime.matchers.planning.QueryProcessingException;
13import tools.refinery.viatra.runtime.matchers.psystem.EnumerablePConstraint;
14import tools.refinery.viatra.runtime.matchers.psystem.PBody;
15import tools.refinery.viatra.runtime.matchers.psystem.PConstraint;
16import tools.refinery.viatra.runtime.matchers.psystem.PVariable;
17import tools.refinery.viatra.runtime.matchers.psystem.basicdeferred.*;
18import tools.refinery.viatra.runtime.matchers.psystem.basicenumerables.*;
19import tools.refinery.viatra.runtime.matchers.psystem.queries.PParameter;
20import tools.refinery.viatra.runtime.matchers.psystem.queries.PQuery;
21import tools.refinery.viatra.runtime.matchers.psystem.rewriters.IConstraintFilter.AllowAllFilter;
22import tools.refinery.viatra.runtime.matchers.psystem.rewriters.IVariableRenamer.SameName;
23import tools.refinery.viatra.runtime.matchers.tuple.Tuple;
24import tools.refinery.viatra.runtime.matchers.tuple.Tuples;
25
26import java.util.*;
27import java.util.stream.Collectors;
28
29/**
30 * This class can create a new PBody for a PQuery. The result body contains a copy of given variables and constraints.
31 *
32 * @author Marton Bur
33 *
34 */
35public class PBodyCopier extends AbstractRewriterTraceSource {
36
37 /**
38 * The created body
39 */
40 protected PBody body;
41 /**
42 * Mapping between the original and the copied variables
43 */
44 protected Map<PVariable, PVariable> variableMapping = new HashMap<>();
45
46 public Map<PVariable, PVariable> getVariableMapping() {
47 return variableMapping;
48 }
49
50 /**
51 * @since 1.6
52 */
53 public PBodyCopier(PBody body, IRewriterTraceCollector traceCollector) {
54 this.body = new PBody(body.getPattern());
55 setTraceCollector(traceCollector);
56
57 // do the actual copying
58 mergeBody(body);
59 }
60
61 /**
62 * @since 1.6
63 */
64 public PBodyCopier(PQuery query) {
65 this.body = new PBody(query);
66 }
67
68 public void mergeBody(PBody sourceBody) {
69 mergeBody(sourceBody, new SameName(), new AllowAllFilter());
70 }
71
72 /**
73 * Merge all variables and constraints from a source body to a target body. If multiple bodies are merged into a
74 * single one, use the renamer and filter options to avoid collisions.
75 */
76 public void mergeBody(PBody sourceBody, IVariableRenamer namingTool, IConstraintFilter filter) {
77
78 // Copy variables
79 Set<PVariable> allVariables = sourceBody.getAllVariables();
80 for (PVariable pVariable : allVariables) {
81 if (pVariable.isUnique()) {
82 copyVariable(pVariable, namingTool.createVariableName(pVariable, sourceBody.getPattern()));
83 }
84 }
85
86 // Copy exported parameters
87 this.body.setSymbolicParameters(sourceBody.getSymbolicParameters().stream()
88 .map(this::copyExportedParameterConstraint).collect(Collectors.toList()));
89
90 // Copy constraints which are not filtered
91 Set<PConstraint> constraints = sourceBody.getConstraints();
92 for (PConstraint pConstraint : constraints) {
93 if (!(pConstraint instanceof ExportedParameter) && !filter.filter(pConstraint)) {
94 copyConstraint(pConstraint);
95 }
96 }
97
98 // Add trace between original and copied body
99 addTrace(sourceBody, body);
100 }
101
102 protected void copyVariable(PVariable variable, String newName) {
103 PVariable newPVariable = body.getOrCreateVariableByName(newName);
104 variableMapping.put(variable, newPVariable);
105 }
106
107 /**
108 * Returns the body with the copied variables and constraints. The returned body is still uninitialized.
109 */
110 public PBody getCopiedBody() {
111 return body;
112 }
113
114 protected void copyConstraint(PConstraint constraint) {
115 if (constraint instanceof ExportedParameter) {
116 copyExportedParameterConstraint((ExportedParameter) constraint);
117 } else if (constraint instanceof Equality) {
118 copyEqualityConstraint((Equality) constraint);
119 } else if (constraint instanceof Inequality) {
120 copyInequalityConstraint((Inequality) constraint);
121 } else if (constraint instanceof TypeConstraint) {
122 copyTypeConstraint((TypeConstraint) constraint);
123 } else if (constraint instanceof TypeFilterConstraint) {
124 copyTypeFilterConstraint((TypeFilterConstraint) constraint);
125 } else if (constraint instanceof ConstantValue) {
126 copyConstantValueConstraint((ConstantValue) constraint);
127 } else if (constraint instanceof PositivePatternCall) {
128 copyPositivePatternCallConstraint((PositivePatternCall) constraint);
129 } else if (constraint instanceof NegativePatternCall) {
130 copyNegativePatternCallConstraint((NegativePatternCall) constraint);
131 } else if (constraint instanceof BinaryTransitiveClosure) {
132 copyBinaryTransitiveClosureConstraint((BinaryTransitiveClosure) constraint);
133 } else if (constraint instanceof RepresentativeElectionConstraint) {
134 copyRepresentativeElectionConstraint((RepresentativeElectionConstraint) constraint);
135 } else if (constraint instanceof RelationEvaluation) {
136 copyRelationEvaluationConstraint((RelationEvaluation) constraint);
137 } else if (constraint instanceof BinaryReflexiveTransitiveClosure) {
138 copyBinaryReflexiveTransitiveClosureConstraint((BinaryReflexiveTransitiveClosure) constraint);
139 } else if (constraint instanceof PatternMatchCounter) {
140 copyPatternMatchCounterConstraint((PatternMatchCounter) constraint);
141 } else if (constraint instanceof AggregatorConstraint) {
142 copyAggregatorConstraint((AggregatorConstraint) constraint);
143 } else if (constraint instanceof ExpressionEvaluation) {
144 copyExpressionEvaluationConstraint((ExpressionEvaluation) constraint);
145 } else {
146 throw new QueryProcessingException("Unknown PConstraint {0} encountered while copying PBody",
147 new String[] { constraint.getClass().getName() }, "Unknown PConstraint", body.getPattern());
148 }
149 }
150
151 protected ExportedParameter copyExportedParameterConstraint(ExportedParameter exportedParameter) {
152 PVariable mappedPVariable = variableMapping.get(exportedParameter.getParameterVariable());
153 PParameter parameter = exportedParameter.getPatternParameter();
154 ExportedParameter newExportedParameter;
155 newExportedParameter = new ExportedParameter(body, mappedPVariable, parameter);
156 body.getSymbolicParameters().add(newExportedParameter);
157 addTrace(exportedParameter, newExportedParameter);
158 return newExportedParameter;
159 }
160
161 protected void copyEqualityConstraint(Equality equality) {
162 PVariable who = equality.getWho();
163 PVariable withWhom = equality.getWithWhom();
164 addTrace(equality, new Equality(body, variableMapping.get(who), variableMapping.get(withWhom)));
165 }
166
167 protected void copyInequalityConstraint(Inequality inequality) {
168 PVariable who = inequality.getWho();
169 PVariable withWhom = inequality.getWithWhom();
170 addTrace(inequality, new Inequality(body, variableMapping.get(who), variableMapping.get(withWhom)));
171 }
172
173 protected void copyTypeConstraint(TypeConstraint typeConstraint) {
174 PVariable[] mappedVariables = extractMappedVariables(typeConstraint);
175 Tuple variablesTuple = Tuples.flatTupleOf((Object[]) mappedVariables);
176 addTrace(typeConstraint, new TypeConstraint(body, variablesTuple, typeConstraint.getSupplierKey()));
177 }
178
179 protected void copyTypeFilterConstraint(TypeFilterConstraint typeConstraint) {
180 PVariable[] mappedVariables = extractMappedVariables(typeConstraint);
181 Tuple variablesTuple = Tuples.flatTupleOf((Object[]) mappedVariables);
182 addTrace(typeConstraint, new TypeFilterConstraint(body, variablesTuple, typeConstraint.getInputKey()));
183 }
184
185 protected void copyConstantValueConstraint(ConstantValue constantValue) {
186 PVariable pVariable = (PVariable) constantValue.getVariablesTuple().getElements()[0];
187 addTrace(constantValue,
188 new ConstantValue(body, variableMapping.get(pVariable), constantValue.getSupplierKey()));
189 }
190
191 protected void copyPositivePatternCallConstraint(PositivePatternCall positivePatternCall) {
192 PVariable[] mappedVariables = extractMappedVariables(positivePatternCall);
193 Tuple variablesTuple = Tuples.flatTupleOf((Object[]) mappedVariables);
194 addTrace(positivePatternCall,
195 new PositivePatternCall(body, variablesTuple, positivePatternCall.getReferredQuery()));
196 }
197
198 protected void copyNegativePatternCallConstraint(NegativePatternCall negativePatternCall) {
199 PVariable[] mappedVariables = extractMappedVariables(negativePatternCall);
200 Tuple variablesTuple = Tuples.flatTupleOf((Object[]) mappedVariables);
201 addTrace(negativePatternCall,
202 new NegativePatternCall(body, variablesTuple, negativePatternCall.getReferredQuery()));
203 }
204
205 protected void copyBinaryTransitiveClosureConstraint(BinaryTransitiveClosure binaryTransitiveClosure) {
206 PVariable[] mappedVariables = extractMappedVariables(binaryTransitiveClosure);
207 Tuple variablesTuple = Tuples.flatTupleOf((Object[]) mappedVariables);
208 addTrace(binaryTransitiveClosure,
209 new BinaryTransitiveClosure(body, variablesTuple, binaryTransitiveClosure.getReferredQuery()));
210 }
211
212 protected void copyRepresentativeElectionConstraint(RepresentativeElectionConstraint constraint) {
213 var mappedVariables = extractMappedVariables(constraint);
214 var variablesTuple = Tuples.flatTupleOf((Object[]) mappedVariables);
215 addTrace(constraint, new RepresentativeElectionConstraint(body, variablesTuple, constraint.getReferredQuery(),
216 constraint.getConnectivity()));
217 }
218
219 /**
220 * @since 2.8
221 */
222 protected void copyRelationEvaluationConstraint(RelationEvaluation relationEvaluation) {
223 PVariable[] mappedVariables = extractMappedVariables(relationEvaluation);
224 Tuple variablesTuple = Tuples.flatTupleOf((Object[]) mappedVariables);
225 addTrace(relationEvaluation, new RelationEvaluation(body, variablesTuple, relationEvaluation.getReferredQueries(),
226 relationEvaluation.getEvaluator()));
227 }
228
229 /**
230 * @since 2.0
231 */
232 protected void copyBinaryReflexiveTransitiveClosureConstraint(
233 BinaryReflexiveTransitiveClosure binaryReflexiveTransitiveClosure) {
234 PVariable[] mappedVariables = extractMappedVariables(binaryReflexiveTransitiveClosure);
235 Tuple variablesTuple = Tuples.flatTupleOf((Object[]) mappedVariables);
236 addTrace(binaryReflexiveTransitiveClosure,
237 new BinaryReflexiveTransitiveClosure(body, variablesTuple,
238 binaryReflexiveTransitiveClosure.getReferredQuery(),
239 binaryReflexiveTransitiveClosure.getUniverseType()));
240 }
241
242 protected void copyPatternMatchCounterConstraint(PatternMatchCounter patternMatchCounter) {
243 PVariable[] mappedVariables = extractMappedVariables(patternMatchCounter);
244 PVariable mappedResultVariable = variableMapping.get(patternMatchCounter.getResultVariable());
245 Tuple variablesTuple = Tuples.flatTupleOf((Object[]) mappedVariables);
246 addTrace(patternMatchCounter, new PatternMatchCounter(body, variablesTuple,
247 patternMatchCounter.getReferredQuery(), mappedResultVariable));
248 }
249
250 /**
251 * @since 1.4
252 */
253 protected void copyAggregatorConstraint(AggregatorConstraint constraint) {
254 PVariable[] mappedVariables = extractMappedVariables(constraint);
255 PVariable mappedResultVariable = variableMapping.get(constraint.getResultVariable());
256 Tuple variablesTuple = Tuples.flatTupleOf((Object[]) mappedVariables);
257 addTrace(constraint, new AggregatorConstraint(constraint.getAggregator(), body, variablesTuple,
258 constraint.getReferredQuery(), mappedResultVariable, constraint.getAggregatedColumn()));
259 }
260
261 protected void copyExpressionEvaluationConstraint(ExpressionEvaluation expressionEvaluation) {
262 PVariable mappedOutputVariable = variableMapping.get(expressionEvaluation.getOutputVariable());
263 addTrace(expressionEvaluation, new ExpressionEvaluation(body,
264 new VariableMappingExpressionEvaluatorWrapper(expressionEvaluation.getEvaluator(), variableMapping),
265 mappedOutputVariable, expressionEvaluation.isUnwinding()));
266 }
267
268 /**
269 * For positive pattern calls
270 *
271 * @param positivePatternCall
272 * @return the mapped variables to the pattern's parameters
273 */
274 protected PVariable[] extractMappedVariables(EnumerablePConstraint enumerablePConstraint) {
275 Object[] pVariables = enumerablePConstraint.getVariablesTuple().getElements();
276 return mapVariableList(pVariables);
277 }
278
279 /**
280 * For negative and count pattern calls.
281 *
282 * @param patternMatchCounter
283 * @return the mapped variables to the pattern's parameters
284 */
285 private PVariable[] extractMappedVariables(PatternCallBasedDeferred patternCallBasedDeferred) {
286 Object[] pVariables = patternCallBasedDeferred.getActualParametersTuple().getElements();
287 return mapVariableList(pVariables);
288 }
289
290 /**
291 * For type filters.
292 */
293 private PVariable[] extractMappedVariables(TypeFilterConstraint typeFilterConstraint) {
294 Object[] pVariables = typeFilterConstraint.getVariablesTuple().getElements();
295 return mapVariableList(pVariables);
296 }
297
298 private PVariable[] mapVariableList(Object[] pVariables) {
299 List<PVariable> list = new ArrayList<PVariable>();
300 for (int i = 0; i < pVariables.length; i++) {
301 PVariable mappedVariable = variableMapping.get(pVariables[i]);
302 list.add(mappedVariable);
303 }
304 return list.toArray(new PVariable[0]);
305 }
306
307}