diff options
Diffstat (limited to 'subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/planning/SubPlan.java')
-rw-r--r-- | subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/planning/SubPlan.java | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/planning/SubPlan.java b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/planning/SubPlan.java new file mode 100644 index 00000000..1998df9d --- /dev/null +++ b/subprojects/viatra-runtime/src/main/java/tools/refinery/viatra/runtime/matchers/planning/SubPlan.java | |||
@@ -0,0 +1,240 @@ | |||
1 | /******************************************************************************* | ||
2 | * Copyright (c) 2004-2008 Gabor Bergmann and Daniel Varro | ||
3 | * This program and the accompanying materials are made available under the | ||
4 | * terms of the Eclipse Public License v. 2.0 which is available at | ||
5 | * http://www.eclipse.org/legal/epl-v20.html. | ||
6 | * | ||
7 | * SPDX-License-Identifier: EPL-2.0 | ||
8 | *******************************************************************************/ | ||
9 | |||
10 | package tools.refinery.viatra.runtime.matchers.planning; | ||
11 | |||
12 | import java.util.Arrays; | ||
13 | import java.util.HashSet; | ||
14 | import java.util.List; | ||
15 | import java.util.Set; | ||
16 | import java.util.WeakHashMap; | ||
17 | import java.util.stream.Collectors; | ||
18 | |||
19 | import tools.refinery.viatra.runtime.matchers.context.IQueryMetaContext; | ||
20 | import tools.refinery.viatra.runtime.matchers.planning.helpers.TypeHelper; | ||
21 | import tools.refinery.viatra.runtime.matchers.planning.operations.POperation; | ||
22 | import tools.refinery.viatra.runtime.matchers.planning.operations.PProject; | ||
23 | import tools.refinery.viatra.runtime.matchers.planning.operations.PStart; | ||
24 | import tools.refinery.viatra.runtime.matchers.psystem.PBody; | ||
25 | import tools.refinery.viatra.runtime.matchers.psystem.PConstraint; | ||
26 | import tools.refinery.viatra.runtime.matchers.psystem.PVariable; | ||
27 | import tools.refinery.viatra.runtime.matchers.psystem.TypeJudgement; | ||
28 | |||
29 | /** | ||
30 | * A plan representing a subset of (or possibly all the) constraints evaluated. A SubPlan instance is responsible for | ||
31 | * representing a state of the plan; but after it is initialized it is expected be immutable | ||
32 | * (exception: inferred constraints, see {@link #inferConstraint(PConstraint)}). | ||
33 | * | ||
34 | * <p> A SubPlan is constructed by applying a {@link POperation} on zero or more parent SubPlans. | ||
35 | * Important maintained information: <ul> | ||
36 | * <li>set of <b>variables</b> whose values are known when the runtime evaluation is at this stage, | ||
37 | * <li>set of <b>constraints</b> that are known to hold true at this point. | ||
38 | * </ul> | ||
39 | * | ||
40 | * <p> Recommended to instantiate via a {@link SubPlanFactory} or subclasses, | ||
41 | * so that query planners can subclass SubPlan if needed. | ||
42 | * | ||
43 | * @author Gabor Bergmann | ||
44 | * | ||
45 | */ | ||
46 | public class SubPlan { | ||
47 | private PBody body; | ||
48 | private List<? extends SubPlan> parentPlans; | ||
49 | private POperation operation; | ||
50 | |||
51 | private final Set<PVariable> visibleVariables; | ||
52 | private final Set<PVariable> allVariables; | ||
53 | private final Set<PVariable> introducedVariables; // delta compared to first parent | ||
54 | private Set<PConstraint> allConstraints; | ||
55 | private Set<PConstraint> deltaConstraints; // delta compared to all parents | ||
56 | private Set<PConstraint> externallyInferredConstraints; // inferred in addition to direct consequences of the operation and parents | ||
57 | |||
58 | |||
59 | |||
60 | |||
61 | |||
62 | /** | ||
63 | * A SubPlan is constructed by applying a {@link POperation} on zero or more parent SubPlans. | ||
64 | */ | ||
65 | public SubPlan(PBody body, POperation operation, SubPlan... parentPlans) { | ||
66 | this(body, operation, Arrays.asList(parentPlans)); | ||
67 | } | ||
68 | /** | ||
69 | * A SubPlan is constructed by applying a {@link POperation} on zero or more parent SubPlans. | ||
70 | */ | ||
71 | public SubPlan(PBody body, POperation operation, List<? extends SubPlan> parentPlans) { | ||
72 | super(); | ||
73 | this.body = body; | ||
74 | this.parentPlans = parentPlans; | ||
75 | this.operation = operation; | ||
76 | |||
77 | this.externallyInferredConstraints = new HashSet<PConstraint>(); | ||
78 | this.deltaConstraints = new HashSet<PConstraint>(operation.getDeltaConstraints()); | ||
79 | |||
80 | this.allVariables = new HashSet<PVariable>(); | ||
81 | for (PConstraint constraint: deltaConstraints) { | ||
82 | this.allVariables.addAll(constraint.getDeducedVariables()); | ||
83 | } | ||
84 | this.allConstraints = new HashSet<PConstraint>(deltaConstraints); | ||
85 | for (SubPlan parentPlan: parentPlans) { | ||
86 | this.allConstraints.addAll(parentPlan.getAllEnforcedConstraints()); | ||
87 | this.allVariables.addAll(parentPlan.getAllDeducedVariables()); | ||
88 | } | ||
89 | |||
90 | // TODO this is ugly a bit | ||
91 | if (operation instanceof PStart) { | ||
92 | this.visibleVariables = new HashSet<PVariable>(((PStart) operation).getAPrioriVariables()); | ||
93 | this.allVariables.addAll(visibleVariables); | ||
94 | } else if (operation instanceof PProject) { | ||
95 | this.visibleVariables = new HashSet<PVariable>(((PProject) operation).getToVariables()); | ||
96 | } else { | ||
97 | this.visibleVariables = new HashSet<PVariable>(); | ||
98 | for (SubPlan parentPlan: parentPlans) | ||
99 | this.visibleVariables.addAll(parentPlan.getVisibleVariables()); | ||
100 | for (PConstraint constraint: deltaConstraints) | ||
101 | this.visibleVariables.addAll(constraint.getDeducedVariables()); | ||
102 | } | ||
103 | |||
104 | this.introducedVariables = new HashSet<PVariable>(this.visibleVariables); | ||
105 | if (!parentPlans.isEmpty()) | ||
106 | introducedVariables.removeAll(parentPlans.get(0).getVisibleVariables()); | ||
107 | |||
108 | operation.checkConsistency(this); | ||
109 | } | ||
110 | |||
111 | |||
112 | @Override | ||
113 | public String toString() { | ||
114 | return toLongString(); | ||
115 | } | ||
116 | public String toShortString() { | ||
117 | return String.format("Plan{%s}:%s", | ||
118 | visibleVariables.stream().map(PVariable::getName).collect(Collectors.joining(",")), | ||
119 | operation.getShortName()); | ||
120 | } | ||
121 | public String toLongString() { | ||
122 | return String.format("%s<%s>", | ||
123 | toShortString(), | ||
124 | parentPlans.stream().map(Object::toString).collect(Collectors.joining("; "))); | ||
125 | } | ||
126 | |||
127 | |||
128 | /** | ||
129 | * All constraints that are known to hold at this point | ||
130 | */ | ||
131 | public Set<PConstraint> getAllEnforcedConstraints() { | ||
132 | return allConstraints; | ||
133 | } | ||
134 | |||
135 | /** | ||
136 | * The new constraints enforced at this stage of plan, that aren't yet enforced at parents | ||
137 | * (results are also included in {@link SubPlan#getAllEnforcedConstraints()}) | ||
138 | */ | ||
139 | public Set<PConstraint> getDeltaEnforcedConstraints() { | ||
140 | return deltaConstraints; | ||
141 | } | ||
142 | |||
143 | /** | ||
144 | * Indicate that a given constraint was found to be automatically satisfied at this point | ||
145 | * without additional operations. | ||
146 | * (results are also included in {@link SubPlan#getDeltaEnforcedConstraints()}) | ||
147 | * | ||
148 | * <p>Warning: not propagated automatically to child plans, | ||
149 | * so best to invoke before constructing further SubPlans. </p> | ||
150 | */ | ||
151 | public void inferConstraint(PConstraint constraint) { | ||
152 | externallyInferredConstraints.add(constraint); | ||
153 | deltaConstraints.add(constraint); | ||
154 | allConstraints.add(constraint); | ||
155 | } | ||
156 | |||
157 | public PBody getBody() { | ||
158 | return body; | ||
159 | } | ||
160 | |||
161 | /** | ||
162 | * Variables which are assigned a value at this point | ||
163 | * (results are also included in {@link SubPlan#getAllDeducedVariables()}) | ||
164 | */ | ||
165 | public Set<PVariable> getVisibleVariables() { | ||
166 | return visibleVariables; | ||
167 | } | ||
168 | /** | ||
169 | * Variables which have been assigned a value; | ||
170 | * includes visible variables (see {@link #getVisibleVariables()}) | ||
171 | * and additionally any variables hidden by a projection (see {@link PProject}). | ||
172 | */ | ||
173 | public Set<PVariable> getAllDeducedVariables() { | ||
174 | return allVariables; | ||
175 | } | ||
176 | /** | ||
177 | * Delta compared to first parent: variables that are visible here but were not visible at the first parent. | ||
178 | */ | ||
179 | public Set<PVariable> getIntroducedVariables() { | ||
180 | return introducedVariables; | ||
181 | } | ||
182 | public List<? extends SubPlan> getParentPlans() { | ||
183 | return parentPlans; | ||
184 | } | ||
185 | public POperation getOperation() { | ||
186 | return operation; | ||
187 | } | ||
188 | |||
189 | |||
190 | /** | ||
191 | * The closure of all type judgments of enforced constraints at this point. | ||
192 | * <p> No subsumption applied. | ||
193 | */ | ||
194 | public Set<TypeJudgement> getAllImpliedTypeJudgements(IQueryMetaContext context) { | ||
195 | Set<TypeJudgement> impliedJudgements = allImpliedTypeJudgements.get(context); | ||
196 | if (impliedJudgements == null) { | ||
197 | Set<TypeJudgement> equivalentJudgements = TypeHelper.getDirectJudgements(getAllEnforcedConstraints(), context); | ||
198 | impliedJudgements = TypeHelper.typeClosure(equivalentJudgements, context); | ||
199 | |||
200 | allImpliedTypeJudgements.put(context, impliedJudgements); | ||
201 | } | ||
202 | return impliedJudgements; | ||
203 | } | ||
204 | private WeakHashMap<IQueryMetaContext, Set<TypeJudgement>> allImpliedTypeJudgements = new WeakHashMap<IQueryMetaContext, Set<TypeJudgement>>(); | ||
205 | |||
206 | |||
207 | @Override | ||
208 | public int hashCode() { | ||
209 | final int prime = 31; | ||
210 | int result = 1; | ||
211 | result = prime * result | ||
212 | + ((operation == null) ? 0 : operation.hashCode()); | ||
213 | result = prime * result | ||
214 | + ((parentPlans == null) ? 0 : parentPlans.hashCode()); | ||
215 | return result; | ||
216 | } | ||
217 | @Override | ||
218 | public boolean equals(Object obj) { | ||
219 | if (this == obj) | ||
220 | return true; | ||
221 | if (obj == null) | ||
222 | return false; | ||
223 | if (!(obj instanceof SubPlan)) | ||
224 | return false; | ||
225 | SubPlan other = (SubPlan) obj; | ||
226 | if (operation == null) { | ||
227 | if (other.operation != null) | ||
228 | return false; | ||
229 | } else if (!operation.equals(other.operation)) | ||
230 | return false; | ||
231 | if (parentPlans == null) { | ||
232 | if (other.parentPlans != null) | ||
233 | return false; | ||
234 | } else if (!parentPlans.equals(other.parentPlans)) | ||
235 | return false; | ||
236 | return true; | ||
237 | } | ||
238 | |||
239 | |||
240 | } | ||