diff options
Diffstat (limited to 'Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse')
30 files changed, 17565 insertions, 0 deletions
diff --git a/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/ecore/queries/.gitignore b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/ecore/queries/.gitignore new file mode 100644 index 00000000..a9786e0f --- /dev/null +++ b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/ecore/queries/.gitignore | |||
@@ -0,0 +1,13 @@ | |||
1 | /.DirectSupertype.java._trace | ||
2 | /.Ecore.java._trace | ||
3 | /.LoopInInheritence.java._trace | ||
4 | /.NonSymmetricOpposite.java._trace | ||
5 | /.Opposite.java._trace | ||
6 | /.OppositeDifferentClass.java._trace | ||
7 | /.EcorePatterns.java._trace | ||
8 | /DirectSupertype.java | ||
9 | /EcorePatterns.java | ||
10 | /LoopInInheritence.java | ||
11 | /NonSymmetricOpposite.java | ||
12 | /Opposite.java | ||
13 | /OppositeDifferentClass.java | ||
diff --git a/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/fam/queries/.gitignore b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/fam/queries/.gitignore new file mode 100644 index 00000000..60f1891b --- /dev/null +++ b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/fam/queries/.gitignore | |||
@@ -0,0 +1,10 @@ | |||
1 | /.FamPatterns.java._trace | ||
2 | /.Model.java._trace | ||
3 | /.Parent.java._trace | ||
4 | /.RootElements.java._trace | ||
5 | /.TerminatorAndInformation.java._trace | ||
6 | /.Type.java._trace | ||
7 | /FamPatterns.java | ||
8 | /Model.java | ||
9 | /Parent.java | ||
10 | /RootElements.java | ||
diff --git a/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/fam/queries/TerminatorAndInformation.java b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/fam/queries/TerminatorAndInformation.java new file mode 100644 index 00000000..69a6b9f4 --- /dev/null +++ b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/fam/queries/TerminatorAndInformation.java | |||
@@ -0,0 +1,747 @@ | |||
1 | /** | ||
2 | * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/fam/queries/famPatterns.vql | ||
3 | */ | ||
4 | package ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries; | ||
5 | |||
6 | import ca.mcgill.ecse.dslreasoner.standalone.test.fam.FAMTerminator; | ||
7 | import ca.mcgill.ecse.dslreasoner.standalone.test.fam.InformationLink; | ||
8 | import java.util.Arrays; | ||
9 | import java.util.Collection; | ||
10 | import java.util.LinkedHashSet; | ||
11 | import java.util.List; | ||
12 | import java.util.Objects; | ||
13 | import java.util.Optional; | ||
14 | import java.util.Set; | ||
15 | import java.util.function.Consumer; | ||
16 | import java.util.stream.Collectors; | ||
17 | import java.util.stream.Stream; | ||
18 | import org.apache.log4j.Logger; | ||
19 | import org.eclipse.emf.ecore.EClass; | ||
20 | import org.eclipse.viatra.query.runtime.api.IPatternMatch; | ||
21 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification; | ||
22 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; | ||
23 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; | ||
24 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; | ||
25 | import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; | ||
26 | import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; | ||
27 | import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; | ||
28 | import org.eclipse.viatra.query.runtime.emf.types.EStructuralFeatureInstancesKey; | ||
29 | import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; | ||
30 | import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; | ||
31 | import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; | ||
32 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; | ||
33 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; | ||
34 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality; | ||
35 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; | ||
36 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; | ||
37 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; | ||
38 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; | ||
39 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; | ||
40 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; | ||
41 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | ||
42 | import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; | ||
43 | |||
44 | /** | ||
45 | * A pattern-specific query specification that can instantiate Matcher in a type-safe way. | ||
46 | * | ||
47 | * <p>Original source: | ||
48 | * <code><pre> | ||
49 | * {@literal @}Constraint(message="terminatorAndInformation", severity="error", key={T}) | ||
50 | * pattern terminatorAndInformation(T : FAMTerminator, I : InformationLink) = { | ||
51 | * FunctionalOutput.outgoingLinks(Out,I); | ||
52 | * FunctionalOutput.terminator(Out,T); | ||
53 | * } or { | ||
54 | * InformationLink.to(I,In); | ||
55 | * FunctionalInput.terminator(In,T); | ||
56 | * } | ||
57 | * </pre></code> | ||
58 | * | ||
59 | * @see Matcher | ||
60 | * @see Match | ||
61 | * | ||
62 | */ | ||
63 | @SuppressWarnings("all") | ||
64 | public final class TerminatorAndInformation extends BaseGeneratedEMFQuerySpecification<TerminatorAndInformation.Matcher> { | ||
65 | /** | ||
66 | * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries.terminatorAndInformation pattern, | ||
67 | * to be used in conjunction with {@link Matcher}. | ||
68 | * | ||
69 | * <p>Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. | ||
70 | * Each instance is a (possibly partial) substitution of pattern parameters, | ||
71 | * usable to represent a match of the pattern in the result of a query, | ||
72 | * or to specify the bound (fixed) input parameters when issuing a query. | ||
73 | * | ||
74 | * @see Matcher | ||
75 | * | ||
76 | */ | ||
77 | public static abstract class Match extends BasePatternMatch { | ||
78 | private FAMTerminator fT; | ||
79 | |||
80 | private InformationLink fI; | ||
81 | |||
82 | private static List<String> parameterNames = makeImmutableList("T", "I"); | ||
83 | |||
84 | private Match(final FAMTerminator pT, final InformationLink pI) { | ||
85 | this.fT = pT; | ||
86 | this.fI = pI; | ||
87 | } | ||
88 | |||
89 | @Override | ||
90 | public Object get(final String parameterName) { | ||
91 | if ("T".equals(parameterName)) return this.fT; | ||
92 | if ("I".equals(parameterName)) return this.fI; | ||
93 | return null; | ||
94 | } | ||
95 | |||
96 | public FAMTerminator getT() { | ||
97 | return this.fT; | ||
98 | } | ||
99 | |||
100 | public InformationLink getI() { | ||
101 | return this.fI; | ||
102 | } | ||
103 | |||
104 | @Override | ||
105 | public boolean set(final String parameterName, final Object newValue) { | ||
106 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
107 | if ("T".equals(parameterName) ) { | ||
108 | this.fT = (FAMTerminator) newValue; | ||
109 | return true; | ||
110 | } | ||
111 | if ("I".equals(parameterName) ) { | ||
112 | this.fI = (InformationLink) newValue; | ||
113 | return true; | ||
114 | } | ||
115 | return false; | ||
116 | } | ||
117 | |||
118 | public void setT(final FAMTerminator pT) { | ||
119 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
120 | this.fT = pT; | ||
121 | } | ||
122 | |||
123 | public void setI(final InformationLink pI) { | ||
124 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
125 | this.fI = pI; | ||
126 | } | ||
127 | |||
128 | @Override | ||
129 | public String patternName() { | ||
130 | return "ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries.terminatorAndInformation"; | ||
131 | } | ||
132 | |||
133 | @Override | ||
134 | public List<String> parameterNames() { | ||
135 | return TerminatorAndInformation.Match.parameterNames; | ||
136 | } | ||
137 | |||
138 | @Override | ||
139 | public Object[] toArray() { | ||
140 | return new Object[]{fT, fI}; | ||
141 | } | ||
142 | |||
143 | @Override | ||
144 | public TerminatorAndInformation.Match toImmutable() { | ||
145 | return isMutable() ? newMatch(fT, fI) : this; | ||
146 | } | ||
147 | |||
148 | @Override | ||
149 | public String prettyPrint() { | ||
150 | StringBuilder result = new StringBuilder(); | ||
151 | result.append("\"T\"=" + prettyPrintValue(fT) + ", "); | ||
152 | result.append("\"I\"=" + prettyPrintValue(fI)); | ||
153 | return result.toString(); | ||
154 | } | ||
155 | |||
156 | @Override | ||
157 | public int hashCode() { | ||
158 | return Objects.hash(fT, fI); | ||
159 | } | ||
160 | |||
161 | @Override | ||
162 | public boolean equals(final Object obj) { | ||
163 | if (this == obj) | ||
164 | return true; | ||
165 | if (obj == null) { | ||
166 | return false; | ||
167 | } | ||
168 | if ((obj instanceof TerminatorAndInformation.Match)) { | ||
169 | TerminatorAndInformation.Match other = (TerminatorAndInformation.Match) obj; | ||
170 | return Objects.equals(fT, other.fT) && Objects.equals(fI, other.fI); | ||
171 | } else { | ||
172 | // this should be infrequent | ||
173 | if (!(obj instanceof IPatternMatch)) { | ||
174 | return false; | ||
175 | } | ||
176 | IPatternMatch otherSig = (IPatternMatch) obj; | ||
177 | return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); | ||
178 | } | ||
179 | } | ||
180 | |||
181 | @Override | ||
182 | public TerminatorAndInformation specification() { | ||
183 | return TerminatorAndInformation.instance(); | ||
184 | } | ||
185 | |||
186 | /** | ||
187 | * Returns an empty, mutable match. | ||
188 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
189 | * | ||
190 | * @return the empty match. | ||
191 | * | ||
192 | */ | ||
193 | public static TerminatorAndInformation.Match newEmptyMatch() { | ||
194 | return new Mutable(null, null); | ||
195 | } | ||
196 | |||
197 | /** | ||
198 | * Returns a mutable (partial) match. | ||
199 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
200 | * | ||
201 | * @param pT the fixed value of pattern parameter T, or null if not bound. | ||
202 | * @param pI the fixed value of pattern parameter I, or null if not bound. | ||
203 | * @return the new, mutable (partial) match object. | ||
204 | * | ||
205 | */ | ||
206 | public static TerminatorAndInformation.Match newMutableMatch(final FAMTerminator pT, final InformationLink pI) { | ||
207 | return new Mutable(pT, pI); | ||
208 | } | ||
209 | |||
210 | /** | ||
211 | * Returns a new (partial) match. | ||
212 | * This can be used e.g. to call the matcher with a partial match. | ||
213 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
214 | * @param pT the fixed value of pattern parameter T, or null if not bound. | ||
215 | * @param pI the fixed value of pattern parameter I, or null if not bound. | ||
216 | * @return the (partial) match object. | ||
217 | * | ||
218 | */ | ||
219 | public static TerminatorAndInformation.Match newMatch(final FAMTerminator pT, final InformationLink pI) { | ||
220 | return new Immutable(pT, pI); | ||
221 | } | ||
222 | |||
223 | private static final class Mutable extends TerminatorAndInformation.Match { | ||
224 | Mutable(final FAMTerminator pT, final InformationLink pI) { | ||
225 | super(pT, pI); | ||
226 | } | ||
227 | |||
228 | @Override | ||
229 | public boolean isMutable() { | ||
230 | return true; | ||
231 | } | ||
232 | } | ||
233 | |||
234 | private static final class Immutable extends TerminatorAndInformation.Match { | ||
235 | Immutable(final FAMTerminator pT, final InformationLink pI) { | ||
236 | super(pT, pI); | ||
237 | } | ||
238 | |||
239 | @Override | ||
240 | public boolean isMutable() { | ||
241 | return false; | ||
242 | } | ||
243 | } | ||
244 | } | ||
245 | |||
246 | /** | ||
247 | * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries.terminatorAndInformation pattern, | ||
248 | * providing pattern-specific query methods. | ||
249 | * | ||
250 | * <p>Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, | ||
251 | * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. | ||
252 | * | ||
253 | * <p>Matches of the pattern will be represented as {@link Match}. | ||
254 | * | ||
255 | * <p>Original source: | ||
256 | * <code><pre> | ||
257 | * {@literal @}Constraint(message="terminatorAndInformation", severity="error", key={T}) | ||
258 | * pattern terminatorAndInformation(T : FAMTerminator, I : InformationLink) = { | ||
259 | * FunctionalOutput.outgoingLinks(Out,I); | ||
260 | * FunctionalOutput.terminator(Out,T); | ||
261 | * } or { | ||
262 | * InformationLink.to(I,In); | ||
263 | * FunctionalInput.terminator(In,T); | ||
264 | * } | ||
265 | * </pre></code> | ||
266 | * | ||
267 | * @see Match | ||
268 | * @see TerminatorAndInformation | ||
269 | * | ||
270 | */ | ||
271 | public static class Matcher extends BaseMatcher<TerminatorAndInformation.Match> { | ||
272 | /** | ||
273 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
274 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
275 | * | ||
276 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
277 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
278 | * | ||
279 | */ | ||
280 | public static TerminatorAndInformation.Matcher on(final ViatraQueryEngine engine) { | ||
281 | // check if matcher already exists | ||
282 | Matcher matcher = engine.getExistingMatcher(querySpecification()); | ||
283 | if (matcher == null) { | ||
284 | matcher = (Matcher)engine.getMatcher(querySpecification()); | ||
285 | } | ||
286 | return matcher; | ||
287 | } | ||
288 | |||
289 | /** | ||
290 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
291 | * @return an initialized matcher | ||
292 | * @noreference This method is for internal matcher initialization by the framework, do not call it manually. | ||
293 | * | ||
294 | */ | ||
295 | public static TerminatorAndInformation.Matcher create() { | ||
296 | return new Matcher(); | ||
297 | } | ||
298 | |||
299 | private final static int POSITION_T = 0; | ||
300 | |||
301 | private final static int POSITION_I = 1; | ||
302 | |||
303 | private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(TerminatorAndInformation.Matcher.class); | ||
304 | |||
305 | /** | ||
306 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
307 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
308 | * | ||
309 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
310 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
311 | * | ||
312 | */ | ||
313 | private Matcher() { | ||
314 | super(querySpecification()); | ||
315 | } | ||
316 | |||
317 | /** | ||
318 | * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. | ||
319 | * @param pT the fixed value of pattern parameter T, or null if not bound. | ||
320 | * @param pI the fixed value of pattern parameter I, or null if not bound. | ||
321 | * @return matches represented as a Match object. | ||
322 | * | ||
323 | */ | ||
324 | public Collection<TerminatorAndInformation.Match> getAllMatches(final FAMTerminator pT, final InformationLink pI) { | ||
325 | return rawStreamAllMatches(new Object[]{pT, pI}).collect(Collectors.toSet()); | ||
326 | } | ||
327 | |||
328 | /** | ||
329 | * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. | ||
330 | * </p> | ||
331 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
332 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
333 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
334 | * @param pT the fixed value of pattern parameter T, or null if not bound. | ||
335 | * @param pI the fixed value of pattern parameter I, or null if not bound. | ||
336 | * @return a stream of matches represented as a Match object. | ||
337 | * | ||
338 | */ | ||
339 | public Stream<TerminatorAndInformation.Match> streamAllMatches(final FAMTerminator pT, final InformationLink pI) { | ||
340 | return rawStreamAllMatches(new Object[]{pT, pI}); | ||
341 | } | ||
342 | |||
343 | /** | ||
344 | * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
345 | * Neither determinism nor randomness of selection is guaranteed. | ||
346 | * @param pT the fixed value of pattern parameter T, or null if not bound. | ||
347 | * @param pI the fixed value of pattern parameter I, or null if not bound. | ||
348 | * @return a match represented as a Match object, or null if no match is found. | ||
349 | * | ||
350 | */ | ||
351 | public Optional<TerminatorAndInformation.Match> getOneArbitraryMatch(final FAMTerminator pT, final InformationLink pI) { | ||
352 | return rawGetOneArbitraryMatch(new Object[]{pT, pI}); | ||
353 | } | ||
354 | |||
355 | /** | ||
356 | * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, | ||
357 | * under any possible substitution of the unspecified parameters (if any). | ||
358 | * @param pT the fixed value of pattern parameter T, or null if not bound. | ||
359 | * @param pI the fixed value of pattern parameter I, or null if not bound. | ||
360 | * @return true if the input is a valid (partial) match of the pattern. | ||
361 | * | ||
362 | */ | ||
363 | public boolean hasMatch(final FAMTerminator pT, final InformationLink pI) { | ||
364 | return rawHasMatch(new Object[]{pT, pI}); | ||
365 | } | ||
366 | |||
367 | /** | ||
368 | * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. | ||
369 | * @param pT the fixed value of pattern parameter T, or null if not bound. | ||
370 | * @param pI the fixed value of pattern parameter I, or null if not bound. | ||
371 | * @return the number of pattern matches found. | ||
372 | * | ||
373 | */ | ||
374 | public int countMatches(final FAMTerminator pT, final InformationLink pI) { | ||
375 | return rawCountMatches(new Object[]{pT, pI}); | ||
376 | } | ||
377 | |||
378 | /** | ||
379 | * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
380 | * Neither determinism nor randomness of selection is guaranteed. | ||
381 | * @param pT the fixed value of pattern parameter T, or null if not bound. | ||
382 | * @param pI the fixed value of pattern parameter I, or null if not bound. | ||
383 | * @param processor the action that will process the selected match. | ||
384 | * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked | ||
385 | * | ||
386 | */ | ||
387 | public boolean forOneArbitraryMatch(final FAMTerminator pT, final InformationLink pI, final Consumer<? super TerminatorAndInformation.Match> processor) { | ||
388 | return rawForOneArbitraryMatch(new Object[]{pT, pI}, processor); | ||
389 | } | ||
390 | |||
391 | /** | ||
392 | * Returns a new (partial) match. | ||
393 | * This can be used e.g. to call the matcher with a partial match. | ||
394 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
395 | * @param pT the fixed value of pattern parameter T, or null if not bound. | ||
396 | * @param pI the fixed value of pattern parameter I, or null if not bound. | ||
397 | * @return the (partial) match object. | ||
398 | * | ||
399 | */ | ||
400 | public TerminatorAndInformation.Match newMatch(final FAMTerminator pT, final InformationLink pI) { | ||
401 | return TerminatorAndInformation.Match.newMatch(pT, pI); | ||
402 | } | ||
403 | |||
404 | /** | ||
405 | * Retrieve the set of values that occur in matches for T. | ||
406 | * @return the Set of all values or empty set if there are no matches | ||
407 | * | ||
408 | */ | ||
409 | protected Stream<FAMTerminator> rawStreamAllValuesOfT(final Object[] parameters) { | ||
410 | return rawStreamAllValues(POSITION_T, parameters).map(FAMTerminator.class::cast); | ||
411 | } | ||
412 | |||
413 | /** | ||
414 | * Retrieve the set of values that occur in matches for T. | ||
415 | * @return the Set of all values or empty set if there are no matches | ||
416 | * | ||
417 | */ | ||
418 | public Set<FAMTerminator> getAllValuesOfT() { | ||
419 | return rawStreamAllValuesOfT(emptyArray()).collect(Collectors.toSet()); | ||
420 | } | ||
421 | |||
422 | /** | ||
423 | * Retrieve the set of values that occur in matches for T. | ||
424 | * @return the Set of all values or empty set if there are no matches | ||
425 | * | ||
426 | */ | ||
427 | public Stream<FAMTerminator> streamAllValuesOfT() { | ||
428 | return rawStreamAllValuesOfT(emptyArray()); | ||
429 | } | ||
430 | |||
431 | /** | ||
432 | * Retrieve the set of values that occur in matches for T. | ||
433 | * </p> | ||
434 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
435 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
436 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
437 | * | ||
438 | * @return the Stream of all values or empty set if there are no matches | ||
439 | * | ||
440 | */ | ||
441 | public Stream<FAMTerminator> streamAllValuesOfT(final TerminatorAndInformation.Match partialMatch) { | ||
442 | return rawStreamAllValuesOfT(partialMatch.toArray()); | ||
443 | } | ||
444 | |||
445 | /** | ||
446 | * Retrieve the set of values that occur in matches for T. | ||
447 | * </p> | ||
448 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
449 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
450 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
451 | * | ||
452 | * @return the Stream of all values or empty set if there are no matches | ||
453 | * | ||
454 | */ | ||
455 | public Stream<FAMTerminator> streamAllValuesOfT(final InformationLink pI) { | ||
456 | return rawStreamAllValuesOfT(new Object[]{null, pI}); | ||
457 | } | ||
458 | |||
459 | /** | ||
460 | * Retrieve the set of values that occur in matches for T. | ||
461 | * @return the Set of all values or empty set if there are no matches | ||
462 | * | ||
463 | */ | ||
464 | public Set<FAMTerminator> getAllValuesOfT(final TerminatorAndInformation.Match partialMatch) { | ||
465 | return rawStreamAllValuesOfT(partialMatch.toArray()).collect(Collectors.toSet()); | ||
466 | } | ||
467 | |||
468 | /** | ||
469 | * Retrieve the set of values that occur in matches for T. | ||
470 | * @return the Set of all values or empty set if there are no matches | ||
471 | * | ||
472 | */ | ||
473 | public Set<FAMTerminator> getAllValuesOfT(final InformationLink pI) { | ||
474 | return rawStreamAllValuesOfT(new Object[]{null, pI}).collect(Collectors.toSet()); | ||
475 | } | ||
476 | |||
477 | /** | ||
478 | * Retrieve the set of values that occur in matches for I. | ||
479 | * @return the Set of all values or empty set if there are no matches | ||
480 | * | ||
481 | */ | ||
482 | protected Stream<InformationLink> rawStreamAllValuesOfI(final Object[] parameters) { | ||
483 | return rawStreamAllValues(POSITION_I, parameters).map(InformationLink.class::cast); | ||
484 | } | ||
485 | |||
486 | /** | ||
487 | * Retrieve the set of values that occur in matches for I. | ||
488 | * @return the Set of all values or empty set if there are no matches | ||
489 | * | ||
490 | */ | ||
491 | public Set<InformationLink> getAllValuesOfI() { | ||
492 | return rawStreamAllValuesOfI(emptyArray()).collect(Collectors.toSet()); | ||
493 | } | ||
494 | |||
495 | /** | ||
496 | * Retrieve the set of values that occur in matches for I. | ||
497 | * @return the Set of all values or empty set if there are no matches | ||
498 | * | ||
499 | */ | ||
500 | public Stream<InformationLink> streamAllValuesOfI() { | ||
501 | return rawStreamAllValuesOfI(emptyArray()); | ||
502 | } | ||
503 | |||
504 | /** | ||
505 | * Retrieve the set of values that occur in matches for I. | ||
506 | * </p> | ||
507 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
508 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
509 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
510 | * | ||
511 | * @return the Stream of all values or empty set if there are no matches | ||
512 | * | ||
513 | */ | ||
514 | public Stream<InformationLink> streamAllValuesOfI(final TerminatorAndInformation.Match partialMatch) { | ||
515 | return rawStreamAllValuesOfI(partialMatch.toArray()); | ||
516 | } | ||
517 | |||
518 | /** | ||
519 | * Retrieve the set of values that occur in matches for I. | ||
520 | * </p> | ||
521 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
522 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
523 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
524 | * | ||
525 | * @return the Stream of all values or empty set if there are no matches | ||
526 | * | ||
527 | */ | ||
528 | public Stream<InformationLink> streamAllValuesOfI(final FAMTerminator pT) { | ||
529 | return rawStreamAllValuesOfI(new Object[]{pT, null}); | ||
530 | } | ||
531 | |||
532 | /** | ||
533 | * Retrieve the set of values that occur in matches for I. | ||
534 | * @return the Set of all values or empty set if there are no matches | ||
535 | * | ||
536 | */ | ||
537 | public Set<InformationLink> getAllValuesOfI(final TerminatorAndInformation.Match partialMatch) { | ||
538 | return rawStreamAllValuesOfI(partialMatch.toArray()).collect(Collectors.toSet()); | ||
539 | } | ||
540 | |||
541 | /** | ||
542 | * Retrieve the set of values that occur in matches for I. | ||
543 | * @return the Set of all values or empty set if there are no matches | ||
544 | * | ||
545 | */ | ||
546 | public Set<InformationLink> getAllValuesOfI(final FAMTerminator pT) { | ||
547 | return rawStreamAllValuesOfI(new Object[]{pT, null}).collect(Collectors.toSet()); | ||
548 | } | ||
549 | |||
550 | @Override | ||
551 | protected TerminatorAndInformation.Match tupleToMatch(final Tuple t) { | ||
552 | try { | ||
553 | return TerminatorAndInformation.Match.newMatch((FAMTerminator) t.get(POSITION_T), (InformationLink) t.get(POSITION_I)); | ||
554 | } catch(ClassCastException e) { | ||
555 | LOGGER.error("Element(s) in tuple not properly typed!",e); | ||
556 | return null; | ||
557 | } | ||
558 | } | ||
559 | |||
560 | @Override | ||
561 | protected TerminatorAndInformation.Match arrayToMatch(final Object[] match) { | ||
562 | try { | ||
563 | return TerminatorAndInformation.Match.newMatch((FAMTerminator) match[POSITION_T], (InformationLink) match[POSITION_I]); | ||
564 | } catch(ClassCastException e) { | ||
565 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
566 | return null; | ||
567 | } | ||
568 | } | ||
569 | |||
570 | @Override | ||
571 | protected TerminatorAndInformation.Match arrayToMatchMutable(final Object[] match) { | ||
572 | try { | ||
573 | return TerminatorAndInformation.Match.newMutableMatch((FAMTerminator) match[POSITION_T], (InformationLink) match[POSITION_I]); | ||
574 | } catch(ClassCastException e) { | ||
575 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
576 | return null; | ||
577 | } | ||
578 | } | ||
579 | |||
580 | /** | ||
581 | * @return the singleton instance of the query specification of this pattern | ||
582 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
583 | * | ||
584 | */ | ||
585 | public static IQuerySpecification<TerminatorAndInformation.Matcher> querySpecification() { | ||
586 | return TerminatorAndInformation.instance(); | ||
587 | } | ||
588 | } | ||
589 | |||
590 | private TerminatorAndInformation() { | ||
591 | super(GeneratedPQuery.INSTANCE); | ||
592 | } | ||
593 | |||
594 | /** | ||
595 | * @return the singleton instance of the query specification | ||
596 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
597 | * | ||
598 | */ | ||
599 | public static TerminatorAndInformation instance() { | ||
600 | try{ | ||
601 | return LazyHolder.INSTANCE; | ||
602 | } catch (ExceptionInInitializerError err) { | ||
603 | throw processInitializerError(err); | ||
604 | } | ||
605 | } | ||
606 | |||
607 | @Override | ||
608 | protected TerminatorAndInformation.Matcher instantiate(final ViatraQueryEngine engine) { | ||
609 | return TerminatorAndInformation.Matcher.on(engine); | ||
610 | } | ||
611 | |||
612 | @Override | ||
613 | public TerminatorAndInformation.Matcher instantiate() { | ||
614 | return TerminatorAndInformation.Matcher.create(); | ||
615 | } | ||
616 | |||
617 | @Override | ||
618 | public TerminatorAndInformation.Match newEmptyMatch() { | ||
619 | return TerminatorAndInformation.Match.newEmptyMatch(); | ||
620 | } | ||
621 | |||
622 | @Override | ||
623 | public TerminatorAndInformation.Match newMatch(final Object... parameters) { | ||
624 | return TerminatorAndInformation.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.fam.FAMTerminator) parameters[0], (ca.mcgill.ecse.dslreasoner.standalone.test.fam.InformationLink) parameters[1]); | ||
625 | } | ||
626 | |||
627 | /** | ||
628 | * Inner class allowing the singleton instance of {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries.TerminatorAndInformation (visibility: PUBLIC, simpleName: TerminatorAndInformation, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries.TerminatorAndInformation, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created | ||
629 | * <b>not</b> at the class load time of the outer class, | ||
630 | * but rather at the first call to {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries.TerminatorAndInformation (visibility: PUBLIC, simpleName: TerminatorAndInformation, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries.TerminatorAndInformation, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. | ||
631 | * | ||
632 | * <p> This workaround is required e.g. to support recursion. | ||
633 | * | ||
634 | */ | ||
635 | private static class LazyHolder { | ||
636 | private final static TerminatorAndInformation INSTANCE = new TerminatorAndInformation(); | ||
637 | |||
638 | /** | ||
639 | * Statically initializes the query specification <b>after</b> the field {@link #INSTANCE} is assigned. | ||
640 | * This initialization order is required to support indirect recursion. | ||
641 | * | ||
642 | * <p> The static initializer is defined using a helper field to work around limitations of the code generator. | ||
643 | * | ||
644 | */ | ||
645 | private final static Object STATIC_INITIALIZER = ensureInitialized(); | ||
646 | |||
647 | public static Object ensureInitialized() { | ||
648 | INSTANCE.ensureInitializedInternal(); | ||
649 | return null; | ||
650 | } | ||
651 | } | ||
652 | |||
653 | private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { | ||
654 | private final static TerminatorAndInformation.GeneratedPQuery INSTANCE = new GeneratedPQuery(); | ||
655 | |||
656 | private final PParameter parameter_T = new PParameter("T", "ca.mcgill.ecse.dslreasoner.standalone.test.fam.FAMTerminator", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("FamMetamodel", "FAMTerminator")), PParameterDirection.INOUT); | ||
657 | |||
658 | private final PParameter parameter_I = new PParameter("I", "ca.mcgill.ecse.dslreasoner.standalone.test.fam.InformationLink", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("FamMetamodel", "InformationLink")), PParameterDirection.INOUT); | ||
659 | |||
660 | private final List<PParameter> parameters = Arrays.asList(parameter_T, parameter_I); | ||
661 | |||
662 | private GeneratedPQuery() { | ||
663 | super(PVisibility.PUBLIC); | ||
664 | } | ||
665 | |||
666 | @Override | ||
667 | public String getFullyQualifiedName() { | ||
668 | return "ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries.terminatorAndInformation"; | ||
669 | } | ||
670 | |||
671 | @Override | ||
672 | public List<String> getParameterNames() { | ||
673 | return Arrays.asList("T","I"); | ||
674 | } | ||
675 | |||
676 | @Override | ||
677 | public List<PParameter> getParameters() { | ||
678 | return parameters; | ||
679 | } | ||
680 | |||
681 | @Override | ||
682 | public Set<PBody> doGetContainedBodies() { | ||
683 | setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); | ||
684 | Set<PBody> bodies = new LinkedHashSet<>(); | ||
685 | { | ||
686 | PBody body = new PBody(this); | ||
687 | PVariable var_T = body.getOrCreateVariableByName("T"); | ||
688 | PVariable var_I = body.getOrCreateVariableByName("I"); | ||
689 | PVariable var_Out = body.getOrCreateVariableByName("Out"); | ||
690 | new TypeConstraint(body, Tuples.flatTupleOf(var_T), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("FamMetamodel", "FAMTerminator"))); | ||
691 | new TypeConstraint(body, Tuples.flatTupleOf(var_I), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("FamMetamodel", "InformationLink"))); | ||
692 | body.setSymbolicParameters(Arrays.<ExportedParameter>asList( | ||
693 | new ExportedParameter(body, var_T, parameter_T), | ||
694 | new ExportedParameter(body, var_I, parameter_I) | ||
695 | )); | ||
696 | // FunctionalOutput.outgoingLinks(Out,I) | ||
697 | new TypeConstraint(body, Tuples.flatTupleOf(var_Out), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("FamMetamodel", "FunctionalOutput"))); | ||
698 | PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); | ||
699 | new TypeConstraint(body, Tuples.flatTupleOf(var_Out, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("FamMetamodel", "FunctionalOutput", "outgoingLinks"))); | ||
700 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("FamMetamodel", "InformationLink"))); | ||
701 | new Equality(body, var__virtual_0_, var_I); | ||
702 | // FunctionalOutput.terminator(Out,T) | ||
703 | new TypeConstraint(body, Tuples.flatTupleOf(var_Out), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("FamMetamodel", "FunctionalOutput"))); | ||
704 | PVariable var__virtual_1_ = body.getOrCreateVariableByName(".virtual{1}"); | ||
705 | new TypeConstraint(body, Tuples.flatTupleOf(var_Out, var__virtual_1_), new EStructuralFeatureInstancesKey(getFeatureLiteral("FamMetamodel", "FunctionalData", "terminator"))); | ||
706 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_1_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("FamMetamodel", "FAMTerminator"))); | ||
707 | new Equality(body, var__virtual_1_, var_T); | ||
708 | bodies.add(body); | ||
709 | } | ||
710 | { | ||
711 | PBody body = new PBody(this); | ||
712 | PVariable var_T = body.getOrCreateVariableByName("T"); | ||
713 | PVariable var_I = body.getOrCreateVariableByName("I"); | ||
714 | PVariable var_In = body.getOrCreateVariableByName("In"); | ||
715 | new TypeConstraint(body, Tuples.flatTupleOf(var_T), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("FamMetamodel", "FAMTerminator"))); | ||
716 | new TypeConstraint(body, Tuples.flatTupleOf(var_I), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("FamMetamodel", "InformationLink"))); | ||
717 | body.setSymbolicParameters(Arrays.<ExportedParameter>asList( | ||
718 | new ExportedParameter(body, var_T, parameter_T), | ||
719 | new ExportedParameter(body, var_I, parameter_I) | ||
720 | )); | ||
721 | // InformationLink.to(I,In) | ||
722 | new TypeConstraint(body, Tuples.flatTupleOf(var_I), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("FamMetamodel", "InformationLink"))); | ||
723 | PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); | ||
724 | new TypeConstraint(body, Tuples.flatTupleOf(var_I, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("FamMetamodel", "InformationLink", "to"))); | ||
725 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("FamMetamodel", "FunctionalInput"))); | ||
726 | new Equality(body, var__virtual_0_, var_In); | ||
727 | // FunctionalInput.terminator(In,T) | ||
728 | new TypeConstraint(body, Tuples.flatTupleOf(var_In), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("FamMetamodel", "FunctionalInput"))); | ||
729 | PVariable var__virtual_1_ = body.getOrCreateVariableByName(".virtual{1}"); | ||
730 | new TypeConstraint(body, Tuples.flatTupleOf(var_In, var__virtual_1_), new EStructuralFeatureInstancesKey(getFeatureLiteral("FamMetamodel", "FunctionalData", "terminator"))); | ||
731 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_1_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("FamMetamodel", "FAMTerminator"))); | ||
732 | new Equality(body, var__virtual_1_, var_T); | ||
733 | bodies.add(body); | ||
734 | } | ||
735 | { | ||
736 | PAnnotation annotation = new PAnnotation("Constraint"); | ||
737 | annotation.addAttribute("message", "terminatorAndInformation"); | ||
738 | annotation.addAttribute("severity", "error"); | ||
739 | annotation.addAttribute("key", Arrays.asList(new Object[] { | ||
740 | new ParameterReference("T") | ||
741 | })); | ||
742 | addAnnotation(annotation); | ||
743 | } | ||
744 | return bodies; | ||
745 | } | ||
746 | } | ||
747 | } | ||
diff --git a/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/fam/queries/Type.java b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/fam/queries/Type.java new file mode 100644 index 00000000..bc3230c5 --- /dev/null +++ b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/fam/queries/Type.java | |||
@@ -0,0 +1,770 @@ | |||
1 | /** | ||
2 | * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/fam/queries/famPatterns.vql | ||
3 | */ | ||
4 | package ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries; | ||
5 | |||
6 | import ca.mcgill.ecse.dslreasoner.standalone.test.fam.Function; | ||
7 | import ca.mcgill.ecse.dslreasoner.standalone.test.fam.FunctionType; | ||
8 | import ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries.Parent; | ||
9 | import ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries.RootElements; | ||
10 | import java.util.Arrays; | ||
11 | import java.util.Collection; | ||
12 | import java.util.LinkedHashSet; | ||
13 | import java.util.List; | ||
14 | import java.util.Objects; | ||
15 | import java.util.Optional; | ||
16 | import java.util.Set; | ||
17 | import java.util.function.Consumer; | ||
18 | import java.util.stream.Collectors; | ||
19 | import java.util.stream.Stream; | ||
20 | import org.apache.log4j.Logger; | ||
21 | import org.eclipse.emf.ecore.EClass; | ||
22 | import org.eclipse.emf.ecore.EDataType; | ||
23 | import org.eclipse.viatra.query.runtime.api.IPatternMatch; | ||
24 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification; | ||
25 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; | ||
26 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; | ||
27 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; | ||
28 | import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; | ||
29 | import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; | ||
30 | import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; | ||
31 | import org.eclipse.viatra.query.runtime.emf.types.EDataTypeInSlotsKey; | ||
32 | import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; | ||
33 | import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; | ||
34 | import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; | ||
35 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; | ||
36 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality; | ||
37 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; | ||
38 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.NegativePatternCall; | ||
39 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.ConstantValue; | ||
40 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall; | ||
41 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; | ||
42 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; | ||
43 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; | ||
44 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; | ||
45 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; | ||
46 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | ||
47 | import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; | ||
48 | |||
49 | /** | ||
50 | * A pattern-specific query specification that can instantiate Matcher in a type-safe way. | ||
51 | * | ||
52 | * <p>Original source: | ||
53 | * <code><pre> | ||
54 | * {@literal @}QueryBasedFeature | ||
55 | * pattern type(This : Function, Target : FunctionType) = { | ||
56 | * find rootElements(_Model, This); | ||
57 | * Target == FunctionType::Root; | ||
58 | * } or { | ||
59 | * neg find parent(_Child, This); | ||
60 | * neg find rootElements(_Model, This); | ||
61 | * Target == FunctionType::Leaf; | ||
62 | * } or { | ||
63 | * find parent(This, _Par); | ||
64 | * find parent(_Child, This); | ||
65 | * Target == FunctionType::Intermediate; | ||
66 | * } | ||
67 | * </pre></code> | ||
68 | * | ||
69 | * @see Matcher | ||
70 | * @see Match | ||
71 | * | ||
72 | */ | ||
73 | @SuppressWarnings("all") | ||
74 | public final class Type extends BaseGeneratedEMFQuerySpecification<Type.Matcher> { | ||
75 | /** | ||
76 | * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries.type pattern, | ||
77 | * to be used in conjunction with {@link Matcher}. | ||
78 | * | ||
79 | * <p>Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. | ||
80 | * Each instance is a (possibly partial) substitution of pattern parameters, | ||
81 | * usable to represent a match of the pattern in the result of a query, | ||
82 | * or to specify the bound (fixed) input parameters when issuing a query. | ||
83 | * | ||
84 | * @see Matcher | ||
85 | * | ||
86 | */ | ||
87 | public static abstract class Match extends BasePatternMatch { | ||
88 | private Function fThis; | ||
89 | |||
90 | private FunctionType fTarget; | ||
91 | |||
92 | private static List<String> parameterNames = makeImmutableList("This", "Target"); | ||
93 | |||
94 | private Match(final Function pThis, final FunctionType pTarget) { | ||
95 | this.fThis = pThis; | ||
96 | this.fTarget = pTarget; | ||
97 | } | ||
98 | |||
99 | @Override | ||
100 | public Object get(final String parameterName) { | ||
101 | if ("This".equals(parameterName)) return this.fThis; | ||
102 | if ("Target".equals(parameterName)) return this.fTarget; | ||
103 | return null; | ||
104 | } | ||
105 | |||
106 | public Function getThis() { | ||
107 | return this.fThis; | ||
108 | } | ||
109 | |||
110 | public FunctionType getTarget() { | ||
111 | return this.fTarget; | ||
112 | } | ||
113 | |||
114 | @Override | ||
115 | public boolean set(final String parameterName, final Object newValue) { | ||
116 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
117 | if ("This".equals(parameterName) ) { | ||
118 | this.fThis = (Function) newValue; | ||
119 | return true; | ||
120 | } | ||
121 | if ("Target".equals(parameterName) ) { | ||
122 | this.fTarget = (FunctionType) newValue; | ||
123 | return true; | ||
124 | } | ||
125 | return false; | ||
126 | } | ||
127 | |||
128 | public void setThis(final Function pThis) { | ||
129 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
130 | this.fThis = pThis; | ||
131 | } | ||
132 | |||
133 | public void setTarget(final FunctionType pTarget) { | ||
134 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
135 | this.fTarget = pTarget; | ||
136 | } | ||
137 | |||
138 | @Override | ||
139 | public String patternName() { | ||
140 | return "ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries.type"; | ||
141 | } | ||
142 | |||
143 | @Override | ||
144 | public List<String> parameterNames() { | ||
145 | return Type.Match.parameterNames; | ||
146 | } | ||
147 | |||
148 | @Override | ||
149 | public Object[] toArray() { | ||
150 | return new Object[]{fThis, fTarget}; | ||
151 | } | ||
152 | |||
153 | @Override | ||
154 | public Type.Match toImmutable() { | ||
155 | return isMutable() ? newMatch(fThis, fTarget) : this; | ||
156 | } | ||
157 | |||
158 | @Override | ||
159 | public String prettyPrint() { | ||
160 | StringBuilder result = new StringBuilder(); | ||
161 | result.append("\"This\"=" + prettyPrintValue(fThis) + ", "); | ||
162 | result.append("\"Target\"=" + prettyPrintValue(fTarget)); | ||
163 | return result.toString(); | ||
164 | } | ||
165 | |||
166 | @Override | ||
167 | public int hashCode() { | ||
168 | return Objects.hash(fThis, fTarget); | ||
169 | } | ||
170 | |||
171 | @Override | ||
172 | public boolean equals(final Object obj) { | ||
173 | if (this == obj) | ||
174 | return true; | ||
175 | if (obj == null) { | ||
176 | return false; | ||
177 | } | ||
178 | if ((obj instanceof Type.Match)) { | ||
179 | Type.Match other = (Type.Match) obj; | ||
180 | return Objects.equals(fThis, other.fThis) && Objects.equals(fTarget, other.fTarget); | ||
181 | } else { | ||
182 | // this should be infrequent | ||
183 | if (!(obj instanceof IPatternMatch)) { | ||
184 | return false; | ||
185 | } | ||
186 | IPatternMatch otherSig = (IPatternMatch) obj; | ||
187 | return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); | ||
188 | } | ||
189 | } | ||
190 | |||
191 | @Override | ||
192 | public Type specification() { | ||
193 | return Type.instance(); | ||
194 | } | ||
195 | |||
196 | /** | ||
197 | * Returns an empty, mutable match. | ||
198 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
199 | * | ||
200 | * @return the empty match. | ||
201 | * | ||
202 | */ | ||
203 | public static Type.Match newEmptyMatch() { | ||
204 | return new Mutable(null, null); | ||
205 | } | ||
206 | |||
207 | /** | ||
208 | * Returns a mutable (partial) match. | ||
209 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
210 | * | ||
211 | * @param pThis the fixed value of pattern parameter This, or null if not bound. | ||
212 | * @param pTarget the fixed value of pattern parameter Target, or null if not bound. | ||
213 | * @return the new, mutable (partial) match object. | ||
214 | * | ||
215 | */ | ||
216 | public static Type.Match newMutableMatch(final Function pThis, final FunctionType pTarget) { | ||
217 | return new Mutable(pThis, pTarget); | ||
218 | } | ||
219 | |||
220 | /** | ||
221 | * Returns a new (partial) match. | ||
222 | * This can be used e.g. to call the matcher with a partial match. | ||
223 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
224 | * @param pThis the fixed value of pattern parameter This, or null if not bound. | ||
225 | * @param pTarget the fixed value of pattern parameter Target, or null if not bound. | ||
226 | * @return the (partial) match object. | ||
227 | * | ||
228 | */ | ||
229 | public static Type.Match newMatch(final Function pThis, final FunctionType pTarget) { | ||
230 | return new Immutable(pThis, pTarget); | ||
231 | } | ||
232 | |||
233 | private static final class Mutable extends Type.Match { | ||
234 | Mutable(final Function pThis, final FunctionType pTarget) { | ||
235 | super(pThis, pTarget); | ||
236 | } | ||
237 | |||
238 | @Override | ||
239 | public boolean isMutable() { | ||
240 | return true; | ||
241 | } | ||
242 | } | ||
243 | |||
244 | private static final class Immutable extends Type.Match { | ||
245 | Immutable(final Function pThis, final FunctionType pTarget) { | ||
246 | super(pThis, pTarget); | ||
247 | } | ||
248 | |||
249 | @Override | ||
250 | public boolean isMutable() { | ||
251 | return false; | ||
252 | } | ||
253 | } | ||
254 | } | ||
255 | |||
256 | /** | ||
257 | * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries.type pattern, | ||
258 | * providing pattern-specific query methods. | ||
259 | * | ||
260 | * <p>Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, | ||
261 | * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. | ||
262 | * | ||
263 | * <p>Matches of the pattern will be represented as {@link Match}. | ||
264 | * | ||
265 | * <p>Original source: | ||
266 | * <code><pre> | ||
267 | * {@literal @}QueryBasedFeature | ||
268 | * pattern type(This : Function, Target : FunctionType) = { | ||
269 | * find rootElements(_Model, This); | ||
270 | * Target == FunctionType::Root; | ||
271 | * } or { | ||
272 | * neg find parent(_Child, This); | ||
273 | * neg find rootElements(_Model, This); | ||
274 | * Target == FunctionType::Leaf; | ||
275 | * } or { | ||
276 | * find parent(This, _Par); | ||
277 | * find parent(_Child, This); | ||
278 | * Target == FunctionType::Intermediate; | ||
279 | * } | ||
280 | * </pre></code> | ||
281 | * | ||
282 | * @see Match | ||
283 | * @see Type | ||
284 | * | ||
285 | */ | ||
286 | public static class Matcher extends BaseMatcher<Type.Match> { | ||
287 | /** | ||
288 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
289 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
290 | * | ||
291 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
292 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
293 | * | ||
294 | */ | ||
295 | public static Type.Matcher on(final ViatraQueryEngine engine) { | ||
296 | // check if matcher already exists | ||
297 | Matcher matcher = engine.getExistingMatcher(querySpecification()); | ||
298 | if (matcher == null) { | ||
299 | matcher = (Matcher)engine.getMatcher(querySpecification()); | ||
300 | } | ||
301 | return matcher; | ||
302 | } | ||
303 | |||
304 | /** | ||
305 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
306 | * @return an initialized matcher | ||
307 | * @noreference This method is for internal matcher initialization by the framework, do not call it manually. | ||
308 | * | ||
309 | */ | ||
310 | public static Type.Matcher create() { | ||
311 | return new Matcher(); | ||
312 | } | ||
313 | |||
314 | private final static int POSITION_THIS = 0; | ||
315 | |||
316 | private final static int POSITION_TARGET = 1; | ||
317 | |||
318 | private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(Type.Matcher.class); | ||
319 | |||
320 | /** | ||
321 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
322 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
323 | * | ||
324 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
325 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
326 | * | ||
327 | */ | ||
328 | private Matcher() { | ||
329 | super(querySpecification()); | ||
330 | } | ||
331 | |||
332 | /** | ||
333 | * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. | ||
334 | * @param pThis the fixed value of pattern parameter This, or null if not bound. | ||
335 | * @param pTarget the fixed value of pattern parameter Target, or null if not bound. | ||
336 | * @return matches represented as a Match object. | ||
337 | * | ||
338 | */ | ||
339 | public Collection<Type.Match> getAllMatches(final Function pThis, final FunctionType pTarget) { | ||
340 | return rawStreamAllMatches(new Object[]{pThis, pTarget}).collect(Collectors.toSet()); | ||
341 | } | ||
342 | |||
343 | /** | ||
344 | * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. | ||
345 | * </p> | ||
346 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
347 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
348 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
349 | * @param pThis the fixed value of pattern parameter This, or null if not bound. | ||
350 | * @param pTarget the fixed value of pattern parameter Target, or null if not bound. | ||
351 | * @return a stream of matches represented as a Match object. | ||
352 | * | ||
353 | */ | ||
354 | public Stream<Type.Match> streamAllMatches(final Function pThis, final FunctionType pTarget) { | ||
355 | return rawStreamAllMatches(new Object[]{pThis, pTarget}); | ||
356 | } | ||
357 | |||
358 | /** | ||
359 | * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
360 | * Neither determinism nor randomness of selection is guaranteed. | ||
361 | * @param pThis the fixed value of pattern parameter This, or null if not bound. | ||
362 | * @param pTarget the fixed value of pattern parameter Target, or null if not bound. | ||
363 | * @return a match represented as a Match object, or null if no match is found. | ||
364 | * | ||
365 | */ | ||
366 | public Optional<Type.Match> getOneArbitraryMatch(final Function pThis, final FunctionType pTarget) { | ||
367 | return rawGetOneArbitraryMatch(new Object[]{pThis, pTarget}); | ||
368 | } | ||
369 | |||
370 | /** | ||
371 | * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, | ||
372 | * under any possible substitution of the unspecified parameters (if any). | ||
373 | * @param pThis the fixed value of pattern parameter This, or null if not bound. | ||
374 | * @param pTarget the fixed value of pattern parameter Target, or null if not bound. | ||
375 | * @return true if the input is a valid (partial) match of the pattern. | ||
376 | * | ||
377 | */ | ||
378 | public boolean hasMatch(final Function pThis, final FunctionType pTarget) { | ||
379 | return rawHasMatch(new Object[]{pThis, pTarget}); | ||
380 | } | ||
381 | |||
382 | /** | ||
383 | * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. | ||
384 | * @param pThis the fixed value of pattern parameter This, or null if not bound. | ||
385 | * @param pTarget the fixed value of pattern parameter Target, or null if not bound. | ||
386 | * @return the number of pattern matches found. | ||
387 | * | ||
388 | */ | ||
389 | public int countMatches(final Function pThis, final FunctionType pTarget) { | ||
390 | return rawCountMatches(new Object[]{pThis, pTarget}); | ||
391 | } | ||
392 | |||
393 | /** | ||
394 | * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
395 | * Neither determinism nor randomness of selection is guaranteed. | ||
396 | * @param pThis the fixed value of pattern parameter This, or null if not bound. | ||
397 | * @param pTarget the fixed value of pattern parameter Target, or null if not bound. | ||
398 | * @param processor the action that will process the selected match. | ||
399 | * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked | ||
400 | * | ||
401 | */ | ||
402 | public boolean forOneArbitraryMatch(final Function pThis, final FunctionType pTarget, final Consumer<? super Type.Match> processor) { | ||
403 | return rawForOneArbitraryMatch(new Object[]{pThis, pTarget}, processor); | ||
404 | } | ||
405 | |||
406 | /** | ||
407 | * Returns a new (partial) match. | ||
408 | * This can be used e.g. to call the matcher with a partial match. | ||
409 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
410 | * @param pThis the fixed value of pattern parameter This, or null if not bound. | ||
411 | * @param pTarget the fixed value of pattern parameter Target, or null if not bound. | ||
412 | * @return the (partial) match object. | ||
413 | * | ||
414 | */ | ||
415 | public Type.Match newMatch(final Function pThis, final FunctionType pTarget) { | ||
416 | return Type.Match.newMatch(pThis, pTarget); | ||
417 | } | ||
418 | |||
419 | /** | ||
420 | * Retrieve the set of values that occur in matches for This. | ||
421 | * @return the Set of all values or empty set if there are no matches | ||
422 | * | ||
423 | */ | ||
424 | protected Stream<Function> rawStreamAllValuesOfThis(final Object[] parameters) { | ||
425 | return rawStreamAllValues(POSITION_THIS, parameters).map(Function.class::cast); | ||
426 | } | ||
427 | |||
428 | /** | ||
429 | * Retrieve the set of values that occur in matches for This. | ||
430 | * @return the Set of all values or empty set if there are no matches | ||
431 | * | ||
432 | */ | ||
433 | public Set<Function> getAllValuesOfThis() { | ||
434 | return rawStreamAllValuesOfThis(emptyArray()).collect(Collectors.toSet()); | ||
435 | } | ||
436 | |||
437 | /** | ||
438 | * Retrieve the set of values that occur in matches for This. | ||
439 | * @return the Set of all values or empty set if there are no matches | ||
440 | * | ||
441 | */ | ||
442 | public Stream<Function> streamAllValuesOfThis() { | ||
443 | return rawStreamAllValuesOfThis(emptyArray()); | ||
444 | } | ||
445 | |||
446 | /** | ||
447 | * Retrieve the set of values that occur in matches for This. | ||
448 | * </p> | ||
449 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
450 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
451 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
452 | * | ||
453 | * @return the Stream of all values or empty set if there are no matches | ||
454 | * | ||
455 | */ | ||
456 | public Stream<Function> streamAllValuesOfThis(final Type.Match partialMatch) { | ||
457 | return rawStreamAllValuesOfThis(partialMatch.toArray()); | ||
458 | } | ||
459 | |||
460 | /** | ||
461 | * Retrieve the set of values that occur in matches for This. | ||
462 | * </p> | ||
463 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
464 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
465 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
466 | * | ||
467 | * @return the Stream of all values or empty set if there are no matches | ||
468 | * | ||
469 | */ | ||
470 | public Stream<Function> streamAllValuesOfThis(final FunctionType pTarget) { | ||
471 | return rawStreamAllValuesOfThis(new Object[]{null, pTarget}); | ||
472 | } | ||
473 | |||
474 | /** | ||
475 | * Retrieve the set of values that occur in matches for This. | ||
476 | * @return the Set of all values or empty set if there are no matches | ||
477 | * | ||
478 | */ | ||
479 | public Set<Function> getAllValuesOfThis(final Type.Match partialMatch) { | ||
480 | return rawStreamAllValuesOfThis(partialMatch.toArray()).collect(Collectors.toSet()); | ||
481 | } | ||
482 | |||
483 | /** | ||
484 | * Retrieve the set of values that occur in matches for This. | ||
485 | * @return the Set of all values or empty set if there are no matches | ||
486 | * | ||
487 | */ | ||
488 | public Set<Function> getAllValuesOfThis(final FunctionType pTarget) { | ||
489 | return rawStreamAllValuesOfThis(new Object[]{null, pTarget}).collect(Collectors.toSet()); | ||
490 | } | ||
491 | |||
492 | /** | ||
493 | * Retrieve the set of values that occur in matches for Target. | ||
494 | * @return the Set of all values or empty set if there are no matches | ||
495 | * | ||
496 | */ | ||
497 | protected Stream<FunctionType> rawStreamAllValuesOfTarget(final Object[] parameters) { | ||
498 | return rawStreamAllValues(POSITION_TARGET, parameters).map(FunctionType.class::cast); | ||
499 | } | ||
500 | |||
501 | /** | ||
502 | * Retrieve the set of values that occur in matches for Target. | ||
503 | * @return the Set of all values or empty set if there are no matches | ||
504 | * | ||
505 | */ | ||
506 | public Set<FunctionType> getAllValuesOfTarget() { | ||
507 | return rawStreamAllValuesOfTarget(emptyArray()).collect(Collectors.toSet()); | ||
508 | } | ||
509 | |||
510 | /** | ||
511 | * Retrieve the set of values that occur in matches for Target. | ||
512 | * @return the Set of all values or empty set if there are no matches | ||
513 | * | ||
514 | */ | ||
515 | public Stream<FunctionType> streamAllValuesOfTarget() { | ||
516 | return rawStreamAllValuesOfTarget(emptyArray()); | ||
517 | } | ||
518 | |||
519 | /** | ||
520 | * Retrieve the set of values that occur in matches for Target. | ||
521 | * </p> | ||
522 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
523 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
524 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
525 | * | ||
526 | * @return the Stream of all values or empty set if there are no matches | ||
527 | * | ||
528 | */ | ||
529 | public Stream<FunctionType> streamAllValuesOfTarget(final Type.Match partialMatch) { | ||
530 | return rawStreamAllValuesOfTarget(partialMatch.toArray()); | ||
531 | } | ||
532 | |||
533 | /** | ||
534 | * Retrieve the set of values that occur in matches for Target. | ||
535 | * </p> | ||
536 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
537 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
538 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
539 | * | ||
540 | * @return the Stream of all values or empty set if there are no matches | ||
541 | * | ||
542 | */ | ||
543 | public Stream<FunctionType> streamAllValuesOfTarget(final Function pThis) { | ||
544 | return rawStreamAllValuesOfTarget(new Object[]{pThis, null}); | ||
545 | } | ||
546 | |||
547 | /** | ||
548 | * Retrieve the set of values that occur in matches for Target. | ||
549 | * @return the Set of all values or empty set if there are no matches | ||
550 | * | ||
551 | */ | ||
552 | public Set<FunctionType> getAllValuesOfTarget(final Type.Match partialMatch) { | ||
553 | return rawStreamAllValuesOfTarget(partialMatch.toArray()).collect(Collectors.toSet()); | ||
554 | } | ||
555 | |||
556 | /** | ||
557 | * Retrieve the set of values that occur in matches for Target. | ||
558 | * @return the Set of all values or empty set if there are no matches | ||
559 | * | ||
560 | */ | ||
561 | public Set<FunctionType> getAllValuesOfTarget(final Function pThis) { | ||
562 | return rawStreamAllValuesOfTarget(new Object[]{pThis, null}).collect(Collectors.toSet()); | ||
563 | } | ||
564 | |||
565 | @Override | ||
566 | protected Type.Match tupleToMatch(final Tuple t) { | ||
567 | try { | ||
568 | return Type.Match.newMatch((Function) t.get(POSITION_THIS), (FunctionType) t.get(POSITION_TARGET)); | ||
569 | } catch(ClassCastException e) { | ||
570 | LOGGER.error("Element(s) in tuple not properly typed!",e); | ||
571 | return null; | ||
572 | } | ||
573 | } | ||
574 | |||
575 | @Override | ||
576 | protected Type.Match arrayToMatch(final Object[] match) { | ||
577 | try { | ||
578 | return Type.Match.newMatch((Function) match[POSITION_THIS], (FunctionType) match[POSITION_TARGET]); | ||
579 | } catch(ClassCastException e) { | ||
580 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
581 | return null; | ||
582 | } | ||
583 | } | ||
584 | |||
585 | @Override | ||
586 | protected Type.Match arrayToMatchMutable(final Object[] match) { | ||
587 | try { | ||
588 | return Type.Match.newMutableMatch((Function) match[POSITION_THIS], (FunctionType) match[POSITION_TARGET]); | ||
589 | } catch(ClassCastException e) { | ||
590 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
591 | return null; | ||
592 | } | ||
593 | } | ||
594 | |||
595 | /** | ||
596 | * @return the singleton instance of the query specification of this pattern | ||
597 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
598 | * | ||
599 | */ | ||
600 | public static IQuerySpecification<Type.Matcher> querySpecification() { | ||
601 | return Type.instance(); | ||
602 | } | ||
603 | } | ||
604 | |||
605 | private Type() { | ||
606 | super(GeneratedPQuery.INSTANCE); | ||
607 | } | ||
608 | |||
609 | /** | ||
610 | * @return the singleton instance of the query specification | ||
611 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
612 | * | ||
613 | */ | ||
614 | public static Type instance() { | ||
615 | try{ | ||
616 | return LazyHolder.INSTANCE; | ||
617 | } catch (ExceptionInInitializerError err) { | ||
618 | throw processInitializerError(err); | ||
619 | } | ||
620 | } | ||
621 | |||
622 | @Override | ||
623 | protected Type.Matcher instantiate(final ViatraQueryEngine engine) { | ||
624 | return Type.Matcher.on(engine); | ||
625 | } | ||
626 | |||
627 | @Override | ||
628 | public Type.Matcher instantiate() { | ||
629 | return Type.Matcher.create(); | ||
630 | } | ||
631 | |||
632 | @Override | ||
633 | public Type.Match newEmptyMatch() { | ||
634 | return Type.Match.newEmptyMatch(); | ||
635 | } | ||
636 | |||
637 | @Override | ||
638 | public Type.Match newMatch(final Object... parameters) { | ||
639 | return Type.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.fam.Function) parameters[0], (ca.mcgill.ecse.dslreasoner.standalone.test.fam.FunctionType) parameters[1]); | ||
640 | } | ||
641 | |||
642 | /** | ||
643 | * Inner class allowing the singleton instance of {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries.Type (visibility: PUBLIC, simpleName: Type, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries.Type, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created | ||
644 | * <b>not</b> at the class load time of the outer class, | ||
645 | * but rather at the first call to {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries.Type (visibility: PUBLIC, simpleName: Type, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries.Type, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. | ||
646 | * | ||
647 | * <p> This workaround is required e.g. to support recursion. | ||
648 | * | ||
649 | */ | ||
650 | private static class LazyHolder { | ||
651 | private final static Type INSTANCE = new Type(); | ||
652 | |||
653 | /** | ||
654 | * Statically initializes the query specification <b>after</b> the field {@link #INSTANCE} is assigned. | ||
655 | * This initialization order is required to support indirect recursion. | ||
656 | * | ||
657 | * <p> The static initializer is defined using a helper field to work around limitations of the code generator. | ||
658 | * | ||
659 | */ | ||
660 | private final static Object STATIC_INITIALIZER = ensureInitialized(); | ||
661 | |||
662 | public static Object ensureInitialized() { | ||
663 | INSTANCE.ensureInitializedInternal(); | ||
664 | return null; | ||
665 | } | ||
666 | } | ||
667 | |||
668 | private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { | ||
669 | private final static Type.GeneratedPQuery INSTANCE = new GeneratedPQuery(); | ||
670 | |||
671 | private final PParameter parameter_This = new PParameter("This", "ca.mcgill.ecse.dslreasoner.standalone.test.fam.Function", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("FamMetamodel", "Function")), PParameterDirection.INOUT); | ||
672 | |||
673 | private final PParameter parameter_Target = new PParameter("Target", "ca.mcgill.ecse.dslreasoner.standalone.test.fam.FunctionType", new EDataTypeInSlotsKey((EDataType)getClassifierLiteralSafe("FamMetamodel", "FunctionType")), PParameterDirection.INOUT); | ||
674 | |||
675 | private final List<PParameter> parameters = Arrays.asList(parameter_This, parameter_Target); | ||
676 | |||
677 | private GeneratedPQuery() { | ||
678 | super(PVisibility.PUBLIC); | ||
679 | } | ||
680 | |||
681 | @Override | ||
682 | public String getFullyQualifiedName() { | ||
683 | return "ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries.type"; | ||
684 | } | ||
685 | |||
686 | @Override | ||
687 | public List<String> getParameterNames() { | ||
688 | return Arrays.asList("This","Target"); | ||
689 | } | ||
690 | |||
691 | @Override | ||
692 | public List<PParameter> getParameters() { | ||
693 | return parameters; | ||
694 | } | ||
695 | |||
696 | @Override | ||
697 | public Set<PBody> doGetContainedBodies() { | ||
698 | setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); | ||
699 | Set<PBody> bodies = new LinkedHashSet<>(); | ||
700 | { | ||
701 | PBody body = new PBody(this); | ||
702 | PVariable var_This = body.getOrCreateVariableByName("This"); | ||
703 | PVariable var_Target = body.getOrCreateVariableByName("Target"); | ||
704 | PVariable var__Model = body.getOrCreateVariableByName("_Model"); | ||
705 | new TypeConstraint(body, Tuples.flatTupleOf(var_This), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("FamMetamodel", "Function"))); | ||
706 | new TypeConstraint(body, Tuples.flatTupleOf(var_Target), new EDataTypeInSlotsKey((EDataType)getClassifierLiteral("FamMetamodel", "FunctionType"))); | ||
707 | body.setSymbolicParameters(Arrays.<ExportedParameter>asList( | ||
708 | new ExportedParameter(body, var_This, parameter_This), | ||
709 | new ExportedParameter(body, var_Target, parameter_Target) | ||
710 | )); | ||
711 | // find rootElements(_Model, This) | ||
712 | new PositivePatternCall(body, Tuples.flatTupleOf(var__Model, var_This), RootElements.instance().getInternalQueryRepresentation()); | ||
713 | // Target == FunctionType::Root | ||
714 | PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); | ||
715 | new ConstantValue(body, var__virtual_0_, getEnumLiteral("FamMetamodel", "FunctionType", "Root").getInstance()); | ||
716 | new Equality(body, var_Target, var__virtual_0_); | ||
717 | bodies.add(body); | ||
718 | } | ||
719 | { | ||
720 | PBody body = new PBody(this); | ||
721 | PVariable var_This = body.getOrCreateVariableByName("This"); | ||
722 | PVariable var_Target = body.getOrCreateVariableByName("Target"); | ||
723 | PVariable var__Child = body.getOrCreateVariableByName("_Child"); | ||
724 | PVariable var__Model = body.getOrCreateVariableByName("_Model"); | ||
725 | new TypeConstraint(body, Tuples.flatTupleOf(var_This), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("FamMetamodel", "Function"))); | ||
726 | new TypeConstraint(body, Tuples.flatTupleOf(var_Target), new EDataTypeInSlotsKey((EDataType)getClassifierLiteral("FamMetamodel", "FunctionType"))); | ||
727 | body.setSymbolicParameters(Arrays.<ExportedParameter>asList( | ||
728 | new ExportedParameter(body, var_This, parameter_This), | ||
729 | new ExportedParameter(body, var_Target, parameter_Target) | ||
730 | )); | ||
731 | // neg find parent(_Child, This) | ||
732 | new NegativePatternCall(body, Tuples.flatTupleOf(var__Child, var_This), Parent.instance().getInternalQueryRepresentation()); | ||
733 | // neg find rootElements(_Model, This) | ||
734 | new NegativePatternCall(body, Tuples.flatTupleOf(var__Model, var_This), RootElements.instance().getInternalQueryRepresentation()); | ||
735 | // Target == FunctionType::Leaf | ||
736 | PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); | ||
737 | new ConstantValue(body, var__virtual_0_, getEnumLiteral("FamMetamodel", "FunctionType", "Leaf").getInstance()); | ||
738 | new Equality(body, var_Target, var__virtual_0_); | ||
739 | bodies.add(body); | ||
740 | } | ||
741 | { | ||
742 | PBody body = new PBody(this); | ||
743 | PVariable var_This = body.getOrCreateVariableByName("This"); | ||
744 | PVariable var_Target = body.getOrCreateVariableByName("Target"); | ||
745 | PVariable var__Par = body.getOrCreateVariableByName("_Par"); | ||
746 | PVariable var__Child = body.getOrCreateVariableByName("_Child"); | ||
747 | new TypeConstraint(body, Tuples.flatTupleOf(var_This), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("FamMetamodel", "Function"))); | ||
748 | new TypeConstraint(body, Tuples.flatTupleOf(var_Target), new EDataTypeInSlotsKey((EDataType)getClassifierLiteral("FamMetamodel", "FunctionType"))); | ||
749 | body.setSymbolicParameters(Arrays.<ExportedParameter>asList( | ||
750 | new ExportedParameter(body, var_This, parameter_This), | ||
751 | new ExportedParameter(body, var_Target, parameter_Target) | ||
752 | )); | ||
753 | // find parent(This, _Par) | ||
754 | new PositivePatternCall(body, Tuples.flatTupleOf(var_This, var__Par), Parent.instance().getInternalQueryRepresentation()); | ||
755 | // find parent(_Child, This) | ||
756 | new PositivePatternCall(body, Tuples.flatTupleOf(var__Child, var_This), Parent.instance().getInternalQueryRepresentation()); | ||
757 | // Target == FunctionType::Intermediate | ||
758 | PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); | ||
759 | new ConstantValue(body, var__virtual_0_, getEnumLiteral("FamMetamodel", "FunctionType", "Intermediate").getInstance()); | ||
760 | new Equality(body, var_Target, var__virtual_0_); | ||
761 | bodies.add(body); | ||
762 | } | ||
763 | { | ||
764 | PAnnotation annotation = new PAnnotation("QueryBasedFeature"); | ||
765 | addAnnotation(annotation); | ||
766 | } | ||
767 | return bodies; | ||
768 | } | ||
769 | } | ||
770 | } | ||
diff --git a/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/filesystem/queries/.gitignore b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/filesystem/queries/.gitignore new file mode 100644 index 00000000..dcc36d34 --- /dev/null +++ b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/filesystem/queries/.gitignore | |||
@@ -0,0 +1,9 @@ | |||
1 | /.ContentInNotLive.java._trace | ||
2 | /.FileSystem.java._trace | ||
3 | /.Live.java._trace | ||
4 | /.PatternContent.java._trace | ||
5 | /.FileSystemPatterns.java._trace | ||
6 | /PatternContent.java | ||
7 | /ContentInNotLive.java | ||
8 | /FileSystemPatterns.java | ||
9 | /Live.java | ||
diff --git a/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/.gitignore b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/.gitignore new file mode 100644 index 00000000..96fd178f --- /dev/null +++ b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/.gitignore | |||
@@ -0,0 +1,158 @@ | |||
1 | /.EntryInRegion_M0.java._trace | ||
2 | /.EntryInRegion_M1.java._trace | ||
3 | /.EntryInRegion_M2.java._trace | ||
4 | /.MultipleEntryInRegion_M0.java._trace | ||
5 | /.MultipleEntryInRegion_M1.java._trace | ||
6 | /.MultipleEntryInRegion_M2.java._trace | ||
7 | /.NoEntryInRegion_M0.java._trace | ||
8 | /.NoEntryInRegion_M1.java._trace | ||
9 | /.NoEntryInRegion_M2.java._trace | ||
10 | /.NoEntryInRegion_M3.java._trace | ||
11 | /.NoEntryInRegion_M4.java._trace | ||
12 | /.NoEntryInRegion_M5.java._trace | ||
13 | /.MultipleEntryInRegion_M3.java._trace | ||
14 | /.EntryInRegion.java._trace | ||
15 | /.MultipleEntryInRegion.java._trace | ||
16 | /.NoEntryInRegion.java._trace | ||
17 | /.Transition.java._trace | ||
18 | /.Child.java._trace | ||
19 | /.ChoiceHasNoIncoming.java._trace | ||
20 | /.ChoiceHasNoOutgoing.java._trace | ||
21 | /.HasMultipleIncomingTrainsition.java._trace | ||
22 | /.HasMultipleOutgoingTrainsition.java._trace | ||
23 | /.HasMultipleRegions.java._trace | ||
24 | /.IncomingToEntry.java._trace | ||
25 | /.MultipleTransitionFromEntry.java._trace | ||
26 | /.NoOutgoingTransitionFromEntry.java._trace | ||
27 | /.NoStateInRegion.java._trace | ||
28 | /.NotSynchronizingStates.java._trace | ||
29 | /.OutgoingFromExit.java._trace | ||
30 | /.OutgoingFromFinal.java._trace | ||
31 | /.StateInRegion.java._trace | ||
32 | /.SynchHasNoIncoming.java._trace | ||
33 | /.SynchHasNoOutgoing.java._trace | ||
34 | /.SynchThree.java._trace | ||
35 | /.SynchronizedIncomingInSameRegion.java._trace | ||
36 | /.SynchronizedRegionDoesNotHaveMultipleRegions.java._trace | ||
37 | /.SynchronizedRegionsAreNotSiblings.java._trace | ||
38 | /.TwoSynch.java._trace | ||
39 | /.YakinduPatterns.java._trace | ||
40 | /.ChoiceHasNoIncoming_M0.java._trace | ||
41 | /.ChoiceHasNoIncoming_M1.java._trace | ||
42 | /.ChoiceHasNoIncoming_M2.java._trace | ||
43 | /.ChoiceHasNoIncoming_M3.java._trace | ||
44 | /.ChoiceHasNoIncoming_M4.java._trace | ||
45 | /.ChoiceHasNoIncoming_M5.java._trace | ||
46 | /.ChoiceHasNoIncoming_M6.java._trace | ||
47 | /.ChoiceHasNoOutgoing_M0.java._trace | ||
48 | /.ChoiceHasNoOutgoing_M1.java._trace | ||
49 | /.ChoiceHasNoOutgoing_M2.java._trace | ||
50 | /.ChoiceHasNoOutgoing_M3.java._trace | ||
51 | /.ChoiceHasNoOutgoing_M4.java._trace | ||
52 | /.ChoiceHasNoOutgoing_M5.java._trace | ||
53 | /.ChoiceHasNoOutgoing_M6.java._trace | ||
54 | /.IncomingToEntry_1.java._trace | ||
55 | /.IncomingToEntry_2.java._trace | ||
56 | /.IncomingToEntry_3.java._trace | ||
57 | /.IncomingToEntry_4.java._trace | ||
58 | /.IncomingToEntry_5.java._trace | ||
59 | /.IncomingToEntry_M0.java._trace | ||
60 | /.MultipleEntryInRegion_M4.java._trace | ||
61 | /.MultipleEntryInRegion_M5.java._trace | ||
62 | /.MultipleTransitionFromEntry_M0.java._trace | ||
63 | /.MultipleTransitionFromEntry_M1.java._trace | ||
64 | /.MultipleTransitionFromEntry_M2.java._trace | ||
65 | /.MultipleTransitionFromEntry_M3.java._trace | ||
66 | /.MultipleTransitionFromEntry_M4.java._trace | ||
67 | /.NoOutgoingTransitionFromEntry_M0.java._trace | ||
68 | /.NoOutgoingTransitionFromEntry_M1.java._trace | ||
69 | /.NoOutgoingTransitionFromEntry_M2.java._trace | ||
70 | /.NoOutgoingTransitionFromEntry_M3.java._trace | ||
71 | /.NoOutgoingTransitionFromEntry_M4.java._trace | ||
72 | /.NoOutgoingTransitionFromEntry_M5.java._trace | ||
73 | /.NoStateInRegion_M0.java._trace | ||
74 | /.NoStateInRegion_M1.java._trace | ||
75 | /.NoStateInRegion_M2.java._trace | ||
76 | /.NoStateInRegion_M3.java._trace | ||
77 | /.OutgoingFromExit_M0.java._trace | ||
78 | /.OutgoingFromExit_M1.java._trace | ||
79 | /.OutgoingFromExit_M2.java._trace | ||
80 | /.OutgoingFromFinal_M0.java._trace | ||
81 | /.OutgoingFromFinal_M1.java._trace | ||
82 | /.OutgoingFromFinal_M2.java._trace | ||
83 | /.StateInRegion_M0.java._trace | ||
84 | /.StateInRegion_M1.java._trace | ||
85 | /.StateInRegion_M2.java._trace | ||
86 | /.Transition_M0.java._trace | ||
87 | /.Transition_M1.java._trace | ||
88 | /.Transition_M2.java._trace | ||
89 | /.Transition_M3.java._trace | ||
90 | /.Transition_M4.java._trace | ||
91 | /.YakinduMutatedPatterns.java._trace | ||
92 | /YakinduPatterns.java | ||
93 | /MultipleEntryInRegion.java | ||
94 | /ChoiceHasNoIncoming_M0.java | ||
95 | /ChoiceHasNoIncoming_M1.java | ||
96 | /ChoiceHasNoIncoming_M2.java | ||
97 | /ChoiceHasNoIncoming_M3.java | ||
98 | /ChoiceHasNoIncoming_M4.java | ||
99 | /ChoiceHasNoIncoming_M5.java | ||
100 | /ChoiceHasNoIncoming_M6.java | ||
101 | /ChoiceHasNoOutgoing_M0.java | ||
102 | /ChoiceHasNoOutgoing_M1.java | ||
103 | /ChoiceHasNoOutgoing_M2.java | ||
104 | /ChoiceHasNoOutgoing_M3.java | ||
105 | /ChoiceHasNoOutgoing_M4.java | ||
106 | /ChoiceHasNoOutgoing_M5.java | ||
107 | /ChoiceHasNoOutgoing_M6.java | ||
108 | /EntryInRegion_M0.java | ||
109 | /EntryInRegion_M1.java | ||
110 | /EntryInRegion_M2.java | ||
111 | /IncomingToEntry_1.java | ||
112 | /IncomingToEntry_2.java | ||
113 | /IncomingToEntry_3.java | ||
114 | /IncomingToEntry_4.java | ||
115 | /IncomingToEntry_5.java | ||
116 | /IncomingToEntry_M0.java | ||
117 | /MultipleEntryInRegion_M0.java | ||
118 | /MultipleEntryInRegion_M1.java | ||
119 | /MultipleEntryInRegion_M2.java | ||
120 | /MultipleEntryInRegion_M3.java | ||
121 | /MultipleEntryInRegion_M4.java | ||
122 | /MultipleEntryInRegion_M5.java | ||
123 | /MultipleTransitionFromEntry_M0.java | ||
124 | /MultipleTransitionFromEntry_M1.java | ||
125 | /MultipleTransitionFromEntry_M2.java | ||
126 | /MultipleTransitionFromEntry_M3.java | ||
127 | /MultipleTransitionFromEntry_M4.java | ||
128 | /NoEntryInRegion_M0.java | ||
129 | /NoEntryInRegion_M1.java | ||
130 | /NoEntryInRegion_M2.java | ||
131 | /NoEntryInRegion_M3.java | ||
132 | /NoEntryInRegion_M4.java | ||
133 | /NoEntryInRegion_M5.java | ||
134 | /NoOutgoingTransitionFromEntry_M0.java | ||
135 | /NoOutgoingTransitionFromEntry_M1.java | ||
136 | /NoOutgoingTransitionFromEntry_M2.java | ||
137 | /NoOutgoingTransitionFromEntry_M3.java | ||
138 | /NoOutgoingTransitionFromEntry_M4.java | ||
139 | /NoOutgoingTransitionFromEntry_M5.java | ||
140 | /NoStateInRegion_M0.java | ||
141 | /NoStateInRegion_M1.java | ||
142 | /NoStateInRegion_M2.java | ||
143 | /NoStateInRegion_M3.java | ||
144 | /OutgoingFromExit_M0.java | ||
145 | /OutgoingFromExit_M1.java | ||
146 | /OutgoingFromExit_M2.java | ||
147 | /OutgoingFromFinal_M0.java | ||
148 | /OutgoingFromFinal_M1.java | ||
149 | /OutgoingFromFinal_M2.java | ||
150 | /StateInRegion_M0.java | ||
151 | /StateInRegion_M1.java | ||
152 | /StateInRegion_M2.java | ||
153 | /Transition_M0.java | ||
154 | /Transition_M1.java | ||
155 | /Transition_M2.java | ||
156 | /Transition_M3.java | ||
157 | /Transition_M4.java | ||
158 | /YakinduMutatedPatterns.java | ||
diff --git a/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/Child.java b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/Child.java new file mode 100644 index 00000000..9867c1ee --- /dev/null +++ b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/Child.java | |||
@@ -0,0 +1,721 @@ | |||
1 | /** | ||
2 | * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql | ||
3 | */ | ||
4 | package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; | ||
5 | |||
6 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.CompositeElement; | ||
7 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex; | ||
8 | import java.util.Arrays; | ||
9 | import java.util.Collection; | ||
10 | import java.util.LinkedHashSet; | ||
11 | import java.util.List; | ||
12 | import java.util.Objects; | ||
13 | import java.util.Optional; | ||
14 | import java.util.Set; | ||
15 | import java.util.function.Consumer; | ||
16 | import java.util.stream.Collectors; | ||
17 | import java.util.stream.Stream; | ||
18 | import org.apache.log4j.Logger; | ||
19 | import org.eclipse.emf.ecore.EClass; | ||
20 | import org.eclipse.viatra.query.runtime.api.IPatternMatch; | ||
21 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification; | ||
22 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; | ||
23 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; | ||
24 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; | ||
25 | import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; | ||
26 | import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; | ||
27 | import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; | ||
28 | import org.eclipse.viatra.query.runtime.emf.types.EStructuralFeatureInstancesKey; | ||
29 | import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; | ||
30 | import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; | ||
31 | import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; | ||
32 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality; | ||
33 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; | ||
34 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; | ||
35 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; | ||
36 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; | ||
37 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; | ||
38 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; | ||
39 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | ||
40 | import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; | ||
41 | |||
42 | /** | ||
43 | * A pattern-specific query specification that can instantiate Matcher in a type-safe way. | ||
44 | * | ||
45 | * <p>Original source: | ||
46 | * <code><pre> | ||
47 | * /////////////////////////////// | ||
48 | * // Extra | ||
49 | * // | ||
50 | * //{@literal @}Constraint(severity="error", message="error", key = {s}) | ||
51 | * //pattern SynchronizedRegionDoesNotHaveParent(s : Synchronization, v : Vertex) { | ||
52 | * // find transition(_, v, s); | ||
53 | * // neg find child(_,v); | ||
54 | * //} or { | ||
55 | * // find transition(_, s, v); | ||
56 | * // neg find child(_,v); | ||
57 | * //} | ||
58 | * | ||
59 | * pattern child(parent: CompositeElement, child: Vertex) { | ||
60 | * CompositeElement.regions.vertices(parent, child); | ||
61 | * } | ||
62 | * </pre></code> | ||
63 | * | ||
64 | * @see Matcher | ||
65 | * @see Match | ||
66 | * | ||
67 | */ | ||
68 | @SuppressWarnings("all") | ||
69 | public final class Child extends BaseGeneratedEMFQuerySpecification<Child.Matcher> { | ||
70 | /** | ||
71 | * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.child pattern, | ||
72 | * to be used in conjunction with {@link Matcher}. | ||
73 | * | ||
74 | * <p>Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. | ||
75 | * Each instance is a (possibly partial) substitution of pattern parameters, | ||
76 | * usable to represent a match of the pattern in the result of a query, | ||
77 | * or to specify the bound (fixed) input parameters when issuing a query. | ||
78 | * | ||
79 | * @see Matcher | ||
80 | * | ||
81 | */ | ||
82 | public static abstract class Match extends BasePatternMatch { | ||
83 | private CompositeElement fParent; | ||
84 | |||
85 | private Vertex fChild; | ||
86 | |||
87 | private static List<String> parameterNames = makeImmutableList("parent", "child"); | ||
88 | |||
89 | private Match(final CompositeElement pParent, final Vertex pChild) { | ||
90 | this.fParent = pParent; | ||
91 | this.fChild = pChild; | ||
92 | } | ||
93 | |||
94 | @Override | ||
95 | public Object get(final String parameterName) { | ||
96 | if ("parent".equals(parameterName)) return this.fParent; | ||
97 | if ("child".equals(parameterName)) return this.fChild; | ||
98 | return null; | ||
99 | } | ||
100 | |||
101 | public CompositeElement getParent() { | ||
102 | return this.fParent; | ||
103 | } | ||
104 | |||
105 | public Vertex getChild() { | ||
106 | return this.fChild; | ||
107 | } | ||
108 | |||
109 | @Override | ||
110 | public boolean set(final String parameterName, final Object newValue) { | ||
111 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
112 | if ("parent".equals(parameterName) ) { | ||
113 | this.fParent = (CompositeElement) newValue; | ||
114 | return true; | ||
115 | } | ||
116 | if ("child".equals(parameterName) ) { | ||
117 | this.fChild = (Vertex) newValue; | ||
118 | return true; | ||
119 | } | ||
120 | return false; | ||
121 | } | ||
122 | |||
123 | public void setParent(final CompositeElement pParent) { | ||
124 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
125 | this.fParent = pParent; | ||
126 | } | ||
127 | |||
128 | public void setChild(final Vertex pChild) { | ||
129 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
130 | this.fChild = pChild; | ||
131 | } | ||
132 | |||
133 | @Override | ||
134 | public String patternName() { | ||
135 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.child"; | ||
136 | } | ||
137 | |||
138 | @Override | ||
139 | public List<String> parameterNames() { | ||
140 | return Child.Match.parameterNames; | ||
141 | } | ||
142 | |||
143 | @Override | ||
144 | public Object[] toArray() { | ||
145 | return new Object[]{fParent, fChild}; | ||
146 | } | ||
147 | |||
148 | @Override | ||
149 | public Child.Match toImmutable() { | ||
150 | return isMutable() ? newMatch(fParent, fChild) : this; | ||
151 | } | ||
152 | |||
153 | @Override | ||
154 | public String prettyPrint() { | ||
155 | StringBuilder result = new StringBuilder(); | ||
156 | result.append("\"parent\"=" + prettyPrintValue(fParent) + ", "); | ||
157 | result.append("\"child\"=" + prettyPrintValue(fChild)); | ||
158 | return result.toString(); | ||
159 | } | ||
160 | |||
161 | @Override | ||
162 | public int hashCode() { | ||
163 | return Objects.hash(fParent, fChild); | ||
164 | } | ||
165 | |||
166 | @Override | ||
167 | public boolean equals(final Object obj) { | ||
168 | if (this == obj) | ||
169 | return true; | ||
170 | if (obj == null) { | ||
171 | return false; | ||
172 | } | ||
173 | if ((obj instanceof Child.Match)) { | ||
174 | Child.Match other = (Child.Match) obj; | ||
175 | return Objects.equals(fParent, other.fParent) && Objects.equals(fChild, other.fChild); | ||
176 | } else { | ||
177 | // this should be infrequent | ||
178 | if (!(obj instanceof IPatternMatch)) { | ||
179 | return false; | ||
180 | } | ||
181 | IPatternMatch otherSig = (IPatternMatch) obj; | ||
182 | return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); | ||
183 | } | ||
184 | } | ||
185 | |||
186 | @Override | ||
187 | public Child specification() { | ||
188 | return Child.instance(); | ||
189 | } | ||
190 | |||
191 | /** | ||
192 | * Returns an empty, mutable match. | ||
193 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
194 | * | ||
195 | * @return the empty match. | ||
196 | * | ||
197 | */ | ||
198 | public static Child.Match newEmptyMatch() { | ||
199 | return new Mutable(null, null); | ||
200 | } | ||
201 | |||
202 | /** | ||
203 | * Returns a mutable (partial) match. | ||
204 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
205 | * | ||
206 | * @param pParent the fixed value of pattern parameter parent, or null if not bound. | ||
207 | * @param pChild the fixed value of pattern parameter child, or null if not bound. | ||
208 | * @return the new, mutable (partial) match object. | ||
209 | * | ||
210 | */ | ||
211 | public static Child.Match newMutableMatch(final CompositeElement pParent, final Vertex pChild) { | ||
212 | return new Mutable(pParent, pChild); | ||
213 | } | ||
214 | |||
215 | /** | ||
216 | * Returns a new (partial) match. | ||
217 | * This can be used e.g. to call the matcher with a partial match. | ||
218 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
219 | * @param pParent the fixed value of pattern parameter parent, or null if not bound. | ||
220 | * @param pChild the fixed value of pattern parameter child, or null if not bound. | ||
221 | * @return the (partial) match object. | ||
222 | * | ||
223 | */ | ||
224 | public static Child.Match newMatch(final CompositeElement pParent, final Vertex pChild) { | ||
225 | return new Immutable(pParent, pChild); | ||
226 | } | ||
227 | |||
228 | private static final class Mutable extends Child.Match { | ||
229 | Mutable(final CompositeElement pParent, final Vertex pChild) { | ||
230 | super(pParent, pChild); | ||
231 | } | ||
232 | |||
233 | @Override | ||
234 | public boolean isMutable() { | ||
235 | return true; | ||
236 | } | ||
237 | } | ||
238 | |||
239 | private static final class Immutable extends Child.Match { | ||
240 | Immutable(final CompositeElement pParent, final Vertex pChild) { | ||
241 | super(pParent, pChild); | ||
242 | } | ||
243 | |||
244 | @Override | ||
245 | public boolean isMutable() { | ||
246 | return false; | ||
247 | } | ||
248 | } | ||
249 | } | ||
250 | |||
251 | /** | ||
252 | * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.child pattern, | ||
253 | * providing pattern-specific query methods. | ||
254 | * | ||
255 | * <p>Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, | ||
256 | * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. | ||
257 | * | ||
258 | * <p>Matches of the pattern will be represented as {@link Match}. | ||
259 | * | ||
260 | * <p>Original source: | ||
261 | * <code><pre> | ||
262 | * /////////////////////////////// | ||
263 | * // Extra | ||
264 | * // | ||
265 | * //{@literal @}Constraint(severity="error", message="error", key = {s}) | ||
266 | * //pattern SynchronizedRegionDoesNotHaveParent(s : Synchronization, v : Vertex) { | ||
267 | * // find transition(_, v, s); | ||
268 | * // neg find child(_,v); | ||
269 | * //} or { | ||
270 | * // find transition(_, s, v); | ||
271 | * // neg find child(_,v); | ||
272 | * //} | ||
273 | * | ||
274 | * pattern child(parent: CompositeElement, child: Vertex) { | ||
275 | * CompositeElement.regions.vertices(parent, child); | ||
276 | * } | ||
277 | * </pre></code> | ||
278 | * | ||
279 | * @see Match | ||
280 | * @see Child | ||
281 | * | ||
282 | */ | ||
283 | public static class Matcher extends BaseMatcher<Child.Match> { | ||
284 | /** | ||
285 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
286 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
287 | * | ||
288 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
289 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
290 | * | ||
291 | */ | ||
292 | public static Child.Matcher on(final ViatraQueryEngine engine) { | ||
293 | // check if matcher already exists | ||
294 | Matcher matcher = engine.getExistingMatcher(querySpecification()); | ||
295 | if (matcher == null) { | ||
296 | matcher = (Matcher)engine.getMatcher(querySpecification()); | ||
297 | } | ||
298 | return matcher; | ||
299 | } | ||
300 | |||
301 | /** | ||
302 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
303 | * @return an initialized matcher | ||
304 | * @noreference This method is for internal matcher initialization by the framework, do not call it manually. | ||
305 | * | ||
306 | */ | ||
307 | public static Child.Matcher create() { | ||
308 | return new Matcher(); | ||
309 | } | ||
310 | |||
311 | private final static int POSITION_PARENT = 0; | ||
312 | |||
313 | private final static int POSITION_CHILD = 1; | ||
314 | |||
315 | private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(Child.Matcher.class); | ||
316 | |||
317 | /** | ||
318 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
319 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
320 | * | ||
321 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
322 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
323 | * | ||
324 | */ | ||
325 | private Matcher() { | ||
326 | super(querySpecification()); | ||
327 | } | ||
328 | |||
329 | /** | ||
330 | * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. | ||
331 | * @param pParent the fixed value of pattern parameter parent, or null if not bound. | ||
332 | * @param pChild the fixed value of pattern parameter child, or null if not bound. | ||
333 | * @return matches represented as a Match object. | ||
334 | * | ||
335 | */ | ||
336 | public Collection<Child.Match> getAllMatches(final CompositeElement pParent, final Vertex pChild) { | ||
337 | return rawStreamAllMatches(new Object[]{pParent, pChild}).collect(Collectors.toSet()); | ||
338 | } | ||
339 | |||
340 | /** | ||
341 | * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. | ||
342 | * </p> | ||
343 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
344 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
345 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
346 | * @param pParent the fixed value of pattern parameter parent, or null if not bound. | ||
347 | * @param pChild the fixed value of pattern parameter child, or null if not bound. | ||
348 | * @return a stream of matches represented as a Match object. | ||
349 | * | ||
350 | */ | ||
351 | public Stream<Child.Match> streamAllMatches(final CompositeElement pParent, final Vertex pChild) { | ||
352 | return rawStreamAllMatches(new Object[]{pParent, pChild}); | ||
353 | } | ||
354 | |||
355 | /** | ||
356 | * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
357 | * Neither determinism nor randomness of selection is guaranteed. | ||
358 | * @param pParent the fixed value of pattern parameter parent, or null if not bound. | ||
359 | * @param pChild the fixed value of pattern parameter child, or null if not bound. | ||
360 | * @return a match represented as a Match object, or null if no match is found. | ||
361 | * | ||
362 | */ | ||
363 | public Optional<Child.Match> getOneArbitraryMatch(final CompositeElement pParent, final Vertex pChild) { | ||
364 | return rawGetOneArbitraryMatch(new Object[]{pParent, pChild}); | ||
365 | } | ||
366 | |||
367 | /** | ||
368 | * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, | ||
369 | * under any possible substitution of the unspecified parameters (if any). | ||
370 | * @param pParent the fixed value of pattern parameter parent, or null if not bound. | ||
371 | * @param pChild the fixed value of pattern parameter child, or null if not bound. | ||
372 | * @return true if the input is a valid (partial) match of the pattern. | ||
373 | * | ||
374 | */ | ||
375 | public boolean hasMatch(final CompositeElement pParent, final Vertex pChild) { | ||
376 | return rawHasMatch(new Object[]{pParent, pChild}); | ||
377 | } | ||
378 | |||
379 | /** | ||
380 | * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. | ||
381 | * @param pParent the fixed value of pattern parameter parent, or null if not bound. | ||
382 | * @param pChild the fixed value of pattern parameter child, or null if not bound. | ||
383 | * @return the number of pattern matches found. | ||
384 | * | ||
385 | */ | ||
386 | public int countMatches(final CompositeElement pParent, final Vertex pChild) { | ||
387 | return rawCountMatches(new Object[]{pParent, pChild}); | ||
388 | } | ||
389 | |||
390 | /** | ||
391 | * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
392 | * Neither determinism nor randomness of selection is guaranteed. | ||
393 | * @param pParent the fixed value of pattern parameter parent, or null if not bound. | ||
394 | * @param pChild the fixed value of pattern parameter child, or null if not bound. | ||
395 | * @param processor the action that will process the selected match. | ||
396 | * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked | ||
397 | * | ||
398 | */ | ||
399 | public boolean forOneArbitraryMatch(final CompositeElement pParent, final Vertex pChild, final Consumer<? super Child.Match> processor) { | ||
400 | return rawForOneArbitraryMatch(new Object[]{pParent, pChild}, processor); | ||
401 | } | ||
402 | |||
403 | /** | ||
404 | * Returns a new (partial) match. | ||
405 | * This can be used e.g. to call the matcher with a partial match. | ||
406 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
407 | * @param pParent the fixed value of pattern parameter parent, or null if not bound. | ||
408 | * @param pChild the fixed value of pattern parameter child, or null if not bound. | ||
409 | * @return the (partial) match object. | ||
410 | * | ||
411 | */ | ||
412 | public Child.Match newMatch(final CompositeElement pParent, final Vertex pChild) { | ||
413 | return Child.Match.newMatch(pParent, pChild); | ||
414 | } | ||
415 | |||
416 | /** | ||
417 | * Retrieve the set of values that occur in matches for parent. | ||
418 | * @return the Set of all values or empty set if there are no matches | ||
419 | * | ||
420 | */ | ||
421 | protected Stream<CompositeElement> rawStreamAllValuesOfparent(final Object[] parameters) { | ||
422 | return rawStreamAllValues(POSITION_PARENT, parameters).map(CompositeElement.class::cast); | ||
423 | } | ||
424 | |||
425 | /** | ||
426 | * Retrieve the set of values that occur in matches for parent. | ||
427 | * @return the Set of all values or empty set if there are no matches | ||
428 | * | ||
429 | */ | ||
430 | public Set<CompositeElement> getAllValuesOfparent() { | ||
431 | return rawStreamAllValuesOfparent(emptyArray()).collect(Collectors.toSet()); | ||
432 | } | ||
433 | |||
434 | /** | ||
435 | * Retrieve the set of values that occur in matches for parent. | ||
436 | * @return the Set of all values or empty set if there are no matches | ||
437 | * | ||
438 | */ | ||
439 | public Stream<CompositeElement> streamAllValuesOfparent() { | ||
440 | return rawStreamAllValuesOfparent(emptyArray()); | ||
441 | } | ||
442 | |||
443 | /** | ||
444 | * Retrieve the set of values that occur in matches for parent. | ||
445 | * </p> | ||
446 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
447 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
448 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
449 | * | ||
450 | * @return the Stream of all values or empty set if there are no matches | ||
451 | * | ||
452 | */ | ||
453 | public Stream<CompositeElement> streamAllValuesOfparent(final Child.Match partialMatch) { | ||
454 | return rawStreamAllValuesOfparent(partialMatch.toArray()); | ||
455 | } | ||
456 | |||
457 | /** | ||
458 | * Retrieve the set of values that occur in matches for parent. | ||
459 | * </p> | ||
460 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
461 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
462 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
463 | * | ||
464 | * @return the Stream of all values or empty set if there are no matches | ||
465 | * | ||
466 | */ | ||
467 | public Stream<CompositeElement> streamAllValuesOfparent(final Vertex pChild) { | ||
468 | return rawStreamAllValuesOfparent(new Object[]{null, pChild}); | ||
469 | } | ||
470 | |||
471 | /** | ||
472 | * Retrieve the set of values that occur in matches for parent. | ||
473 | * @return the Set of all values or empty set if there are no matches | ||
474 | * | ||
475 | */ | ||
476 | public Set<CompositeElement> getAllValuesOfparent(final Child.Match partialMatch) { | ||
477 | return rawStreamAllValuesOfparent(partialMatch.toArray()).collect(Collectors.toSet()); | ||
478 | } | ||
479 | |||
480 | /** | ||
481 | * Retrieve the set of values that occur in matches for parent. | ||
482 | * @return the Set of all values or empty set if there are no matches | ||
483 | * | ||
484 | */ | ||
485 | public Set<CompositeElement> getAllValuesOfparent(final Vertex pChild) { | ||
486 | return rawStreamAllValuesOfparent(new Object[]{null, pChild}).collect(Collectors.toSet()); | ||
487 | } | ||
488 | |||
489 | /** | ||
490 | * Retrieve the set of values that occur in matches for child. | ||
491 | * @return the Set of all values or empty set if there are no matches | ||
492 | * | ||
493 | */ | ||
494 | protected Stream<Vertex> rawStreamAllValuesOfchild(final Object[] parameters) { | ||
495 | return rawStreamAllValues(POSITION_CHILD, parameters).map(Vertex.class::cast); | ||
496 | } | ||
497 | |||
498 | /** | ||
499 | * Retrieve the set of values that occur in matches for child. | ||
500 | * @return the Set of all values or empty set if there are no matches | ||
501 | * | ||
502 | */ | ||
503 | public Set<Vertex> getAllValuesOfchild() { | ||
504 | return rawStreamAllValuesOfchild(emptyArray()).collect(Collectors.toSet()); | ||
505 | } | ||
506 | |||
507 | /** | ||
508 | * Retrieve the set of values that occur in matches for child. | ||
509 | * @return the Set of all values or empty set if there are no matches | ||
510 | * | ||
511 | */ | ||
512 | public Stream<Vertex> streamAllValuesOfchild() { | ||
513 | return rawStreamAllValuesOfchild(emptyArray()); | ||
514 | } | ||
515 | |||
516 | /** | ||
517 | * Retrieve the set of values that occur in matches for child. | ||
518 | * </p> | ||
519 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
520 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
521 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
522 | * | ||
523 | * @return the Stream of all values or empty set if there are no matches | ||
524 | * | ||
525 | */ | ||
526 | public Stream<Vertex> streamAllValuesOfchild(final Child.Match partialMatch) { | ||
527 | return rawStreamAllValuesOfchild(partialMatch.toArray()); | ||
528 | } | ||
529 | |||
530 | /** | ||
531 | * Retrieve the set of values that occur in matches for child. | ||
532 | * </p> | ||
533 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
534 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
535 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
536 | * | ||
537 | * @return the Stream of all values or empty set if there are no matches | ||
538 | * | ||
539 | */ | ||
540 | public Stream<Vertex> streamAllValuesOfchild(final CompositeElement pParent) { | ||
541 | return rawStreamAllValuesOfchild(new Object[]{pParent, null}); | ||
542 | } | ||
543 | |||
544 | /** | ||
545 | * Retrieve the set of values that occur in matches for child. | ||
546 | * @return the Set of all values or empty set if there are no matches | ||
547 | * | ||
548 | */ | ||
549 | public Set<Vertex> getAllValuesOfchild(final Child.Match partialMatch) { | ||
550 | return rawStreamAllValuesOfchild(partialMatch.toArray()).collect(Collectors.toSet()); | ||
551 | } | ||
552 | |||
553 | /** | ||
554 | * Retrieve the set of values that occur in matches for child. | ||
555 | * @return the Set of all values or empty set if there are no matches | ||
556 | * | ||
557 | */ | ||
558 | public Set<Vertex> getAllValuesOfchild(final CompositeElement pParent) { | ||
559 | return rawStreamAllValuesOfchild(new Object[]{pParent, null}).collect(Collectors.toSet()); | ||
560 | } | ||
561 | |||
562 | @Override | ||
563 | protected Child.Match tupleToMatch(final Tuple t) { | ||
564 | try { | ||
565 | return Child.Match.newMatch((CompositeElement) t.get(POSITION_PARENT), (Vertex) t.get(POSITION_CHILD)); | ||
566 | } catch(ClassCastException e) { | ||
567 | LOGGER.error("Element(s) in tuple not properly typed!",e); | ||
568 | return null; | ||
569 | } | ||
570 | } | ||
571 | |||
572 | @Override | ||
573 | protected Child.Match arrayToMatch(final Object[] match) { | ||
574 | try { | ||
575 | return Child.Match.newMatch((CompositeElement) match[POSITION_PARENT], (Vertex) match[POSITION_CHILD]); | ||
576 | } catch(ClassCastException e) { | ||
577 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
578 | return null; | ||
579 | } | ||
580 | } | ||
581 | |||
582 | @Override | ||
583 | protected Child.Match arrayToMatchMutable(final Object[] match) { | ||
584 | try { | ||
585 | return Child.Match.newMutableMatch((CompositeElement) match[POSITION_PARENT], (Vertex) match[POSITION_CHILD]); | ||
586 | } catch(ClassCastException e) { | ||
587 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
588 | return null; | ||
589 | } | ||
590 | } | ||
591 | |||
592 | /** | ||
593 | * @return the singleton instance of the query specification of this pattern | ||
594 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
595 | * | ||
596 | */ | ||
597 | public static IQuerySpecification<Child.Matcher> querySpecification() { | ||
598 | return Child.instance(); | ||
599 | } | ||
600 | } | ||
601 | |||
602 | private Child() { | ||
603 | super(GeneratedPQuery.INSTANCE); | ||
604 | } | ||
605 | |||
606 | /** | ||
607 | * @return the singleton instance of the query specification | ||
608 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
609 | * | ||
610 | */ | ||
611 | public static Child instance() { | ||
612 | try{ | ||
613 | return LazyHolder.INSTANCE; | ||
614 | } catch (ExceptionInInitializerError err) { | ||
615 | throw processInitializerError(err); | ||
616 | } | ||
617 | } | ||
618 | |||
619 | @Override | ||
620 | protected Child.Matcher instantiate(final ViatraQueryEngine engine) { | ||
621 | return Child.Matcher.on(engine); | ||
622 | } | ||
623 | |||
624 | @Override | ||
625 | public Child.Matcher instantiate() { | ||
626 | return Child.Matcher.create(); | ||
627 | } | ||
628 | |||
629 | @Override | ||
630 | public Child.Match newEmptyMatch() { | ||
631 | return Child.Match.newEmptyMatch(); | ||
632 | } | ||
633 | |||
634 | @Override | ||
635 | public Child.Match newMatch(final Object... parameters) { | ||
636 | return Child.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.CompositeElement) parameters[0], (ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex) parameters[1]); | ||
637 | } | ||
638 | |||
639 | /** | ||
640 | * Inner class allowing the singleton instance of {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.Child (visibility: PUBLIC, simpleName: Child, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.Child, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created | ||
641 | * <b>not</b> at the class load time of the outer class, | ||
642 | * but rather at the first call to {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.Child (visibility: PUBLIC, simpleName: Child, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.Child, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. | ||
643 | * | ||
644 | * <p> This workaround is required e.g. to support recursion. | ||
645 | * | ||
646 | */ | ||
647 | private static class LazyHolder { | ||
648 | private final static Child INSTANCE = new Child(); | ||
649 | |||
650 | /** | ||
651 | * Statically initializes the query specification <b>after</b> the field {@link #INSTANCE} is assigned. | ||
652 | * This initialization order is required to support indirect recursion. | ||
653 | * | ||
654 | * <p> The static initializer is defined using a helper field to work around limitations of the code generator. | ||
655 | * | ||
656 | */ | ||
657 | private final static Object STATIC_INITIALIZER = ensureInitialized(); | ||
658 | |||
659 | public static Object ensureInitialized() { | ||
660 | INSTANCE.ensureInitializedInternal(); | ||
661 | return null; | ||
662 | } | ||
663 | } | ||
664 | |||
665 | private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { | ||
666 | private final static Child.GeneratedPQuery INSTANCE = new GeneratedPQuery(); | ||
667 | |||
668 | private final PParameter parameter_parent = new PParameter("parent", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.CompositeElement", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "CompositeElement")), PParameterDirection.INOUT); | ||
669 | |||
670 | private final PParameter parameter_child = new PParameter("child", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Vertex")), PParameterDirection.INOUT); | ||
671 | |||
672 | private final List<PParameter> parameters = Arrays.asList(parameter_parent, parameter_child); | ||
673 | |||
674 | private GeneratedPQuery() { | ||
675 | super(PVisibility.PUBLIC); | ||
676 | } | ||
677 | |||
678 | @Override | ||
679 | public String getFullyQualifiedName() { | ||
680 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.child"; | ||
681 | } | ||
682 | |||
683 | @Override | ||
684 | public List<String> getParameterNames() { | ||
685 | return Arrays.asList("parent","child"); | ||
686 | } | ||
687 | |||
688 | @Override | ||
689 | public List<PParameter> getParameters() { | ||
690 | return parameters; | ||
691 | } | ||
692 | |||
693 | @Override | ||
694 | public Set<PBody> doGetContainedBodies() { | ||
695 | setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); | ||
696 | Set<PBody> bodies = new LinkedHashSet<>(); | ||
697 | { | ||
698 | PBody body = new PBody(this); | ||
699 | PVariable var_parent = body.getOrCreateVariableByName("parent"); | ||
700 | PVariable var_child = body.getOrCreateVariableByName("child"); | ||
701 | new TypeConstraint(body, Tuples.flatTupleOf(var_parent), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "CompositeElement"))); | ||
702 | new TypeConstraint(body, Tuples.flatTupleOf(var_child), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); | ||
703 | body.setSymbolicParameters(Arrays.<ExportedParameter>asList( | ||
704 | new ExportedParameter(body, var_parent, parameter_parent), | ||
705 | new ExportedParameter(body, var_child, parameter_child) | ||
706 | )); | ||
707 | // CompositeElement.regions.vertices(parent, child) | ||
708 | new TypeConstraint(body, Tuples.flatTupleOf(var_parent), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "CompositeElement"))); | ||
709 | PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); | ||
710 | new TypeConstraint(body, Tuples.flatTupleOf(var_parent, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "CompositeElement", "regions"))); | ||
711 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Region"))); | ||
712 | PVariable var__virtual_1_ = body.getOrCreateVariableByName(".virtual{1}"); | ||
713 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_, var__virtual_1_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Region", "vertices"))); | ||
714 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_1_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); | ||
715 | new Equality(body, var__virtual_1_, var_child); | ||
716 | bodies.add(body); | ||
717 | } | ||
718 | return bodies; | ||
719 | } | ||
720 | } | ||
721 | } | ||
diff --git a/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/ChoiceHasNoIncoming.java b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/ChoiceHasNoIncoming.java new file mode 100644 index 00000000..8e62ee9d --- /dev/null +++ b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/ChoiceHasNoIncoming.java | |||
@@ -0,0 +1,551 @@ | |||
1 | /** | ||
2 | * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql | ||
3 | */ | ||
4 | package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; | ||
5 | |||
6 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Choice; | ||
7 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.Transition; | ||
8 | import java.util.Arrays; | ||
9 | import java.util.Collection; | ||
10 | import java.util.LinkedHashSet; | ||
11 | import java.util.List; | ||
12 | import java.util.Objects; | ||
13 | import java.util.Optional; | ||
14 | import java.util.Set; | ||
15 | import java.util.function.Consumer; | ||
16 | import java.util.stream.Collectors; | ||
17 | import java.util.stream.Stream; | ||
18 | import org.apache.log4j.Logger; | ||
19 | import org.eclipse.emf.ecore.EClass; | ||
20 | import org.eclipse.viatra.query.runtime.api.IPatternMatch; | ||
21 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification; | ||
22 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; | ||
23 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; | ||
24 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; | ||
25 | import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; | ||
26 | import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; | ||
27 | import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; | ||
28 | import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; | ||
29 | import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; | ||
30 | import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; | ||
31 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; | ||
32 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; | ||
33 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; | ||
34 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.NegativePatternCall; | ||
35 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; | ||
36 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; | ||
37 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; | ||
38 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; | ||
39 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; | ||
40 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | ||
41 | import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; | ||
42 | |||
43 | /** | ||
44 | * A pattern-specific query specification that can instantiate Matcher in a type-safe way. | ||
45 | * | ||
46 | * <p>Original source: | ||
47 | * <code><pre> | ||
48 | * {@literal @}Constraint(severity="error", message="error", key = {c}) | ||
49 | * pattern choiceHasNoIncoming(c: Choice) { | ||
50 | * neg find transition(_, _, c); | ||
51 | * } | ||
52 | * </pre></code> | ||
53 | * | ||
54 | * @see Matcher | ||
55 | * @see Match | ||
56 | * | ||
57 | */ | ||
58 | @SuppressWarnings("all") | ||
59 | public final class ChoiceHasNoIncoming extends BaseGeneratedEMFQuerySpecification<ChoiceHasNoIncoming.Matcher> { | ||
60 | /** | ||
61 | * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.choiceHasNoIncoming pattern, | ||
62 | * to be used in conjunction with {@link Matcher}. | ||
63 | * | ||
64 | * <p>Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. | ||
65 | * Each instance is a (possibly partial) substitution of pattern parameters, | ||
66 | * usable to represent a match of the pattern in the result of a query, | ||
67 | * or to specify the bound (fixed) input parameters when issuing a query. | ||
68 | * | ||
69 | * @see Matcher | ||
70 | * | ||
71 | */ | ||
72 | public static abstract class Match extends BasePatternMatch { | ||
73 | private Choice fC; | ||
74 | |||
75 | private static List<String> parameterNames = makeImmutableList("c"); | ||
76 | |||
77 | private Match(final Choice pC) { | ||
78 | this.fC = pC; | ||
79 | } | ||
80 | |||
81 | @Override | ||
82 | public Object get(final String parameterName) { | ||
83 | if ("c".equals(parameterName)) return this.fC; | ||
84 | return null; | ||
85 | } | ||
86 | |||
87 | public Choice getC() { | ||
88 | return this.fC; | ||
89 | } | ||
90 | |||
91 | @Override | ||
92 | public boolean set(final String parameterName, final Object newValue) { | ||
93 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
94 | if ("c".equals(parameterName) ) { | ||
95 | this.fC = (Choice) newValue; | ||
96 | return true; | ||
97 | } | ||
98 | return false; | ||
99 | } | ||
100 | |||
101 | public void setC(final Choice pC) { | ||
102 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
103 | this.fC = pC; | ||
104 | } | ||
105 | |||
106 | @Override | ||
107 | public String patternName() { | ||
108 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.choiceHasNoIncoming"; | ||
109 | } | ||
110 | |||
111 | @Override | ||
112 | public List<String> parameterNames() { | ||
113 | return ChoiceHasNoIncoming.Match.parameterNames; | ||
114 | } | ||
115 | |||
116 | @Override | ||
117 | public Object[] toArray() { | ||
118 | return new Object[]{fC}; | ||
119 | } | ||
120 | |||
121 | @Override | ||
122 | public ChoiceHasNoIncoming.Match toImmutable() { | ||
123 | return isMutable() ? newMatch(fC) : this; | ||
124 | } | ||
125 | |||
126 | @Override | ||
127 | public String prettyPrint() { | ||
128 | StringBuilder result = new StringBuilder(); | ||
129 | result.append("\"c\"=" + prettyPrintValue(fC)); | ||
130 | return result.toString(); | ||
131 | } | ||
132 | |||
133 | @Override | ||
134 | public int hashCode() { | ||
135 | return Objects.hash(fC); | ||
136 | } | ||
137 | |||
138 | @Override | ||
139 | public boolean equals(final Object obj) { | ||
140 | if (this == obj) | ||
141 | return true; | ||
142 | if (obj == null) { | ||
143 | return false; | ||
144 | } | ||
145 | if ((obj instanceof ChoiceHasNoIncoming.Match)) { | ||
146 | ChoiceHasNoIncoming.Match other = (ChoiceHasNoIncoming.Match) obj; | ||
147 | return Objects.equals(fC, other.fC); | ||
148 | } else { | ||
149 | // this should be infrequent | ||
150 | if (!(obj instanceof IPatternMatch)) { | ||
151 | return false; | ||
152 | } | ||
153 | IPatternMatch otherSig = (IPatternMatch) obj; | ||
154 | return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); | ||
155 | } | ||
156 | } | ||
157 | |||
158 | @Override | ||
159 | public ChoiceHasNoIncoming specification() { | ||
160 | return ChoiceHasNoIncoming.instance(); | ||
161 | } | ||
162 | |||
163 | /** | ||
164 | * Returns an empty, mutable match. | ||
165 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
166 | * | ||
167 | * @return the empty match. | ||
168 | * | ||
169 | */ | ||
170 | public static ChoiceHasNoIncoming.Match newEmptyMatch() { | ||
171 | return new Mutable(null); | ||
172 | } | ||
173 | |||
174 | /** | ||
175 | * Returns a mutable (partial) match. | ||
176 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
177 | * | ||
178 | * @param pC the fixed value of pattern parameter c, or null if not bound. | ||
179 | * @return the new, mutable (partial) match object. | ||
180 | * | ||
181 | */ | ||
182 | public static ChoiceHasNoIncoming.Match newMutableMatch(final Choice pC) { | ||
183 | return new Mutable(pC); | ||
184 | } | ||
185 | |||
186 | /** | ||
187 | * Returns a new (partial) match. | ||
188 | * This can be used e.g. to call the matcher with a partial match. | ||
189 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
190 | * @param pC the fixed value of pattern parameter c, or null if not bound. | ||
191 | * @return the (partial) match object. | ||
192 | * | ||
193 | */ | ||
194 | public static ChoiceHasNoIncoming.Match newMatch(final Choice pC) { | ||
195 | return new Immutable(pC); | ||
196 | } | ||
197 | |||
198 | private static final class Mutable extends ChoiceHasNoIncoming.Match { | ||
199 | Mutable(final Choice pC) { | ||
200 | super(pC); | ||
201 | } | ||
202 | |||
203 | @Override | ||
204 | public boolean isMutable() { | ||
205 | return true; | ||
206 | } | ||
207 | } | ||
208 | |||
209 | private static final class Immutable extends ChoiceHasNoIncoming.Match { | ||
210 | Immutable(final Choice pC) { | ||
211 | super(pC); | ||
212 | } | ||
213 | |||
214 | @Override | ||
215 | public boolean isMutable() { | ||
216 | return false; | ||
217 | } | ||
218 | } | ||
219 | } | ||
220 | |||
221 | /** | ||
222 | * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.choiceHasNoIncoming pattern, | ||
223 | * providing pattern-specific query methods. | ||
224 | * | ||
225 | * <p>Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, | ||
226 | * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. | ||
227 | * | ||
228 | * <p>Matches of the pattern will be represented as {@link Match}. | ||
229 | * | ||
230 | * <p>Original source: | ||
231 | * <code><pre> | ||
232 | * {@literal @}Constraint(severity="error", message="error", key = {c}) | ||
233 | * pattern choiceHasNoIncoming(c: Choice) { | ||
234 | * neg find transition(_, _, c); | ||
235 | * } | ||
236 | * </pre></code> | ||
237 | * | ||
238 | * @see Match | ||
239 | * @see ChoiceHasNoIncoming | ||
240 | * | ||
241 | */ | ||
242 | public static class Matcher extends BaseMatcher<ChoiceHasNoIncoming.Match> { | ||
243 | /** | ||
244 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
245 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
246 | * | ||
247 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
248 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
249 | * | ||
250 | */ | ||
251 | public static ChoiceHasNoIncoming.Matcher on(final ViatraQueryEngine engine) { | ||
252 | // check if matcher already exists | ||
253 | Matcher matcher = engine.getExistingMatcher(querySpecification()); | ||
254 | if (matcher == null) { | ||
255 | matcher = (Matcher)engine.getMatcher(querySpecification()); | ||
256 | } | ||
257 | return matcher; | ||
258 | } | ||
259 | |||
260 | /** | ||
261 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
262 | * @return an initialized matcher | ||
263 | * @noreference This method is for internal matcher initialization by the framework, do not call it manually. | ||
264 | * | ||
265 | */ | ||
266 | public static ChoiceHasNoIncoming.Matcher create() { | ||
267 | return new Matcher(); | ||
268 | } | ||
269 | |||
270 | private final static int POSITION_C = 0; | ||
271 | |||
272 | private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(ChoiceHasNoIncoming.Matcher.class); | ||
273 | |||
274 | /** | ||
275 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
276 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
277 | * | ||
278 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
279 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
280 | * | ||
281 | */ | ||
282 | private Matcher() { | ||
283 | super(querySpecification()); | ||
284 | } | ||
285 | |||
286 | /** | ||
287 | * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. | ||
288 | * @param pC the fixed value of pattern parameter c, or null if not bound. | ||
289 | * @return matches represented as a Match object. | ||
290 | * | ||
291 | */ | ||
292 | public Collection<ChoiceHasNoIncoming.Match> getAllMatches(final Choice pC) { | ||
293 | return rawStreamAllMatches(new Object[]{pC}).collect(Collectors.toSet()); | ||
294 | } | ||
295 | |||
296 | /** | ||
297 | * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. | ||
298 | * </p> | ||
299 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
300 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
301 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
302 | * @param pC the fixed value of pattern parameter c, or null if not bound. | ||
303 | * @return a stream of matches represented as a Match object. | ||
304 | * | ||
305 | */ | ||
306 | public Stream<ChoiceHasNoIncoming.Match> streamAllMatches(final Choice pC) { | ||
307 | return rawStreamAllMatches(new Object[]{pC}); | ||
308 | } | ||
309 | |||
310 | /** | ||
311 | * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
312 | * Neither determinism nor randomness of selection is guaranteed. | ||
313 | * @param pC the fixed value of pattern parameter c, or null if not bound. | ||
314 | * @return a match represented as a Match object, or null if no match is found. | ||
315 | * | ||
316 | */ | ||
317 | public Optional<ChoiceHasNoIncoming.Match> getOneArbitraryMatch(final Choice pC) { | ||
318 | return rawGetOneArbitraryMatch(new Object[]{pC}); | ||
319 | } | ||
320 | |||
321 | /** | ||
322 | * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, | ||
323 | * under any possible substitution of the unspecified parameters (if any). | ||
324 | * @param pC the fixed value of pattern parameter c, or null if not bound. | ||
325 | * @return true if the input is a valid (partial) match of the pattern. | ||
326 | * | ||
327 | */ | ||
328 | public boolean hasMatch(final Choice pC) { | ||
329 | return rawHasMatch(new Object[]{pC}); | ||
330 | } | ||
331 | |||
332 | /** | ||
333 | * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. | ||
334 | * @param pC the fixed value of pattern parameter c, or null if not bound. | ||
335 | * @return the number of pattern matches found. | ||
336 | * | ||
337 | */ | ||
338 | public int countMatches(final Choice pC) { | ||
339 | return rawCountMatches(new Object[]{pC}); | ||
340 | } | ||
341 | |||
342 | /** | ||
343 | * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
344 | * Neither determinism nor randomness of selection is guaranteed. | ||
345 | * @param pC the fixed value of pattern parameter c, or null if not bound. | ||
346 | * @param processor the action that will process the selected match. | ||
347 | * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked | ||
348 | * | ||
349 | */ | ||
350 | public boolean forOneArbitraryMatch(final Choice pC, final Consumer<? super ChoiceHasNoIncoming.Match> processor) { | ||
351 | return rawForOneArbitraryMatch(new Object[]{pC}, processor); | ||
352 | } | ||
353 | |||
354 | /** | ||
355 | * Returns a new (partial) match. | ||
356 | * This can be used e.g. to call the matcher with a partial match. | ||
357 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
358 | * @param pC the fixed value of pattern parameter c, or null if not bound. | ||
359 | * @return the (partial) match object. | ||
360 | * | ||
361 | */ | ||
362 | public ChoiceHasNoIncoming.Match newMatch(final Choice pC) { | ||
363 | return ChoiceHasNoIncoming.Match.newMatch(pC); | ||
364 | } | ||
365 | |||
366 | /** | ||
367 | * Retrieve the set of values that occur in matches for c. | ||
368 | * @return the Set of all values or empty set if there are no matches | ||
369 | * | ||
370 | */ | ||
371 | protected Stream<Choice> rawStreamAllValuesOfc(final Object[] parameters) { | ||
372 | return rawStreamAllValues(POSITION_C, parameters).map(Choice.class::cast); | ||
373 | } | ||
374 | |||
375 | /** | ||
376 | * Retrieve the set of values that occur in matches for c. | ||
377 | * @return the Set of all values or empty set if there are no matches | ||
378 | * | ||
379 | */ | ||
380 | public Set<Choice> getAllValuesOfc() { | ||
381 | return rawStreamAllValuesOfc(emptyArray()).collect(Collectors.toSet()); | ||
382 | } | ||
383 | |||
384 | /** | ||
385 | * Retrieve the set of values that occur in matches for c. | ||
386 | * @return the Set of all values or empty set if there are no matches | ||
387 | * | ||
388 | */ | ||
389 | public Stream<Choice> streamAllValuesOfc() { | ||
390 | return rawStreamAllValuesOfc(emptyArray()); | ||
391 | } | ||
392 | |||
393 | @Override | ||
394 | protected ChoiceHasNoIncoming.Match tupleToMatch(final Tuple t) { | ||
395 | try { | ||
396 | return ChoiceHasNoIncoming.Match.newMatch((Choice) t.get(POSITION_C)); | ||
397 | } catch(ClassCastException e) { | ||
398 | LOGGER.error("Element(s) in tuple not properly typed!",e); | ||
399 | return null; | ||
400 | } | ||
401 | } | ||
402 | |||
403 | @Override | ||
404 | protected ChoiceHasNoIncoming.Match arrayToMatch(final Object[] match) { | ||
405 | try { | ||
406 | return ChoiceHasNoIncoming.Match.newMatch((Choice) match[POSITION_C]); | ||
407 | } catch(ClassCastException e) { | ||
408 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
409 | return null; | ||
410 | } | ||
411 | } | ||
412 | |||
413 | @Override | ||
414 | protected ChoiceHasNoIncoming.Match arrayToMatchMutable(final Object[] match) { | ||
415 | try { | ||
416 | return ChoiceHasNoIncoming.Match.newMutableMatch((Choice) match[POSITION_C]); | ||
417 | } catch(ClassCastException e) { | ||
418 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
419 | return null; | ||
420 | } | ||
421 | } | ||
422 | |||
423 | /** | ||
424 | * @return the singleton instance of the query specification of this pattern | ||
425 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
426 | * | ||
427 | */ | ||
428 | public static IQuerySpecification<ChoiceHasNoIncoming.Matcher> querySpecification() { | ||
429 | return ChoiceHasNoIncoming.instance(); | ||
430 | } | ||
431 | } | ||
432 | |||
433 | private ChoiceHasNoIncoming() { | ||
434 | super(GeneratedPQuery.INSTANCE); | ||
435 | } | ||
436 | |||
437 | /** | ||
438 | * @return the singleton instance of the query specification | ||
439 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
440 | * | ||
441 | */ | ||
442 | public static ChoiceHasNoIncoming instance() { | ||
443 | try{ | ||
444 | return LazyHolder.INSTANCE; | ||
445 | } catch (ExceptionInInitializerError err) { | ||
446 | throw processInitializerError(err); | ||
447 | } | ||
448 | } | ||
449 | |||
450 | @Override | ||
451 | protected ChoiceHasNoIncoming.Matcher instantiate(final ViatraQueryEngine engine) { | ||
452 | return ChoiceHasNoIncoming.Matcher.on(engine); | ||
453 | } | ||
454 | |||
455 | @Override | ||
456 | public ChoiceHasNoIncoming.Matcher instantiate() { | ||
457 | return ChoiceHasNoIncoming.Matcher.create(); | ||
458 | } | ||
459 | |||
460 | @Override | ||
461 | public ChoiceHasNoIncoming.Match newEmptyMatch() { | ||
462 | return ChoiceHasNoIncoming.Match.newEmptyMatch(); | ||
463 | } | ||
464 | |||
465 | @Override | ||
466 | public ChoiceHasNoIncoming.Match newMatch(final Object... parameters) { | ||
467 | return ChoiceHasNoIncoming.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Choice) parameters[0]); | ||
468 | } | ||
469 | |||
470 | /** | ||
471 | * Inner class allowing the singleton instance of {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.ChoiceHasNoIncoming (visibility: PUBLIC, simpleName: ChoiceHasNoIncoming, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.ChoiceHasNoIncoming, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created | ||
472 | * <b>not</b> at the class load time of the outer class, | ||
473 | * but rather at the first call to {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.ChoiceHasNoIncoming (visibility: PUBLIC, simpleName: ChoiceHasNoIncoming, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.ChoiceHasNoIncoming, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. | ||
474 | * | ||
475 | * <p> This workaround is required e.g. to support recursion. | ||
476 | * | ||
477 | */ | ||
478 | private static class LazyHolder { | ||
479 | private final static ChoiceHasNoIncoming INSTANCE = new ChoiceHasNoIncoming(); | ||
480 | |||
481 | /** | ||
482 | * Statically initializes the query specification <b>after</b> the field {@link #INSTANCE} is assigned. | ||
483 | * This initialization order is required to support indirect recursion. | ||
484 | * | ||
485 | * <p> The static initializer is defined using a helper field to work around limitations of the code generator. | ||
486 | * | ||
487 | */ | ||
488 | private final static Object STATIC_INITIALIZER = ensureInitialized(); | ||
489 | |||
490 | public static Object ensureInitialized() { | ||
491 | INSTANCE.ensureInitializedInternal(); | ||
492 | return null; | ||
493 | } | ||
494 | } | ||
495 | |||
496 | private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { | ||
497 | private final static ChoiceHasNoIncoming.GeneratedPQuery INSTANCE = new GeneratedPQuery(); | ||
498 | |||
499 | private final PParameter parameter_c = new PParameter("c", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Choice", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Choice")), PParameterDirection.INOUT); | ||
500 | |||
501 | private final List<PParameter> parameters = Arrays.asList(parameter_c); | ||
502 | |||
503 | private GeneratedPQuery() { | ||
504 | super(PVisibility.PUBLIC); | ||
505 | } | ||
506 | |||
507 | @Override | ||
508 | public String getFullyQualifiedName() { | ||
509 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.choiceHasNoIncoming"; | ||
510 | } | ||
511 | |||
512 | @Override | ||
513 | public List<String> getParameterNames() { | ||
514 | return Arrays.asList("c"); | ||
515 | } | ||
516 | |||
517 | @Override | ||
518 | public List<PParameter> getParameters() { | ||
519 | return parameters; | ||
520 | } | ||
521 | |||
522 | @Override | ||
523 | public Set<PBody> doGetContainedBodies() { | ||
524 | setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); | ||
525 | Set<PBody> bodies = new LinkedHashSet<>(); | ||
526 | { | ||
527 | PBody body = new PBody(this); | ||
528 | PVariable var_c = body.getOrCreateVariableByName("c"); | ||
529 | PVariable var___0_ = body.getOrCreateVariableByName("_<0>"); | ||
530 | PVariable var___1_ = body.getOrCreateVariableByName("_<1>"); | ||
531 | new TypeConstraint(body, Tuples.flatTupleOf(var_c), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Choice"))); | ||
532 | body.setSymbolicParameters(Arrays.<ExportedParameter>asList( | ||
533 | new ExportedParameter(body, var_c, parameter_c) | ||
534 | )); | ||
535 | // neg find transition(_, _, c) | ||
536 | new NegativePatternCall(body, Tuples.flatTupleOf(var___0_, var___1_, var_c), Transition.instance().getInternalQueryRepresentation()); | ||
537 | bodies.add(body); | ||
538 | } | ||
539 | { | ||
540 | PAnnotation annotation = new PAnnotation("Constraint"); | ||
541 | annotation.addAttribute("severity", "error"); | ||
542 | annotation.addAttribute("message", "error"); | ||
543 | annotation.addAttribute("key", Arrays.asList(new Object[] { | ||
544 | new ParameterReference("c") | ||
545 | })); | ||
546 | addAnnotation(annotation); | ||
547 | } | ||
548 | return bodies; | ||
549 | } | ||
550 | } | ||
551 | } | ||
diff --git a/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/ChoiceHasNoOutgoing.java b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/ChoiceHasNoOutgoing.java new file mode 100644 index 00000000..1c20a03b --- /dev/null +++ b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/ChoiceHasNoOutgoing.java | |||
@@ -0,0 +1,559 @@ | |||
1 | /** | ||
2 | * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql | ||
3 | */ | ||
4 | package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; | ||
5 | |||
6 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Choice; | ||
7 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.Transition; | ||
8 | import java.util.Arrays; | ||
9 | import java.util.Collection; | ||
10 | import java.util.LinkedHashSet; | ||
11 | import java.util.List; | ||
12 | import java.util.Objects; | ||
13 | import java.util.Optional; | ||
14 | import java.util.Set; | ||
15 | import java.util.function.Consumer; | ||
16 | import java.util.stream.Collectors; | ||
17 | import java.util.stream.Stream; | ||
18 | import org.apache.log4j.Logger; | ||
19 | import org.eclipse.emf.ecore.EClass; | ||
20 | import org.eclipse.viatra.query.runtime.api.IPatternMatch; | ||
21 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification; | ||
22 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; | ||
23 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; | ||
24 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; | ||
25 | import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; | ||
26 | import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; | ||
27 | import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; | ||
28 | import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; | ||
29 | import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; | ||
30 | import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; | ||
31 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; | ||
32 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; | ||
33 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; | ||
34 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.NegativePatternCall; | ||
35 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; | ||
36 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; | ||
37 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; | ||
38 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; | ||
39 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; | ||
40 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | ||
41 | import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; | ||
42 | |||
43 | /** | ||
44 | * A pattern-specific query specification that can instantiate Matcher in a type-safe way. | ||
45 | * | ||
46 | * <p>Original source: | ||
47 | * <code><pre> | ||
48 | * ///////// | ||
49 | * // Choice | ||
50 | * ///////// | ||
51 | * | ||
52 | * {@literal @}Constraint(severity="error", message="error", key = {c}) | ||
53 | * pattern choiceHasNoOutgoing(c : Choice) { | ||
54 | * neg find transition(_, c, _); | ||
55 | * } | ||
56 | * </pre></code> | ||
57 | * | ||
58 | * @see Matcher | ||
59 | * @see Match | ||
60 | * | ||
61 | */ | ||
62 | @SuppressWarnings("all") | ||
63 | public final class ChoiceHasNoOutgoing extends BaseGeneratedEMFQuerySpecification<ChoiceHasNoOutgoing.Matcher> { | ||
64 | /** | ||
65 | * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.choiceHasNoOutgoing pattern, | ||
66 | * to be used in conjunction with {@link Matcher}. | ||
67 | * | ||
68 | * <p>Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. | ||
69 | * Each instance is a (possibly partial) substitution of pattern parameters, | ||
70 | * usable to represent a match of the pattern in the result of a query, | ||
71 | * or to specify the bound (fixed) input parameters when issuing a query. | ||
72 | * | ||
73 | * @see Matcher | ||
74 | * | ||
75 | */ | ||
76 | public static abstract class Match extends BasePatternMatch { | ||
77 | private Choice fC; | ||
78 | |||
79 | private static List<String> parameterNames = makeImmutableList("c"); | ||
80 | |||
81 | private Match(final Choice pC) { | ||
82 | this.fC = pC; | ||
83 | } | ||
84 | |||
85 | @Override | ||
86 | public Object get(final String parameterName) { | ||
87 | if ("c".equals(parameterName)) return this.fC; | ||
88 | return null; | ||
89 | } | ||
90 | |||
91 | public Choice getC() { | ||
92 | return this.fC; | ||
93 | } | ||
94 | |||
95 | @Override | ||
96 | public boolean set(final String parameterName, final Object newValue) { | ||
97 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
98 | if ("c".equals(parameterName) ) { | ||
99 | this.fC = (Choice) newValue; | ||
100 | return true; | ||
101 | } | ||
102 | return false; | ||
103 | } | ||
104 | |||
105 | public void setC(final Choice pC) { | ||
106 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
107 | this.fC = pC; | ||
108 | } | ||
109 | |||
110 | @Override | ||
111 | public String patternName() { | ||
112 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.choiceHasNoOutgoing"; | ||
113 | } | ||
114 | |||
115 | @Override | ||
116 | public List<String> parameterNames() { | ||
117 | return ChoiceHasNoOutgoing.Match.parameterNames; | ||
118 | } | ||
119 | |||
120 | @Override | ||
121 | public Object[] toArray() { | ||
122 | return new Object[]{fC}; | ||
123 | } | ||
124 | |||
125 | @Override | ||
126 | public ChoiceHasNoOutgoing.Match toImmutable() { | ||
127 | return isMutable() ? newMatch(fC) : this; | ||
128 | } | ||
129 | |||
130 | @Override | ||
131 | public String prettyPrint() { | ||
132 | StringBuilder result = new StringBuilder(); | ||
133 | result.append("\"c\"=" + prettyPrintValue(fC)); | ||
134 | return result.toString(); | ||
135 | } | ||
136 | |||
137 | @Override | ||
138 | public int hashCode() { | ||
139 | return Objects.hash(fC); | ||
140 | } | ||
141 | |||
142 | @Override | ||
143 | public boolean equals(final Object obj) { | ||
144 | if (this == obj) | ||
145 | return true; | ||
146 | if (obj == null) { | ||
147 | return false; | ||
148 | } | ||
149 | if ((obj instanceof ChoiceHasNoOutgoing.Match)) { | ||
150 | ChoiceHasNoOutgoing.Match other = (ChoiceHasNoOutgoing.Match) obj; | ||
151 | return Objects.equals(fC, other.fC); | ||
152 | } else { | ||
153 | // this should be infrequent | ||
154 | if (!(obj instanceof IPatternMatch)) { | ||
155 | return false; | ||
156 | } | ||
157 | IPatternMatch otherSig = (IPatternMatch) obj; | ||
158 | return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); | ||
159 | } | ||
160 | } | ||
161 | |||
162 | @Override | ||
163 | public ChoiceHasNoOutgoing specification() { | ||
164 | return ChoiceHasNoOutgoing.instance(); | ||
165 | } | ||
166 | |||
167 | /** | ||
168 | * Returns an empty, mutable match. | ||
169 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
170 | * | ||
171 | * @return the empty match. | ||
172 | * | ||
173 | */ | ||
174 | public static ChoiceHasNoOutgoing.Match newEmptyMatch() { | ||
175 | return new Mutable(null); | ||
176 | } | ||
177 | |||
178 | /** | ||
179 | * Returns a mutable (partial) match. | ||
180 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
181 | * | ||
182 | * @param pC the fixed value of pattern parameter c, or null if not bound. | ||
183 | * @return the new, mutable (partial) match object. | ||
184 | * | ||
185 | */ | ||
186 | public static ChoiceHasNoOutgoing.Match newMutableMatch(final Choice pC) { | ||
187 | return new Mutable(pC); | ||
188 | } | ||
189 | |||
190 | /** | ||
191 | * Returns a new (partial) match. | ||
192 | * This can be used e.g. to call the matcher with a partial match. | ||
193 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
194 | * @param pC the fixed value of pattern parameter c, or null if not bound. | ||
195 | * @return the (partial) match object. | ||
196 | * | ||
197 | */ | ||
198 | public static ChoiceHasNoOutgoing.Match newMatch(final Choice pC) { | ||
199 | return new Immutable(pC); | ||
200 | } | ||
201 | |||
202 | private static final class Mutable extends ChoiceHasNoOutgoing.Match { | ||
203 | Mutable(final Choice pC) { | ||
204 | super(pC); | ||
205 | } | ||
206 | |||
207 | @Override | ||
208 | public boolean isMutable() { | ||
209 | return true; | ||
210 | } | ||
211 | } | ||
212 | |||
213 | private static final class Immutable extends ChoiceHasNoOutgoing.Match { | ||
214 | Immutable(final Choice pC) { | ||
215 | super(pC); | ||
216 | } | ||
217 | |||
218 | @Override | ||
219 | public boolean isMutable() { | ||
220 | return false; | ||
221 | } | ||
222 | } | ||
223 | } | ||
224 | |||
225 | /** | ||
226 | * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.choiceHasNoOutgoing pattern, | ||
227 | * providing pattern-specific query methods. | ||
228 | * | ||
229 | * <p>Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, | ||
230 | * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. | ||
231 | * | ||
232 | * <p>Matches of the pattern will be represented as {@link Match}. | ||
233 | * | ||
234 | * <p>Original source: | ||
235 | * <code><pre> | ||
236 | * ///////// | ||
237 | * // Choice | ||
238 | * ///////// | ||
239 | * | ||
240 | * {@literal @}Constraint(severity="error", message="error", key = {c}) | ||
241 | * pattern choiceHasNoOutgoing(c : Choice) { | ||
242 | * neg find transition(_, c, _); | ||
243 | * } | ||
244 | * </pre></code> | ||
245 | * | ||
246 | * @see Match | ||
247 | * @see ChoiceHasNoOutgoing | ||
248 | * | ||
249 | */ | ||
250 | public static class Matcher extends BaseMatcher<ChoiceHasNoOutgoing.Match> { | ||
251 | /** | ||
252 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
253 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
254 | * | ||
255 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
256 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
257 | * | ||
258 | */ | ||
259 | public static ChoiceHasNoOutgoing.Matcher on(final ViatraQueryEngine engine) { | ||
260 | // check if matcher already exists | ||
261 | Matcher matcher = engine.getExistingMatcher(querySpecification()); | ||
262 | if (matcher == null) { | ||
263 | matcher = (Matcher)engine.getMatcher(querySpecification()); | ||
264 | } | ||
265 | return matcher; | ||
266 | } | ||
267 | |||
268 | /** | ||
269 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
270 | * @return an initialized matcher | ||
271 | * @noreference This method is for internal matcher initialization by the framework, do not call it manually. | ||
272 | * | ||
273 | */ | ||
274 | public static ChoiceHasNoOutgoing.Matcher create() { | ||
275 | return new Matcher(); | ||
276 | } | ||
277 | |||
278 | private final static int POSITION_C = 0; | ||
279 | |||
280 | private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(ChoiceHasNoOutgoing.Matcher.class); | ||
281 | |||
282 | /** | ||
283 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
284 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
285 | * | ||
286 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
287 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
288 | * | ||
289 | */ | ||
290 | private Matcher() { | ||
291 | super(querySpecification()); | ||
292 | } | ||
293 | |||
294 | /** | ||
295 | * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. | ||
296 | * @param pC the fixed value of pattern parameter c, or null if not bound. | ||
297 | * @return matches represented as a Match object. | ||
298 | * | ||
299 | */ | ||
300 | public Collection<ChoiceHasNoOutgoing.Match> getAllMatches(final Choice pC) { | ||
301 | return rawStreamAllMatches(new Object[]{pC}).collect(Collectors.toSet()); | ||
302 | } | ||
303 | |||
304 | /** | ||
305 | * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. | ||
306 | * </p> | ||
307 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
308 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
309 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
310 | * @param pC the fixed value of pattern parameter c, or null if not bound. | ||
311 | * @return a stream of matches represented as a Match object. | ||
312 | * | ||
313 | */ | ||
314 | public Stream<ChoiceHasNoOutgoing.Match> streamAllMatches(final Choice pC) { | ||
315 | return rawStreamAllMatches(new Object[]{pC}); | ||
316 | } | ||
317 | |||
318 | /** | ||
319 | * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
320 | * Neither determinism nor randomness of selection is guaranteed. | ||
321 | * @param pC the fixed value of pattern parameter c, or null if not bound. | ||
322 | * @return a match represented as a Match object, or null if no match is found. | ||
323 | * | ||
324 | */ | ||
325 | public Optional<ChoiceHasNoOutgoing.Match> getOneArbitraryMatch(final Choice pC) { | ||
326 | return rawGetOneArbitraryMatch(new Object[]{pC}); | ||
327 | } | ||
328 | |||
329 | /** | ||
330 | * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, | ||
331 | * under any possible substitution of the unspecified parameters (if any). | ||
332 | * @param pC the fixed value of pattern parameter c, or null if not bound. | ||
333 | * @return true if the input is a valid (partial) match of the pattern. | ||
334 | * | ||
335 | */ | ||
336 | public boolean hasMatch(final Choice pC) { | ||
337 | return rawHasMatch(new Object[]{pC}); | ||
338 | } | ||
339 | |||
340 | /** | ||
341 | * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. | ||
342 | * @param pC the fixed value of pattern parameter c, or null if not bound. | ||
343 | * @return the number of pattern matches found. | ||
344 | * | ||
345 | */ | ||
346 | public int countMatches(final Choice pC) { | ||
347 | return rawCountMatches(new Object[]{pC}); | ||
348 | } | ||
349 | |||
350 | /** | ||
351 | * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
352 | * Neither determinism nor randomness of selection is guaranteed. | ||
353 | * @param pC the fixed value of pattern parameter c, or null if not bound. | ||
354 | * @param processor the action that will process the selected match. | ||
355 | * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked | ||
356 | * | ||
357 | */ | ||
358 | public boolean forOneArbitraryMatch(final Choice pC, final Consumer<? super ChoiceHasNoOutgoing.Match> processor) { | ||
359 | return rawForOneArbitraryMatch(new Object[]{pC}, processor); | ||
360 | } | ||
361 | |||
362 | /** | ||
363 | * Returns a new (partial) match. | ||
364 | * This can be used e.g. to call the matcher with a partial match. | ||
365 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
366 | * @param pC the fixed value of pattern parameter c, or null if not bound. | ||
367 | * @return the (partial) match object. | ||
368 | * | ||
369 | */ | ||
370 | public ChoiceHasNoOutgoing.Match newMatch(final Choice pC) { | ||
371 | return ChoiceHasNoOutgoing.Match.newMatch(pC); | ||
372 | } | ||
373 | |||
374 | /** | ||
375 | * Retrieve the set of values that occur in matches for c. | ||
376 | * @return the Set of all values or empty set if there are no matches | ||
377 | * | ||
378 | */ | ||
379 | protected Stream<Choice> rawStreamAllValuesOfc(final Object[] parameters) { | ||
380 | return rawStreamAllValues(POSITION_C, parameters).map(Choice.class::cast); | ||
381 | } | ||
382 | |||
383 | /** | ||
384 | * Retrieve the set of values that occur in matches for c. | ||
385 | * @return the Set of all values or empty set if there are no matches | ||
386 | * | ||
387 | */ | ||
388 | public Set<Choice> getAllValuesOfc() { | ||
389 | return rawStreamAllValuesOfc(emptyArray()).collect(Collectors.toSet()); | ||
390 | } | ||
391 | |||
392 | /** | ||
393 | * Retrieve the set of values that occur in matches for c. | ||
394 | * @return the Set of all values or empty set if there are no matches | ||
395 | * | ||
396 | */ | ||
397 | public Stream<Choice> streamAllValuesOfc() { | ||
398 | return rawStreamAllValuesOfc(emptyArray()); | ||
399 | } | ||
400 | |||
401 | @Override | ||
402 | protected ChoiceHasNoOutgoing.Match tupleToMatch(final Tuple t) { | ||
403 | try { | ||
404 | return ChoiceHasNoOutgoing.Match.newMatch((Choice) t.get(POSITION_C)); | ||
405 | } catch(ClassCastException e) { | ||
406 | LOGGER.error("Element(s) in tuple not properly typed!",e); | ||
407 | return null; | ||
408 | } | ||
409 | } | ||
410 | |||
411 | @Override | ||
412 | protected ChoiceHasNoOutgoing.Match arrayToMatch(final Object[] match) { | ||
413 | try { | ||
414 | return ChoiceHasNoOutgoing.Match.newMatch((Choice) match[POSITION_C]); | ||
415 | } catch(ClassCastException e) { | ||
416 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
417 | return null; | ||
418 | } | ||
419 | } | ||
420 | |||
421 | @Override | ||
422 | protected ChoiceHasNoOutgoing.Match arrayToMatchMutable(final Object[] match) { | ||
423 | try { | ||
424 | return ChoiceHasNoOutgoing.Match.newMutableMatch((Choice) match[POSITION_C]); | ||
425 | } catch(ClassCastException e) { | ||
426 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
427 | return null; | ||
428 | } | ||
429 | } | ||
430 | |||
431 | /** | ||
432 | * @return the singleton instance of the query specification of this pattern | ||
433 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
434 | * | ||
435 | */ | ||
436 | public static IQuerySpecification<ChoiceHasNoOutgoing.Matcher> querySpecification() { | ||
437 | return ChoiceHasNoOutgoing.instance(); | ||
438 | } | ||
439 | } | ||
440 | |||
441 | private ChoiceHasNoOutgoing() { | ||
442 | super(GeneratedPQuery.INSTANCE); | ||
443 | } | ||
444 | |||
445 | /** | ||
446 | * @return the singleton instance of the query specification | ||
447 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
448 | * | ||
449 | */ | ||
450 | public static ChoiceHasNoOutgoing instance() { | ||
451 | try{ | ||
452 | return LazyHolder.INSTANCE; | ||
453 | } catch (ExceptionInInitializerError err) { | ||
454 | throw processInitializerError(err); | ||
455 | } | ||
456 | } | ||
457 | |||
458 | @Override | ||
459 | protected ChoiceHasNoOutgoing.Matcher instantiate(final ViatraQueryEngine engine) { | ||
460 | return ChoiceHasNoOutgoing.Matcher.on(engine); | ||
461 | } | ||
462 | |||
463 | @Override | ||
464 | public ChoiceHasNoOutgoing.Matcher instantiate() { | ||
465 | return ChoiceHasNoOutgoing.Matcher.create(); | ||
466 | } | ||
467 | |||
468 | @Override | ||
469 | public ChoiceHasNoOutgoing.Match newEmptyMatch() { | ||
470 | return ChoiceHasNoOutgoing.Match.newEmptyMatch(); | ||
471 | } | ||
472 | |||
473 | @Override | ||
474 | public ChoiceHasNoOutgoing.Match newMatch(final Object... parameters) { | ||
475 | return ChoiceHasNoOutgoing.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Choice) parameters[0]); | ||
476 | } | ||
477 | |||
478 | /** | ||
479 | * Inner class allowing the singleton instance of {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.ChoiceHasNoOutgoing (visibility: PUBLIC, simpleName: ChoiceHasNoOutgoing, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.ChoiceHasNoOutgoing, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created | ||
480 | * <b>not</b> at the class load time of the outer class, | ||
481 | * but rather at the first call to {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.ChoiceHasNoOutgoing (visibility: PUBLIC, simpleName: ChoiceHasNoOutgoing, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.ChoiceHasNoOutgoing, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. | ||
482 | * | ||
483 | * <p> This workaround is required e.g. to support recursion. | ||
484 | * | ||
485 | */ | ||
486 | private static class LazyHolder { | ||
487 | private final static ChoiceHasNoOutgoing INSTANCE = new ChoiceHasNoOutgoing(); | ||
488 | |||
489 | /** | ||
490 | * Statically initializes the query specification <b>after</b> the field {@link #INSTANCE} is assigned. | ||
491 | * This initialization order is required to support indirect recursion. | ||
492 | * | ||
493 | * <p> The static initializer is defined using a helper field to work around limitations of the code generator. | ||
494 | * | ||
495 | */ | ||
496 | private final static Object STATIC_INITIALIZER = ensureInitialized(); | ||
497 | |||
498 | public static Object ensureInitialized() { | ||
499 | INSTANCE.ensureInitializedInternal(); | ||
500 | return null; | ||
501 | } | ||
502 | } | ||
503 | |||
504 | private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { | ||
505 | private final static ChoiceHasNoOutgoing.GeneratedPQuery INSTANCE = new GeneratedPQuery(); | ||
506 | |||
507 | private final PParameter parameter_c = new PParameter("c", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Choice", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Choice")), PParameterDirection.INOUT); | ||
508 | |||
509 | private final List<PParameter> parameters = Arrays.asList(parameter_c); | ||
510 | |||
511 | private GeneratedPQuery() { | ||
512 | super(PVisibility.PUBLIC); | ||
513 | } | ||
514 | |||
515 | @Override | ||
516 | public String getFullyQualifiedName() { | ||
517 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.choiceHasNoOutgoing"; | ||
518 | } | ||
519 | |||
520 | @Override | ||
521 | public List<String> getParameterNames() { | ||
522 | return Arrays.asList("c"); | ||
523 | } | ||
524 | |||
525 | @Override | ||
526 | public List<PParameter> getParameters() { | ||
527 | return parameters; | ||
528 | } | ||
529 | |||
530 | @Override | ||
531 | public Set<PBody> doGetContainedBodies() { | ||
532 | setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); | ||
533 | Set<PBody> bodies = new LinkedHashSet<>(); | ||
534 | { | ||
535 | PBody body = new PBody(this); | ||
536 | PVariable var_c = body.getOrCreateVariableByName("c"); | ||
537 | PVariable var___0_ = body.getOrCreateVariableByName("_<0>"); | ||
538 | PVariable var___1_ = body.getOrCreateVariableByName("_<1>"); | ||
539 | new TypeConstraint(body, Tuples.flatTupleOf(var_c), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Choice"))); | ||
540 | body.setSymbolicParameters(Arrays.<ExportedParameter>asList( | ||
541 | new ExportedParameter(body, var_c, parameter_c) | ||
542 | )); | ||
543 | // neg find transition(_, c, _) | ||
544 | new NegativePatternCall(body, Tuples.flatTupleOf(var___0_, var_c, var___1_), Transition.instance().getInternalQueryRepresentation()); | ||
545 | bodies.add(body); | ||
546 | } | ||
547 | { | ||
548 | PAnnotation annotation = new PAnnotation("Constraint"); | ||
549 | annotation.addAttribute("severity", "error"); | ||
550 | annotation.addAttribute("message", "error"); | ||
551 | annotation.addAttribute("key", Arrays.asList(new Object[] { | ||
552 | new ParameterReference("c") | ||
553 | })); | ||
554 | addAnnotation(annotation); | ||
555 | } | ||
556 | return bodies; | ||
557 | } | ||
558 | } | ||
559 | } | ||
diff --git a/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/EntryInRegion.java b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/EntryInRegion.java new file mode 100644 index 00000000..147b27f9 --- /dev/null +++ b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/EntryInRegion.java | |||
@@ -0,0 +1,702 @@ | |||
1 | /** | ||
2 | * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql | ||
3 | */ | ||
4 | package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; | ||
5 | |||
6 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Entry; | ||
7 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Region; | ||
8 | import java.util.Arrays; | ||
9 | import java.util.Collection; | ||
10 | import java.util.LinkedHashSet; | ||
11 | import java.util.List; | ||
12 | import java.util.Objects; | ||
13 | import java.util.Optional; | ||
14 | import java.util.Set; | ||
15 | import java.util.function.Consumer; | ||
16 | import java.util.stream.Collectors; | ||
17 | import java.util.stream.Stream; | ||
18 | import org.apache.log4j.Logger; | ||
19 | import org.eclipse.emf.ecore.EClass; | ||
20 | import org.eclipse.viatra.query.runtime.api.IPatternMatch; | ||
21 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification; | ||
22 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; | ||
23 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; | ||
24 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; | ||
25 | import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; | ||
26 | import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; | ||
27 | import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; | ||
28 | import org.eclipse.viatra.query.runtime.emf.types.EStructuralFeatureInstancesKey; | ||
29 | import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; | ||
30 | import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; | ||
31 | import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; | ||
32 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality; | ||
33 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; | ||
34 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; | ||
35 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; | ||
36 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; | ||
37 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; | ||
38 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; | ||
39 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | ||
40 | import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; | ||
41 | |||
42 | /** | ||
43 | * A pattern-specific query specification that can instantiate Matcher in a type-safe way. | ||
44 | * | ||
45 | * <p>Original source: | ||
46 | * <code><pre> | ||
47 | * ///////// | ||
48 | * // Entry | ||
49 | * ///////// | ||
50 | * | ||
51 | * pattern entryInRegion(r1 : Region, e1 : Entry) { | ||
52 | * Region.vertices(r1, e1); | ||
53 | * } | ||
54 | * </pre></code> | ||
55 | * | ||
56 | * @see Matcher | ||
57 | * @see Match | ||
58 | * | ||
59 | */ | ||
60 | @SuppressWarnings("all") | ||
61 | public final class EntryInRegion extends BaseGeneratedEMFQuerySpecification<EntryInRegion.Matcher> { | ||
62 | /** | ||
63 | * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.entryInRegion pattern, | ||
64 | * to be used in conjunction with {@link Matcher}. | ||
65 | * | ||
66 | * <p>Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. | ||
67 | * Each instance is a (possibly partial) substitution of pattern parameters, | ||
68 | * usable to represent a match of the pattern in the result of a query, | ||
69 | * or to specify the bound (fixed) input parameters when issuing a query. | ||
70 | * | ||
71 | * @see Matcher | ||
72 | * | ||
73 | */ | ||
74 | public static abstract class Match extends BasePatternMatch { | ||
75 | private Region fR1; | ||
76 | |||
77 | private Entry fE1; | ||
78 | |||
79 | private static List<String> parameterNames = makeImmutableList("r1", "e1"); | ||
80 | |||
81 | private Match(final Region pR1, final Entry pE1) { | ||
82 | this.fR1 = pR1; | ||
83 | this.fE1 = pE1; | ||
84 | } | ||
85 | |||
86 | @Override | ||
87 | public Object get(final String parameterName) { | ||
88 | if ("r1".equals(parameterName)) return this.fR1; | ||
89 | if ("e1".equals(parameterName)) return this.fE1; | ||
90 | return null; | ||
91 | } | ||
92 | |||
93 | public Region getR1() { | ||
94 | return this.fR1; | ||
95 | } | ||
96 | |||
97 | public Entry getE1() { | ||
98 | return this.fE1; | ||
99 | } | ||
100 | |||
101 | @Override | ||
102 | public boolean set(final String parameterName, final Object newValue) { | ||
103 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
104 | if ("r1".equals(parameterName) ) { | ||
105 | this.fR1 = (Region) newValue; | ||
106 | return true; | ||
107 | } | ||
108 | if ("e1".equals(parameterName) ) { | ||
109 | this.fE1 = (Entry) newValue; | ||
110 | return true; | ||
111 | } | ||
112 | return false; | ||
113 | } | ||
114 | |||
115 | public void setR1(final Region pR1) { | ||
116 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
117 | this.fR1 = pR1; | ||
118 | } | ||
119 | |||
120 | public void setE1(final Entry pE1) { | ||
121 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
122 | this.fE1 = pE1; | ||
123 | } | ||
124 | |||
125 | @Override | ||
126 | public String patternName() { | ||
127 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.entryInRegion"; | ||
128 | } | ||
129 | |||
130 | @Override | ||
131 | public List<String> parameterNames() { | ||
132 | return EntryInRegion.Match.parameterNames; | ||
133 | } | ||
134 | |||
135 | @Override | ||
136 | public Object[] toArray() { | ||
137 | return new Object[]{fR1, fE1}; | ||
138 | } | ||
139 | |||
140 | @Override | ||
141 | public EntryInRegion.Match toImmutable() { | ||
142 | return isMutable() ? newMatch(fR1, fE1) : this; | ||
143 | } | ||
144 | |||
145 | @Override | ||
146 | public String prettyPrint() { | ||
147 | StringBuilder result = new StringBuilder(); | ||
148 | result.append("\"r1\"=" + prettyPrintValue(fR1) + ", "); | ||
149 | result.append("\"e1\"=" + prettyPrintValue(fE1)); | ||
150 | return result.toString(); | ||
151 | } | ||
152 | |||
153 | @Override | ||
154 | public int hashCode() { | ||
155 | return Objects.hash(fR1, fE1); | ||
156 | } | ||
157 | |||
158 | @Override | ||
159 | public boolean equals(final Object obj) { | ||
160 | if (this == obj) | ||
161 | return true; | ||
162 | if (obj == null) { | ||
163 | return false; | ||
164 | } | ||
165 | if ((obj instanceof EntryInRegion.Match)) { | ||
166 | EntryInRegion.Match other = (EntryInRegion.Match) obj; | ||
167 | return Objects.equals(fR1, other.fR1) && Objects.equals(fE1, other.fE1); | ||
168 | } else { | ||
169 | // this should be infrequent | ||
170 | if (!(obj instanceof IPatternMatch)) { | ||
171 | return false; | ||
172 | } | ||
173 | IPatternMatch otherSig = (IPatternMatch) obj; | ||
174 | return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); | ||
175 | } | ||
176 | } | ||
177 | |||
178 | @Override | ||
179 | public EntryInRegion specification() { | ||
180 | return EntryInRegion.instance(); | ||
181 | } | ||
182 | |||
183 | /** | ||
184 | * Returns an empty, mutable match. | ||
185 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
186 | * | ||
187 | * @return the empty match. | ||
188 | * | ||
189 | */ | ||
190 | public static EntryInRegion.Match newEmptyMatch() { | ||
191 | return new Mutable(null, null); | ||
192 | } | ||
193 | |||
194 | /** | ||
195 | * Returns a mutable (partial) match. | ||
196 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
197 | * | ||
198 | * @param pR1 the fixed value of pattern parameter r1, or null if not bound. | ||
199 | * @param pE1 the fixed value of pattern parameter e1, or null if not bound. | ||
200 | * @return the new, mutable (partial) match object. | ||
201 | * | ||
202 | */ | ||
203 | public static EntryInRegion.Match newMutableMatch(final Region pR1, final Entry pE1) { | ||
204 | return new Mutable(pR1, pE1); | ||
205 | } | ||
206 | |||
207 | /** | ||
208 | * Returns a new (partial) match. | ||
209 | * This can be used e.g. to call the matcher with a partial match. | ||
210 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
211 | * @param pR1 the fixed value of pattern parameter r1, or null if not bound. | ||
212 | * @param pE1 the fixed value of pattern parameter e1, or null if not bound. | ||
213 | * @return the (partial) match object. | ||
214 | * | ||
215 | */ | ||
216 | public static EntryInRegion.Match newMatch(final Region pR1, final Entry pE1) { | ||
217 | return new Immutable(pR1, pE1); | ||
218 | } | ||
219 | |||
220 | private static final class Mutable extends EntryInRegion.Match { | ||
221 | Mutable(final Region pR1, final Entry pE1) { | ||
222 | super(pR1, pE1); | ||
223 | } | ||
224 | |||
225 | @Override | ||
226 | public boolean isMutable() { | ||
227 | return true; | ||
228 | } | ||
229 | } | ||
230 | |||
231 | private static final class Immutable extends EntryInRegion.Match { | ||
232 | Immutable(final Region pR1, final Entry pE1) { | ||
233 | super(pR1, pE1); | ||
234 | } | ||
235 | |||
236 | @Override | ||
237 | public boolean isMutable() { | ||
238 | return false; | ||
239 | } | ||
240 | } | ||
241 | } | ||
242 | |||
243 | /** | ||
244 | * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.entryInRegion pattern, | ||
245 | * providing pattern-specific query methods. | ||
246 | * | ||
247 | * <p>Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, | ||
248 | * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. | ||
249 | * | ||
250 | * <p>Matches of the pattern will be represented as {@link Match}. | ||
251 | * | ||
252 | * <p>Original source: | ||
253 | * <code><pre> | ||
254 | * ///////// | ||
255 | * // Entry | ||
256 | * ///////// | ||
257 | * | ||
258 | * pattern entryInRegion(r1 : Region, e1 : Entry) { | ||
259 | * Region.vertices(r1, e1); | ||
260 | * } | ||
261 | * </pre></code> | ||
262 | * | ||
263 | * @see Match | ||
264 | * @see EntryInRegion | ||
265 | * | ||
266 | */ | ||
267 | public static class Matcher extends BaseMatcher<EntryInRegion.Match> { | ||
268 | /** | ||
269 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
270 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
271 | * | ||
272 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
273 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
274 | * | ||
275 | */ | ||
276 | public static EntryInRegion.Matcher on(final ViatraQueryEngine engine) { | ||
277 | // check if matcher already exists | ||
278 | Matcher matcher = engine.getExistingMatcher(querySpecification()); | ||
279 | if (matcher == null) { | ||
280 | matcher = (Matcher)engine.getMatcher(querySpecification()); | ||
281 | } | ||
282 | return matcher; | ||
283 | } | ||
284 | |||
285 | /** | ||
286 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
287 | * @return an initialized matcher | ||
288 | * @noreference This method is for internal matcher initialization by the framework, do not call it manually. | ||
289 | * | ||
290 | */ | ||
291 | public static EntryInRegion.Matcher create() { | ||
292 | return new Matcher(); | ||
293 | } | ||
294 | |||
295 | private final static int POSITION_R1 = 0; | ||
296 | |||
297 | private final static int POSITION_E1 = 1; | ||
298 | |||
299 | private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(EntryInRegion.Matcher.class); | ||
300 | |||
301 | /** | ||
302 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
303 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
304 | * | ||
305 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
306 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
307 | * | ||
308 | */ | ||
309 | private Matcher() { | ||
310 | super(querySpecification()); | ||
311 | } | ||
312 | |||
313 | /** | ||
314 | * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. | ||
315 | * @param pR1 the fixed value of pattern parameter r1, or null if not bound. | ||
316 | * @param pE1 the fixed value of pattern parameter e1, or null if not bound. | ||
317 | * @return matches represented as a Match object. | ||
318 | * | ||
319 | */ | ||
320 | public Collection<EntryInRegion.Match> getAllMatches(final Region pR1, final Entry pE1) { | ||
321 | return rawStreamAllMatches(new Object[]{pR1, pE1}).collect(Collectors.toSet()); | ||
322 | } | ||
323 | |||
324 | /** | ||
325 | * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. | ||
326 | * </p> | ||
327 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
328 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
329 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
330 | * @param pR1 the fixed value of pattern parameter r1, or null if not bound. | ||
331 | * @param pE1 the fixed value of pattern parameter e1, or null if not bound. | ||
332 | * @return a stream of matches represented as a Match object. | ||
333 | * | ||
334 | */ | ||
335 | public Stream<EntryInRegion.Match> streamAllMatches(final Region pR1, final Entry pE1) { | ||
336 | return rawStreamAllMatches(new Object[]{pR1, pE1}); | ||
337 | } | ||
338 | |||
339 | /** | ||
340 | * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
341 | * Neither determinism nor randomness of selection is guaranteed. | ||
342 | * @param pR1 the fixed value of pattern parameter r1, or null if not bound. | ||
343 | * @param pE1 the fixed value of pattern parameter e1, or null if not bound. | ||
344 | * @return a match represented as a Match object, or null if no match is found. | ||
345 | * | ||
346 | */ | ||
347 | public Optional<EntryInRegion.Match> getOneArbitraryMatch(final Region pR1, final Entry pE1) { | ||
348 | return rawGetOneArbitraryMatch(new Object[]{pR1, pE1}); | ||
349 | } | ||
350 | |||
351 | /** | ||
352 | * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, | ||
353 | * under any possible substitution of the unspecified parameters (if any). | ||
354 | * @param pR1 the fixed value of pattern parameter r1, or null if not bound. | ||
355 | * @param pE1 the fixed value of pattern parameter e1, or null if not bound. | ||
356 | * @return true if the input is a valid (partial) match of the pattern. | ||
357 | * | ||
358 | */ | ||
359 | public boolean hasMatch(final Region pR1, final Entry pE1) { | ||
360 | return rawHasMatch(new Object[]{pR1, pE1}); | ||
361 | } | ||
362 | |||
363 | /** | ||
364 | * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. | ||
365 | * @param pR1 the fixed value of pattern parameter r1, or null if not bound. | ||
366 | * @param pE1 the fixed value of pattern parameter e1, or null if not bound. | ||
367 | * @return the number of pattern matches found. | ||
368 | * | ||
369 | */ | ||
370 | public int countMatches(final Region pR1, final Entry pE1) { | ||
371 | return rawCountMatches(new Object[]{pR1, pE1}); | ||
372 | } | ||
373 | |||
374 | /** | ||
375 | * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
376 | * Neither determinism nor randomness of selection is guaranteed. | ||
377 | * @param pR1 the fixed value of pattern parameter r1, or null if not bound. | ||
378 | * @param pE1 the fixed value of pattern parameter e1, or null if not bound. | ||
379 | * @param processor the action that will process the selected match. | ||
380 | * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked | ||
381 | * | ||
382 | */ | ||
383 | public boolean forOneArbitraryMatch(final Region pR1, final Entry pE1, final Consumer<? super EntryInRegion.Match> processor) { | ||
384 | return rawForOneArbitraryMatch(new Object[]{pR1, pE1}, processor); | ||
385 | } | ||
386 | |||
387 | /** | ||
388 | * Returns a new (partial) match. | ||
389 | * This can be used e.g. to call the matcher with a partial match. | ||
390 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
391 | * @param pR1 the fixed value of pattern parameter r1, or null if not bound. | ||
392 | * @param pE1 the fixed value of pattern parameter e1, or null if not bound. | ||
393 | * @return the (partial) match object. | ||
394 | * | ||
395 | */ | ||
396 | public EntryInRegion.Match newMatch(final Region pR1, final Entry pE1) { | ||
397 | return EntryInRegion.Match.newMatch(pR1, pE1); | ||
398 | } | ||
399 | |||
400 | /** | ||
401 | * Retrieve the set of values that occur in matches for r1. | ||
402 | * @return the Set of all values or empty set if there are no matches | ||
403 | * | ||
404 | */ | ||
405 | protected Stream<Region> rawStreamAllValuesOfr1(final Object[] parameters) { | ||
406 | return rawStreamAllValues(POSITION_R1, parameters).map(Region.class::cast); | ||
407 | } | ||
408 | |||
409 | /** | ||
410 | * Retrieve the set of values that occur in matches for r1. | ||
411 | * @return the Set of all values or empty set if there are no matches | ||
412 | * | ||
413 | */ | ||
414 | public Set<Region> getAllValuesOfr1() { | ||
415 | return rawStreamAllValuesOfr1(emptyArray()).collect(Collectors.toSet()); | ||
416 | } | ||
417 | |||
418 | /** | ||
419 | * Retrieve the set of values that occur in matches for r1. | ||
420 | * @return the Set of all values or empty set if there are no matches | ||
421 | * | ||
422 | */ | ||
423 | public Stream<Region> streamAllValuesOfr1() { | ||
424 | return rawStreamAllValuesOfr1(emptyArray()); | ||
425 | } | ||
426 | |||
427 | /** | ||
428 | * Retrieve the set of values that occur in matches for r1. | ||
429 | * </p> | ||
430 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
431 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
432 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
433 | * | ||
434 | * @return the Stream of all values or empty set if there are no matches | ||
435 | * | ||
436 | */ | ||
437 | public Stream<Region> streamAllValuesOfr1(final EntryInRegion.Match partialMatch) { | ||
438 | return rawStreamAllValuesOfr1(partialMatch.toArray()); | ||
439 | } | ||
440 | |||
441 | /** | ||
442 | * Retrieve the set of values that occur in matches for r1. | ||
443 | * </p> | ||
444 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
445 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
446 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
447 | * | ||
448 | * @return the Stream of all values or empty set if there are no matches | ||
449 | * | ||
450 | */ | ||
451 | public Stream<Region> streamAllValuesOfr1(final Entry pE1) { | ||
452 | return rawStreamAllValuesOfr1(new Object[]{null, pE1}); | ||
453 | } | ||
454 | |||
455 | /** | ||
456 | * Retrieve the set of values that occur in matches for r1. | ||
457 | * @return the Set of all values or empty set if there are no matches | ||
458 | * | ||
459 | */ | ||
460 | public Set<Region> getAllValuesOfr1(final EntryInRegion.Match partialMatch) { | ||
461 | return rawStreamAllValuesOfr1(partialMatch.toArray()).collect(Collectors.toSet()); | ||
462 | } | ||
463 | |||
464 | /** | ||
465 | * Retrieve the set of values that occur in matches for r1. | ||
466 | * @return the Set of all values or empty set if there are no matches | ||
467 | * | ||
468 | */ | ||
469 | public Set<Region> getAllValuesOfr1(final Entry pE1) { | ||
470 | return rawStreamAllValuesOfr1(new Object[]{null, pE1}).collect(Collectors.toSet()); | ||
471 | } | ||
472 | |||
473 | /** | ||
474 | * Retrieve the set of values that occur in matches for e1. | ||
475 | * @return the Set of all values or empty set if there are no matches | ||
476 | * | ||
477 | */ | ||
478 | protected Stream<Entry> rawStreamAllValuesOfe1(final Object[] parameters) { | ||
479 | return rawStreamAllValues(POSITION_E1, parameters).map(Entry.class::cast); | ||
480 | } | ||
481 | |||
482 | /** | ||
483 | * Retrieve the set of values that occur in matches for e1. | ||
484 | * @return the Set of all values or empty set if there are no matches | ||
485 | * | ||
486 | */ | ||
487 | public Set<Entry> getAllValuesOfe1() { | ||
488 | return rawStreamAllValuesOfe1(emptyArray()).collect(Collectors.toSet()); | ||
489 | } | ||
490 | |||
491 | /** | ||
492 | * Retrieve the set of values that occur in matches for e1. | ||
493 | * @return the Set of all values or empty set if there are no matches | ||
494 | * | ||
495 | */ | ||
496 | public Stream<Entry> streamAllValuesOfe1() { | ||
497 | return rawStreamAllValuesOfe1(emptyArray()); | ||
498 | } | ||
499 | |||
500 | /** | ||
501 | * Retrieve the set of values that occur in matches for e1. | ||
502 | * </p> | ||
503 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
504 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
505 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
506 | * | ||
507 | * @return the Stream of all values or empty set if there are no matches | ||
508 | * | ||
509 | */ | ||
510 | public Stream<Entry> streamAllValuesOfe1(final EntryInRegion.Match partialMatch) { | ||
511 | return rawStreamAllValuesOfe1(partialMatch.toArray()); | ||
512 | } | ||
513 | |||
514 | /** | ||
515 | * Retrieve the set of values that occur in matches for e1. | ||
516 | * </p> | ||
517 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
518 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
519 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
520 | * | ||
521 | * @return the Stream of all values or empty set if there are no matches | ||
522 | * | ||
523 | */ | ||
524 | public Stream<Entry> streamAllValuesOfe1(final Region pR1) { | ||
525 | return rawStreamAllValuesOfe1(new Object[]{pR1, null}); | ||
526 | } | ||
527 | |||
528 | /** | ||
529 | * Retrieve the set of values that occur in matches for e1. | ||
530 | * @return the Set of all values or empty set if there are no matches | ||
531 | * | ||
532 | */ | ||
533 | public Set<Entry> getAllValuesOfe1(final EntryInRegion.Match partialMatch) { | ||
534 | return rawStreamAllValuesOfe1(partialMatch.toArray()).collect(Collectors.toSet()); | ||
535 | } | ||
536 | |||
537 | /** | ||
538 | * Retrieve the set of values that occur in matches for e1. | ||
539 | * @return the Set of all values or empty set if there are no matches | ||
540 | * | ||
541 | */ | ||
542 | public Set<Entry> getAllValuesOfe1(final Region pR1) { | ||
543 | return rawStreamAllValuesOfe1(new Object[]{pR1, null}).collect(Collectors.toSet()); | ||
544 | } | ||
545 | |||
546 | @Override | ||
547 | protected EntryInRegion.Match tupleToMatch(final Tuple t) { | ||
548 | try { | ||
549 | return EntryInRegion.Match.newMatch((Region) t.get(POSITION_R1), (Entry) t.get(POSITION_E1)); | ||
550 | } catch(ClassCastException e) { | ||
551 | LOGGER.error("Element(s) in tuple not properly typed!",e); | ||
552 | return null; | ||
553 | } | ||
554 | } | ||
555 | |||
556 | @Override | ||
557 | protected EntryInRegion.Match arrayToMatch(final Object[] match) { | ||
558 | try { | ||
559 | return EntryInRegion.Match.newMatch((Region) match[POSITION_R1], (Entry) match[POSITION_E1]); | ||
560 | } catch(ClassCastException e) { | ||
561 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
562 | return null; | ||
563 | } | ||
564 | } | ||
565 | |||
566 | @Override | ||
567 | protected EntryInRegion.Match arrayToMatchMutable(final Object[] match) { | ||
568 | try { | ||
569 | return EntryInRegion.Match.newMutableMatch((Region) match[POSITION_R1], (Entry) match[POSITION_E1]); | ||
570 | } catch(ClassCastException e) { | ||
571 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
572 | return null; | ||
573 | } | ||
574 | } | ||
575 | |||
576 | /** | ||
577 | * @return the singleton instance of the query specification of this pattern | ||
578 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
579 | * | ||
580 | */ | ||
581 | public static IQuerySpecification<EntryInRegion.Matcher> querySpecification() { | ||
582 | return EntryInRegion.instance(); | ||
583 | } | ||
584 | } | ||
585 | |||
586 | private EntryInRegion() { | ||
587 | super(GeneratedPQuery.INSTANCE); | ||
588 | } | ||
589 | |||
590 | /** | ||
591 | * @return the singleton instance of the query specification | ||
592 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
593 | * | ||
594 | */ | ||
595 | public static EntryInRegion instance() { | ||
596 | try{ | ||
597 | return LazyHolder.INSTANCE; | ||
598 | } catch (ExceptionInInitializerError err) { | ||
599 | throw processInitializerError(err); | ||
600 | } | ||
601 | } | ||
602 | |||
603 | @Override | ||
604 | protected EntryInRegion.Matcher instantiate(final ViatraQueryEngine engine) { | ||
605 | return EntryInRegion.Matcher.on(engine); | ||
606 | } | ||
607 | |||
608 | @Override | ||
609 | public EntryInRegion.Matcher instantiate() { | ||
610 | return EntryInRegion.Matcher.create(); | ||
611 | } | ||
612 | |||
613 | @Override | ||
614 | public EntryInRegion.Match newEmptyMatch() { | ||
615 | return EntryInRegion.Match.newEmptyMatch(); | ||
616 | } | ||
617 | |||
618 | @Override | ||
619 | public EntryInRegion.Match newMatch(final Object... parameters) { | ||
620 | return EntryInRegion.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Region) parameters[0], (ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Entry) parameters[1]); | ||
621 | } | ||
622 | |||
623 | /** | ||
624 | * Inner class allowing the singleton instance of {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.EntryInRegion (visibility: PUBLIC, simpleName: EntryInRegion, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.EntryInRegion, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created | ||
625 | * <b>not</b> at the class load time of the outer class, | ||
626 | * but rather at the first call to {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.EntryInRegion (visibility: PUBLIC, simpleName: EntryInRegion, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.EntryInRegion, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. | ||
627 | * | ||
628 | * <p> This workaround is required e.g. to support recursion. | ||
629 | * | ||
630 | */ | ||
631 | private static class LazyHolder { | ||
632 | private final static EntryInRegion INSTANCE = new EntryInRegion(); | ||
633 | |||
634 | /** | ||
635 | * Statically initializes the query specification <b>after</b> the field {@link #INSTANCE} is assigned. | ||
636 | * This initialization order is required to support indirect recursion. | ||
637 | * | ||
638 | * <p> The static initializer is defined using a helper field to work around limitations of the code generator. | ||
639 | * | ||
640 | */ | ||
641 | private final static Object STATIC_INITIALIZER = ensureInitialized(); | ||
642 | |||
643 | public static Object ensureInitialized() { | ||
644 | INSTANCE.ensureInitializedInternal(); | ||
645 | return null; | ||
646 | } | ||
647 | } | ||
648 | |||
649 | private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { | ||
650 | private final static EntryInRegion.GeneratedPQuery INSTANCE = new GeneratedPQuery(); | ||
651 | |||
652 | private final PParameter parameter_r1 = new PParameter("r1", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Region", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Region")), PParameterDirection.INOUT); | ||
653 | |||
654 | private final PParameter parameter_e1 = new PParameter("e1", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Entry", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Entry")), PParameterDirection.INOUT); | ||
655 | |||
656 | private final List<PParameter> parameters = Arrays.asList(parameter_r1, parameter_e1); | ||
657 | |||
658 | private GeneratedPQuery() { | ||
659 | super(PVisibility.PUBLIC); | ||
660 | } | ||
661 | |||
662 | @Override | ||
663 | public String getFullyQualifiedName() { | ||
664 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.entryInRegion"; | ||
665 | } | ||
666 | |||
667 | @Override | ||
668 | public List<String> getParameterNames() { | ||
669 | return Arrays.asList("r1","e1"); | ||
670 | } | ||
671 | |||
672 | @Override | ||
673 | public List<PParameter> getParameters() { | ||
674 | return parameters; | ||
675 | } | ||
676 | |||
677 | @Override | ||
678 | public Set<PBody> doGetContainedBodies() { | ||
679 | setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); | ||
680 | Set<PBody> bodies = new LinkedHashSet<>(); | ||
681 | { | ||
682 | PBody body = new PBody(this); | ||
683 | PVariable var_r1 = body.getOrCreateVariableByName("r1"); | ||
684 | PVariable var_e1 = body.getOrCreateVariableByName("e1"); | ||
685 | new TypeConstraint(body, Tuples.flatTupleOf(var_r1), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Region"))); | ||
686 | new TypeConstraint(body, Tuples.flatTupleOf(var_e1), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Entry"))); | ||
687 | body.setSymbolicParameters(Arrays.<ExportedParameter>asList( | ||
688 | new ExportedParameter(body, var_r1, parameter_r1), | ||
689 | new ExportedParameter(body, var_e1, parameter_e1) | ||
690 | )); | ||
691 | // Region.vertices(r1, e1) | ||
692 | new TypeConstraint(body, Tuples.flatTupleOf(var_r1), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Region"))); | ||
693 | PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); | ||
694 | new TypeConstraint(body, Tuples.flatTupleOf(var_r1, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Region", "vertices"))); | ||
695 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); | ||
696 | new Equality(body, var__virtual_0_, var_e1); | ||
697 | bodies.add(body); | ||
698 | } | ||
699 | return bodies; | ||
700 | } | ||
701 | } | ||
702 | } | ||
diff --git a/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/HasMultipleIncomingTrainsition.java b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/HasMultipleIncomingTrainsition.java new file mode 100644 index 00000000..236ce5ff --- /dev/null +++ b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/HasMultipleIncomingTrainsition.java | |||
@@ -0,0 +1,549 @@ | |||
1 | /** | ||
2 | * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql | ||
3 | */ | ||
4 | package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; | ||
5 | |||
6 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization; | ||
7 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.Transition; | ||
8 | import java.util.Arrays; | ||
9 | import java.util.Collection; | ||
10 | import java.util.LinkedHashSet; | ||
11 | import java.util.List; | ||
12 | import java.util.Objects; | ||
13 | import java.util.Optional; | ||
14 | import java.util.Set; | ||
15 | import java.util.function.Consumer; | ||
16 | import java.util.stream.Collectors; | ||
17 | import java.util.stream.Stream; | ||
18 | import org.apache.log4j.Logger; | ||
19 | import org.eclipse.emf.ecore.EClass; | ||
20 | import org.eclipse.viatra.query.runtime.api.IPatternMatch; | ||
21 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification; | ||
22 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; | ||
23 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; | ||
24 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; | ||
25 | import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; | ||
26 | import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; | ||
27 | import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; | ||
28 | import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; | ||
29 | import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; | ||
30 | import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; | ||
31 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; | ||
32 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Inequality; | ||
33 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall; | ||
34 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; | ||
35 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; | ||
36 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; | ||
37 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; | ||
38 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; | ||
39 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | ||
40 | import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; | ||
41 | |||
42 | /** | ||
43 | * A pattern-specific query specification that can instantiate Matcher in a type-safe way. | ||
44 | * | ||
45 | * <p>Original source: | ||
46 | * <code><pre> | ||
47 | * pattern hasMultipleIncomingTrainsition(v : Synchronization) { | ||
48 | * find transition(_, src1, v); | ||
49 | * find transition(_, src2, v); | ||
50 | * src1 != src2; | ||
51 | * } | ||
52 | * </pre></code> | ||
53 | * | ||
54 | * @see Matcher | ||
55 | * @see Match | ||
56 | * | ||
57 | */ | ||
58 | @SuppressWarnings("all") | ||
59 | public final class HasMultipleIncomingTrainsition extends BaseGeneratedEMFQuerySpecification<HasMultipleIncomingTrainsition.Matcher> { | ||
60 | /** | ||
61 | * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.hasMultipleIncomingTrainsition pattern, | ||
62 | * to be used in conjunction with {@link Matcher}. | ||
63 | * | ||
64 | * <p>Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. | ||
65 | * Each instance is a (possibly partial) substitution of pattern parameters, | ||
66 | * usable to represent a match of the pattern in the result of a query, | ||
67 | * or to specify the bound (fixed) input parameters when issuing a query. | ||
68 | * | ||
69 | * @see Matcher | ||
70 | * | ||
71 | */ | ||
72 | public static abstract class Match extends BasePatternMatch { | ||
73 | private Synchronization fV; | ||
74 | |||
75 | private static List<String> parameterNames = makeImmutableList("v"); | ||
76 | |||
77 | private Match(final Synchronization pV) { | ||
78 | this.fV = pV; | ||
79 | } | ||
80 | |||
81 | @Override | ||
82 | public Object get(final String parameterName) { | ||
83 | if ("v".equals(parameterName)) return this.fV; | ||
84 | return null; | ||
85 | } | ||
86 | |||
87 | public Synchronization getV() { | ||
88 | return this.fV; | ||
89 | } | ||
90 | |||
91 | @Override | ||
92 | public boolean set(final String parameterName, final Object newValue) { | ||
93 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
94 | if ("v".equals(parameterName) ) { | ||
95 | this.fV = (Synchronization) newValue; | ||
96 | return true; | ||
97 | } | ||
98 | return false; | ||
99 | } | ||
100 | |||
101 | public void setV(final Synchronization pV) { | ||
102 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
103 | this.fV = pV; | ||
104 | } | ||
105 | |||
106 | @Override | ||
107 | public String patternName() { | ||
108 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.hasMultipleIncomingTrainsition"; | ||
109 | } | ||
110 | |||
111 | @Override | ||
112 | public List<String> parameterNames() { | ||
113 | return HasMultipleIncomingTrainsition.Match.parameterNames; | ||
114 | } | ||
115 | |||
116 | @Override | ||
117 | public Object[] toArray() { | ||
118 | return new Object[]{fV}; | ||
119 | } | ||
120 | |||
121 | @Override | ||
122 | public HasMultipleIncomingTrainsition.Match toImmutable() { | ||
123 | return isMutable() ? newMatch(fV) : this; | ||
124 | } | ||
125 | |||
126 | @Override | ||
127 | public String prettyPrint() { | ||
128 | StringBuilder result = new StringBuilder(); | ||
129 | result.append("\"v\"=" + prettyPrintValue(fV)); | ||
130 | return result.toString(); | ||
131 | } | ||
132 | |||
133 | @Override | ||
134 | public int hashCode() { | ||
135 | return Objects.hash(fV); | ||
136 | } | ||
137 | |||
138 | @Override | ||
139 | public boolean equals(final Object obj) { | ||
140 | if (this == obj) | ||
141 | return true; | ||
142 | if (obj == null) { | ||
143 | return false; | ||
144 | } | ||
145 | if ((obj instanceof HasMultipleIncomingTrainsition.Match)) { | ||
146 | HasMultipleIncomingTrainsition.Match other = (HasMultipleIncomingTrainsition.Match) obj; | ||
147 | return Objects.equals(fV, other.fV); | ||
148 | } else { | ||
149 | // this should be infrequent | ||
150 | if (!(obj instanceof IPatternMatch)) { | ||
151 | return false; | ||
152 | } | ||
153 | IPatternMatch otherSig = (IPatternMatch) obj; | ||
154 | return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); | ||
155 | } | ||
156 | } | ||
157 | |||
158 | @Override | ||
159 | public HasMultipleIncomingTrainsition specification() { | ||
160 | return HasMultipleIncomingTrainsition.instance(); | ||
161 | } | ||
162 | |||
163 | /** | ||
164 | * Returns an empty, mutable match. | ||
165 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
166 | * | ||
167 | * @return the empty match. | ||
168 | * | ||
169 | */ | ||
170 | public static HasMultipleIncomingTrainsition.Match newEmptyMatch() { | ||
171 | return new Mutable(null); | ||
172 | } | ||
173 | |||
174 | /** | ||
175 | * Returns a mutable (partial) match. | ||
176 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
177 | * | ||
178 | * @param pV the fixed value of pattern parameter v, or null if not bound. | ||
179 | * @return the new, mutable (partial) match object. | ||
180 | * | ||
181 | */ | ||
182 | public static HasMultipleIncomingTrainsition.Match newMutableMatch(final Synchronization pV) { | ||
183 | return new Mutable(pV); | ||
184 | } | ||
185 | |||
186 | /** | ||
187 | * Returns a new (partial) match. | ||
188 | * This can be used e.g. to call the matcher with a partial match. | ||
189 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
190 | * @param pV the fixed value of pattern parameter v, or null if not bound. | ||
191 | * @return the (partial) match object. | ||
192 | * | ||
193 | */ | ||
194 | public static HasMultipleIncomingTrainsition.Match newMatch(final Synchronization pV) { | ||
195 | return new Immutable(pV); | ||
196 | } | ||
197 | |||
198 | private static final class Mutable extends HasMultipleIncomingTrainsition.Match { | ||
199 | Mutable(final Synchronization pV) { | ||
200 | super(pV); | ||
201 | } | ||
202 | |||
203 | @Override | ||
204 | public boolean isMutable() { | ||
205 | return true; | ||
206 | } | ||
207 | } | ||
208 | |||
209 | private static final class Immutable extends HasMultipleIncomingTrainsition.Match { | ||
210 | Immutable(final Synchronization pV) { | ||
211 | super(pV); | ||
212 | } | ||
213 | |||
214 | @Override | ||
215 | public boolean isMutable() { | ||
216 | return false; | ||
217 | } | ||
218 | } | ||
219 | } | ||
220 | |||
221 | /** | ||
222 | * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.hasMultipleIncomingTrainsition pattern, | ||
223 | * providing pattern-specific query methods. | ||
224 | * | ||
225 | * <p>Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, | ||
226 | * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. | ||
227 | * | ||
228 | * <p>Matches of the pattern will be represented as {@link Match}. | ||
229 | * | ||
230 | * <p>Original source: | ||
231 | * <code><pre> | ||
232 | * pattern hasMultipleIncomingTrainsition(v : Synchronization) { | ||
233 | * find transition(_, src1, v); | ||
234 | * find transition(_, src2, v); | ||
235 | * src1 != src2; | ||
236 | * } | ||
237 | * </pre></code> | ||
238 | * | ||
239 | * @see Match | ||
240 | * @see HasMultipleIncomingTrainsition | ||
241 | * | ||
242 | */ | ||
243 | public static class Matcher extends BaseMatcher<HasMultipleIncomingTrainsition.Match> { | ||
244 | /** | ||
245 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
246 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
247 | * | ||
248 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
249 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
250 | * | ||
251 | */ | ||
252 | public static HasMultipleIncomingTrainsition.Matcher on(final ViatraQueryEngine engine) { | ||
253 | // check if matcher already exists | ||
254 | Matcher matcher = engine.getExistingMatcher(querySpecification()); | ||
255 | if (matcher == null) { | ||
256 | matcher = (Matcher)engine.getMatcher(querySpecification()); | ||
257 | } | ||
258 | return matcher; | ||
259 | } | ||
260 | |||
261 | /** | ||
262 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
263 | * @return an initialized matcher | ||
264 | * @noreference This method is for internal matcher initialization by the framework, do not call it manually. | ||
265 | * | ||
266 | */ | ||
267 | public static HasMultipleIncomingTrainsition.Matcher create() { | ||
268 | return new Matcher(); | ||
269 | } | ||
270 | |||
271 | private final static int POSITION_V = 0; | ||
272 | |||
273 | private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(HasMultipleIncomingTrainsition.Matcher.class); | ||
274 | |||
275 | /** | ||
276 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
277 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
278 | * | ||
279 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
280 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
281 | * | ||
282 | */ | ||
283 | private Matcher() { | ||
284 | super(querySpecification()); | ||
285 | } | ||
286 | |||
287 | /** | ||
288 | * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. | ||
289 | * @param pV the fixed value of pattern parameter v, or null if not bound. | ||
290 | * @return matches represented as a Match object. | ||
291 | * | ||
292 | */ | ||
293 | public Collection<HasMultipleIncomingTrainsition.Match> getAllMatches(final Synchronization pV) { | ||
294 | return rawStreamAllMatches(new Object[]{pV}).collect(Collectors.toSet()); | ||
295 | } | ||
296 | |||
297 | /** | ||
298 | * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. | ||
299 | * </p> | ||
300 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
301 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
302 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
303 | * @param pV the fixed value of pattern parameter v, or null if not bound. | ||
304 | * @return a stream of matches represented as a Match object. | ||
305 | * | ||
306 | */ | ||
307 | public Stream<HasMultipleIncomingTrainsition.Match> streamAllMatches(final Synchronization pV) { | ||
308 | return rawStreamAllMatches(new Object[]{pV}); | ||
309 | } | ||
310 | |||
311 | /** | ||
312 | * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
313 | * Neither determinism nor randomness of selection is guaranteed. | ||
314 | * @param pV the fixed value of pattern parameter v, or null if not bound. | ||
315 | * @return a match represented as a Match object, or null if no match is found. | ||
316 | * | ||
317 | */ | ||
318 | public Optional<HasMultipleIncomingTrainsition.Match> getOneArbitraryMatch(final Synchronization pV) { | ||
319 | return rawGetOneArbitraryMatch(new Object[]{pV}); | ||
320 | } | ||
321 | |||
322 | /** | ||
323 | * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, | ||
324 | * under any possible substitution of the unspecified parameters (if any). | ||
325 | * @param pV the fixed value of pattern parameter v, or null if not bound. | ||
326 | * @return true if the input is a valid (partial) match of the pattern. | ||
327 | * | ||
328 | */ | ||
329 | public boolean hasMatch(final Synchronization pV) { | ||
330 | return rawHasMatch(new Object[]{pV}); | ||
331 | } | ||
332 | |||
333 | /** | ||
334 | * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. | ||
335 | * @param pV the fixed value of pattern parameter v, or null if not bound. | ||
336 | * @return the number of pattern matches found. | ||
337 | * | ||
338 | */ | ||
339 | public int countMatches(final Synchronization pV) { | ||
340 | return rawCountMatches(new Object[]{pV}); | ||
341 | } | ||
342 | |||
343 | /** | ||
344 | * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
345 | * Neither determinism nor randomness of selection is guaranteed. | ||
346 | * @param pV the fixed value of pattern parameter v, or null if not bound. | ||
347 | * @param processor the action that will process the selected match. | ||
348 | * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked | ||
349 | * | ||
350 | */ | ||
351 | public boolean forOneArbitraryMatch(final Synchronization pV, final Consumer<? super HasMultipleIncomingTrainsition.Match> processor) { | ||
352 | return rawForOneArbitraryMatch(new Object[]{pV}, processor); | ||
353 | } | ||
354 | |||
355 | /** | ||
356 | * Returns a new (partial) match. | ||
357 | * This can be used e.g. to call the matcher with a partial match. | ||
358 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
359 | * @param pV the fixed value of pattern parameter v, or null if not bound. | ||
360 | * @return the (partial) match object. | ||
361 | * | ||
362 | */ | ||
363 | public HasMultipleIncomingTrainsition.Match newMatch(final Synchronization pV) { | ||
364 | return HasMultipleIncomingTrainsition.Match.newMatch(pV); | ||
365 | } | ||
366 | |||
367 | /** | ||
368 | * Retrieve the set of values that occur in matches for v. | ||
369 | * @return the Set of all values or empty set if there are no matches | ||
370 | * | ||
371 | */ | ||
372 | protected Stream<Synchronization> rawStreamAllValuesOfv(final Object[] parameters) { | ||
373 | return rawStreamAllValues(POSITION_V, parameters).map(Synchronization.class::cast); | ||
374 | } | ||
375 | |||
376 | /** | ||
377 | * Retrieve the set of values that occur in matches for v. | ||
378 | * @return the Set of all values or empty set if there are no matches | ||
379 | * | ||
380 | */ | ||
381 | public Set<Synchronization> getAllValuesOfv() { | ||
382 | return rawStreamAllValuesOfv(emptyArray()).collect(Collectors.toSet()); | ||
383 | } | ||
384 | |||
385 | /** | ||
386 | * Retrieve the set of values that occur in matches for v. | ||
387 | * @return the Set of all values or empty set if there are no matches | ||
388 | * | ||
389 | */ | ||
390 | public Stream<Synchronization> streamAllValuesOfv() { | ||
391 | return rawStreamAllValuesOfv(emptyArray()); | ||
392 | } | ||
393 | |||
394 | @Override | ||
395 | protected HasMultipleIncomingTrainsition.Match tupleToMatch(final Tuple t) { | ||
396 | try { | ||
397 | return HasMultipleIncomingTrainsition.Match.newMatch((Synchronization) t.get(POSITION_V)); | ||
398 | } catch(ClassCastException e) { | ||
399 | LOGGER.error("Element(s) in tuple not properly typed!",e); | ||
400 | return null; | ||
401 | } | ||
402 | } | ||
403 | |||
404 | @Override | ||
405 | protected HasMultipleIncomingTrainsition.Match arrayToMatch(final Object[] match) { | ||
406 | try { | ||
407 | return HasMultipleIncomingTrainsition.Match.newMatch((Synchronization) match[POSITION_V]); | ||
408 | } catch(ClassCastException e) { | ||
409 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
410 | return null; | ||
411 | } | ||
412 | } | ||
413 | |||
414 | @Override | ||
415 | protected HasMultipleIncomingTrainsition.Match arrayToMatchMutable(final Object[] match) { | ||
416 | try { | ||
417 | return HasMultipleIncomingTrainsition.Match.newMutableMatch((Synchronization) match[POSITION_V]); | ||
418 | } catch(ClassCastException e) { | ||
419 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
420 | return null; | ||
421 | } | ||
422 | } | ||
423 | |||
424 | /** | ||
425 | * @return the singleton instance of the query specification of this pattern | ||
426 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
427 | * | ||
428 | */ | ||
429 | public static IQuerySpecification<HasMultipleIncomingTrainsition.Matcher> querySpecification() { | ||
430 | return HasMultipleIncomingTrainsition.instance(); | ||
431 | } | ||
432 | } | ||
433 | |||
434 | private HasMultipleIncomingTrainsition() { | ||
435 | super(GeneratedPQuery.INSTANCE); | ||
436 | } | ||
437 | |||
438 | /** | ||
439 | * @return the singleton instance of the query specification | ||
440 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
441 | * | ||
442 | */ | ||
443 | public static HasMultipleIncomingTrainsition instance() { | ||
444 | try{ | ||
445 | return LazyHolder.INSTANCE; | ||
446 | } catch (ExceptionInInitializerError err) { | ||
447 | throw processInitializerError(err); | ||
448 | } | ||
449 | } | ||
450 | |||
451 | @Override | ||
452 | protected HasMultipleIncomingTrainsition.Matcher instantiate(final ViatraQueryEngine engine) { | ||
453 | return HasMultipleIncomingTrainsition.Matcher.on(engine); | ||
454 | } | ||
455 | |||
456 | @Override | ||
457 | public HasMultipleIncomingTrainsition.Matcher instantiate() { | ||
458 | return HasMultipleIncomingTrainsition.Matcher.create(); | ||
459 | } | ||
460 | |||
461 | @Override | ||
462 | public HasMultipleIncomingTrainsition.Match newEmptyMatch() { | ||
463 | return HasMultipleIncomingTrainsition.Match.newEmptyMatch(); | ||
464 | } | ||
465 | |||
466 | @Override | ||
467 | public HasMultipleIncomingTrainsition.Match newMatch(final Object... parameters) { | ||
468 | return HasMultipleIncomingTrainsition.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization) parameters[0]); | ||
469 | } | ||
470 | |||
471 | /** | ||
472 | * Inner class allowing the singleton instance of {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.HasMultipleIncomingTrainsition (visibility: PUBLIC, simpleName: HasMultipleIncomingTrainsition, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.HasMultipleIncomingTrainsition, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created | ||
473 | * <b>not</b> at the class load time of the outer class, | ||
474 | * but rather at the first call to {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.HasMultipleIncomingTrainsition (visibility: PUBLIC, simpleName: HasMultipleIncomingTrainsition, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.HasMultipleIncomingTrainsition, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. | ||
475 | * | ||
476 | * <p> This workaround is required e.g. to support recursion. | ||
477 | * | ||
478 | */ | ||
479 | private static class LazyHolder { | ||
480 | private final static HasMultipleIncomingTrainsition INSTANCE = new HasMultipleIncomingTrainsition(); | ||
481 | |||
482 | /** | ||
483 | * Statically initializes the query specification <b>after</b> the field {@link #INSTANCE} is assigned. | ||
484 | * This initialization order is required to support indirect recursion. | ||
485 | * | ||
486 | * <p> The static initializer is defined using a helper field to work around limitations of the code generator. | ||
487 | * | ||
488 | */ | ||
489 | private final static Object STATIC_INITIALIZER = ensureInitialized(); | ||
490 | |||
491 | public static Object ensureInitialized() { | ||
492 | INSTANCE.ensureInitializedInternal(); | ||
493 | return null; | ||
494 | } | ||
495 | } | ||
496 | |||
497 | private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { | ||
498 | private final static HasMultipleIncomingTrainsition.GeneratedPQuery INSTANCE = new GeneratedPQuery(); | ||
499 | |||
500 | private final PParameter parameter_v = new PParameter("v", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Synchronization")), PParameterDirection.INOUT); | ||
501 | |||
502 | private final List<PParameter> parameters = Arrays.asList(parameter_v); | ||
503 | |||
504 | private GeneratedPQuery() { | ||
505 | super(PVisibility.PUBLIC); | ||
506 | } | ||
507 | |||
508 | @Override | ||
509 | public String getFullyQualifiedName() { | ||
510 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.hasMultipleIncomingTrainsition"; | ||
511 | } | ||
512 | |||
513 | @Override | ||
514 | public List<String> getParameterNames() { | ||
515 | return Arrays.asList("v"); | ||
516 | } | ||
517 | |||
518 | @Override | ||
519 | public List<PParameter> getParameters() { | ||
520 | return parameters; | ||
521 | } | ||
522 | |||
523 | @Override | ||
524 | public Set<PBody> doGetContainedBodies() { | ||
525 | setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); | ||
526 | Set<PBody> bodies = new LinkedHashSet<>(); | ||
527 | { | ||
528 | PBody body = new PBody(this); | ||
529 | PVariable var_v = body.getOrCreateVariableByName("v"); | ||
530 | PVariable var___0_ = body.getOrCreateVariableByName("_<0>"); | ||
531 | PVariable var_src1 = body.getOrCreateVariableByName("src1"); | ||
532 | PVariable var___1_ = body.getOrCreateVariableByName("_<1>"); | ||
533 | PVariable var_src2 = body.getOrCreateVariableByName("src2"); | ||
534 | new TypeConstraint(body, Tuples.flatTupleOf(var_v), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Synchronization"))); | ||
535 | body.setSymbolicParameters(Arrays.<ExportedParameter>asList( | ||
536 | new ExportedParameter(body, var_v, parameter_v) | ||
537 | )); | ||
538 | // find transition(_, src1, v) | ||
539 | new PositivePatternCall(body, Tuples.flatTupleOf(var___0_, var_src1, var_v), Transition.instance().getInternalQueryRepresentation()); | ||
540 | // find transition(_, src2, v) | ||
541 | new PositivePatternCall(body, Tuples.flatTupleOf(var___1_, var_src2, var_v), Transition.instance().getInternalQueryRepresentation()); | ||
542 | // src1 != src2 | ||
543 | new Inequality(body, var_src1, var_src2); | ||
544 | bodies.add(body); | ||
545 | } | ||
546 | return bodies; | ||
547 | } | ||
548 | } | ||
549 | } | ||
diff --git a/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/HasMultipleOutgoingTrainsition.java b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/HasMultipleOutgoingTrainsition.java new file mode 100644 index 00000000..115b93e1 --- /dev/null +++ b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/HasMultipleOutgoingTrainsition.java | |||
@@ -0,0 +1,549 @@ | |||
1 | /** | ||
2 | * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql | ||
3 | */ | ||
4 | package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; | ||
5 | |||
6 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization; | ||
7 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.Transition; | ||
8 | import java.util.Arrays; | ||
9 | import java.util.Collection; | ||
10 | import java.util.LinkedHashSet; | ||
11 | import java.util.List; | ||
12 | import java.util.Objects; | ||
13 | import java.util.Optional; | ||
14 | import java.util.Set; | ||
15 | import java.util.function.Consumer; | ||
16 | import java.util.stream.Collectors; | ||
17 | import java.util.stream.Stream; | ||
18 | import org.apache.log4j.Logger; | ||
19 | import org.eclipse.emf.ecore.EClass; | ||
20 | import org.eclipse.viatra.query.runtime.api.IPatternMatch; | ||
21 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification; | ||
22 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; | ||
23 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; | ||
24 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; | ||
25 | import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; | ||
26 | import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; | ||
27 | import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; | ||
28 | import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; | ||
29 | import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; | ||
30 | import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; | ||
31 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; | ||
32 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Inequality; | ||
33 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall; | ||
34 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; | ||
35 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; | ||
36 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; | ||
37 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; | ||
38 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; | ||
39 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | ||
40 | import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; | ||
41 | |||
42 | /** | ||
43 | * A pattern-specific query specification that can instantiate Matcher in a type-safe way. | ||
44 | * | ||
45 | * <p>Original source: | ||
46 | * <code><pre> | ||
47 | * pattern hasMultipleOutgoingTrainsition(v : Synchronization) { | ||
48 | * find transition(_, v, trg1); | ||
49 | * find transition(_, v, trg2); | ||
50 | * trg1 != trg2; | ||
51 | * } | ||
52 | * </pre></code> | ||
53 | * | ||
54 | * @see Matcher | ||
55 | * @see Match | ||
56 | * | ||
57 | */ | ||
58 | @SuppressWarnings("all") | ||
59 | public final class HasMultipleOutgoingTrainsition extends BaseGeneratedEMFQuerySpecification<HasMultipleOutgoingTrainsition.Matcher> { | ||
60 | /** | ||
61 | * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.hasMultipleOutgoingTrainsition pattern, | ||
62 | * to be used in conjunction with {@link Matcher}. | ||
63 | * | ||
64 | * <p>Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. | ||
65 | * Each instance is a (possibly partial) substitution of pattern parameters, | ||
66 | * usable to represent a match of the pattern in the result of a query, | ||
67 | * or to specify the bound (fixed) input parameters when issuing a query. | ||
68 | * | ||
69 | * @see Matcher | ||
70 | * | ||
71 | */ | ||
72 | public static abstract class Match extends BasePatternMatch { | ||
73 | private Synchronization fV; | ||
74 | |||
75 | private static List<String> parameterNames = makeImmutableList("v"); | ||
76 | |||
77 | private Match(final Synchronization pV) { | ||
78 | this.fV = pV; | ||
79 | } | ||
80 | |||
81 | @Override | ||
82 | public Object get(final String parameterName) { | ||
83 | if ("v".equals(parameterName)) return this.fV; | ||
84 | return null; | ||
85 | } | ||
86 | |||
87 | public Synchronization getV() { | ||
88 | return this.fV; | ||
89 | } | ||
90 | |||
91 | @Override | ||
92 | public boolean set(final String parameterName, final Object newValue) { | ||
93 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
94 | if ("v".equals(parameterName) ) { | ||
95 | this.fV = (Synchronization) newValue; | ||
96 | return true; | ||
97 | } | ||
98 | return false; | ||
99 | } | ||
100 | |||
101 | public void setV(final Synchronization pV) { | ||
102 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
103 | this.fV = pV; | ||
104 | } | ||
105 | |||
106 | @Override | ||
107 | public String patternName() { | ||
108 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.hasMultipleOutgoingTrainsition"; | ||
109 | } | ||
110 | |||
111 | @Override | ||
112 | public List<String> parameterNames() { | ||
113 | return HasMultipleOutgoingTrainsition.Match.parameterNames; | ||
114 | } | ||
115 | |||
116 | @Override | ||
117 | public Object[] toArray() { | ||
118 | return new Object[]{fV}; | ||
119 | } | ||
120 | |||
121 | @Override | ||
122 | public HasMultipleOutgoingTrainsition.Match toImmutable() { | ||
123 | return isMutable() ? newMatch(fV) : this; | ||
124 | } | ||
125 | |||
126 | @Override | ||
127 | public String prettyPrint() { | ||
128 | StringBuilder result = new StringBuilder(); | ||
129 | result.append("\"v\"=" + prettyPrintValue(fV)); | ||
130 | return result.toString(); | ||
131 | } | ||
132 | |||
133 | @Override | ||
134 | public int hashCode() { | ||
135 | return Objects.hash(fV); | ||
136 | } | ||
137 | |||
138 | @Override | ||
139 | public boolean equals(final Object obj) { | ||
140 | if (this == obj) | ||
141 | return true; | ||
142 | if (obj == null) { | ||
143 | return false; | ||
144 | } | ||
145 | if ((obj instanceof HasMultipleOutgoingTrainsition.Match)) { | ||
146 | HasMultipleOutgoingTrainsition.Match other = (HasMultipleOutgoingTrainsition.Match) obj; | ||
147 | return Objects.equals(fV, other.fV); | ||
148 | } else { | ||
149 | // this should be infrequent | ||
150 | if (!(obj instanceof IPatternMatch)) { | ||
151 | return false; | ||
152 | } | ||
153 | IPatternMatch otherSig = (IPatternMatch) obj; | ||
154 | return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); | ||
155 | } | ||
156 | } | ||
157 | |||
158 | @Override | ||
159 | public HasMultipleOutgoingTrainsition specification() { | ||
160 | return HasMultipleOutgoingTrainsition.instance(); | ||
161 | } | ||
162 | |||
163 | /** | ||
164 | * Returns an empty, mutable match. | ||
165 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
166 | * | ||
167 | * @return the empty match. | ||
168 | * | ||
169 | */ | ||
170 | public static HasMultipleOutgoingTrainsition.Match newEmptyMatch() { | ||
171 | return new Mutable(null); | ||
172 | } | ||
173 | |||
174 | /** | ||
175 | * Returns a mutable (partial) match. | ||
176 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
177 | * | ||
178 | * @param pV the fixed value of pattern parameter v, or null if not bound. | ||
179 | * @return the new, mutable (partial) match object. | ||
180 | * | ||
181 | */ | ||
182 | public static HasMultipleOutgoingTrainsition.Match newMutableMatch(final Synchronization pV) { | ||
183 | return new Mutable(pV); | ||
184 | } | ||
185 | |||
186 | /** | ||
187 | * Returns a new (partial) match. | ||
188 | * This can be used e.g. to call the matcher with a partial match. | ||
189 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
190 | * @param pV the fixed value of pattern parameter v, or null if not bound. | ||
191 | * @return the (partial) match object. | ||
192 | * | ||
193 | */ | ||
194 | public static HasMultipleOutgoingTrainsition.Match newMatch(final Synchronization pV) { | ||
195 | return new Immutable(pV); | ||
196 | } | ||
197 | |||
198 | private static final class Mutable extends HasMultipleOutgoingTrainsition.Match { | ||
199 | Mutable(final Synchronization pV) { | ||
200 | super(pV); | ||
201 | } | ||
202 | |||
203 | @Override | ||
204 | public boolean isMutable() { | ||
205 | return true; | ||
206 | } | ||
207 | } | ||
208 | |||
209 | private static final class Immutable extends HasMultipleOutgoingTrainsition.Match { | ||
210 | Immutable(final Synchronization pV) { | ||
211 | super(pV); | ||
212 | } | ||
213 | |||
214 | @Override | ||
215 | public boolean isMutable() { | ||
216 | return false; | ||
217 | } | ||
218 | } | ||
219 | } | ||
220 | |||
221 | /** | ||
222 | * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.hasMultipleOutgoingTrainsition pattern, | ||
223 | * providing pattern-specific query methods. | ||
224 | * | ||
225 | * <p>Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, | ||
226 | * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. | ||
227 | * | ||
228 | * <p>Matches of the pattern will be represented as {@link Match}. | ||
229 | * | ||
230 | * <p>Original source: | ||
231 | * <code><pre> | ||
232 | * pattern hasMultipleOutgoingTrainsition(v : Synchronization) { | ||
233 | * find transition(_, v, trg1); | ||
234 | * find transition(_, v, trg2); | ||
235 | * trg1 != trg2; | ||
236 | * } | ||
237 | * </pre></code> | ||
238 | * | ||
239 | * @see Match | ||
240 | * @see HasMultipleOutgoingTrainsition | ||
241 | * | ||
242 | */ | ||
243 | public static class Matcher extends BaseMatcher<HasMultipleOutgoingTrainsition.Match> { | ||
244 | /** | ||
245 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
246 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
247 | * | ||
248 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
249 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
250 | * | ||
251 | */ | ||
252 | public static HasMultipleOutgoingTrainsition.Matcher on(final ViatraQueryEngine engine) { | ||
253 | // check if matcher already exists | ||
254 | Matcher matcher = engine.getExistingMatcher(querySpecification()); | ||
255 | if (matcher == null) { | ||
256 | matcher = (Matcher)engine.getMatcher(querySpecification()); | ||
257 | } | ||
258 | return matcher; | ||
259 | } | ||
260 | |||
261 | /** | ||
262 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
263 | * @return an initialized matcher | ||
264 | * @noreference This method is for internal matcher initialization by the framework, do not call it manually. | ||
265 | * | ||
266 | */ | ||
267 | public static HasMultipleOutgoingTrainsition.Matcher create() { | ||
268 | return new Matcher(); | ||
269 | } | ||
270 | |||
271 | private final static int POSITION_V = 0; | ||
272 | |||
273 | private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(HasMultipleOutgoingTrainsition.Matcher.class); | ||
274 | |||
275 | /** | ||
276 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
277 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
278 | * | ||
279 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
280 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
281 | * | ||
282 | */ | ||
283 | private Matcher() { | ||
284 | super(querySpecification()); | ||
285 | } | ||
286 | |||
287 | /** | ||
288 | * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. | ||
289 | * @param pV the fixed value of pattern parameter v, or null if not bound. | ||
290 | * @return matches represented as a Match object. | ||
291 | * | ||
292 | */ | ||
293 | public Collection<HasMultipleOutgoingTrainsition.Match> getAllMatches(final Synchronization pV) { | ||
294 | return rawStreamAllMatches(new Object[]{pV}).collect(Collectors.toSet()); | ||
295 | } | ||
296 | |||
297 | /** | ||
298 | * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. | ||
299 | * </p> | ||
300 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
301 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
302 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
303 | * @param pV the fixed value of pattern parameter v, or null if not bound. | ||
304 | * @return a stream of matches represented as a Match object. | ||
305 | * | ||
306 | */ | ||
307 | public Stream<HasMultipleOutgoingTrainsition.Match> streamAllMatches(final Synchronization pV) { | ||
308 | return rawStreamAllMatches(new Object[]{pV}); | ||
309 | } | ||
310 | |||
311 | /** | ||
312 | * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
313 | * Neither determinism nor randomness of selection is guaranteed. | ||
314 | * @param pV the fixed value of pattern parameter v, or null if not bound. | ||
315 | * @return a match represented as a Match object, or null if no match is found. | ||
316 | * | ||
317 | */ | ||
318 | public Optional<HasMultipleOutgoingTrainsition.Match> getOneArbitraryMatch(final Synchronization pV) { | ||
319 | return rawGetOneArbitraryMatch(new Object[]{pV}); | ||
320 | } | ||
321 | |||
322 | /** | ||
323 | * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, | ||
324 | * under any possible substitution of the unspecified parameters (if any). | ||
325 | * @param pV the fixed value of pattern parameter v, or null if not bound. | ||
326 | * @return true if the input is a valid (partial) match of the pattern. | ||
327 | * | ||
328 | */ | ||
329 | public boolean hasMatch(final Synchronization pV) { | ||
330 | return rawHasMatch(new Object[]{pV}); | ||
331 | } | ||
332 | |||
333 | /** | ||
334 | * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. | ||
335 | * @param pV the fixed value of pattern parameter v, or null if not bound. | ||
336 | * @return the number of pattern matches found. | ||
337 | * | ||
338 | */ | ||
339 | public int countMatches(final Synchronization pV) { | ||
340 | return rawCountMatches(new Object[]{pV}); | ||
341 | } | ||
342 | |||
343 | /** | ||
344 | * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
345 | * Neither determinism nor randomness of selection is guaranteed. | ||
346 | * @param pV the fixed value of pattern parameter v, or null if not bound. | ||
347 | * @param processor the action that will process the selected match. | ||
348 | * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked | ||
349 | * | ||
350 | */ | ||
351 | public boolean forOneArbitraryMatch(final Synchronization pV, final Consumer<? super HasMultipleOutgoingTrainsition.Match> processor) { | ||
352 | return rawForOneArbitraryMatch(new Object[]{pV}, processor); | ||
353 | } | ||
354 | |||
355 | /** | ||
356 | * Returns a new (partial) match. | ||
357 | * This can be used e.g. to call the matcher with a partial match. | ||
358 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
359 | * @param pV the fixed value of pattern parameter v, or null if not bound. | ||
360 | * @return the (partial) match object. | ||
361 | * | ||
362 | */ | ||
363 | public HasMultipleOutgoingTrainsition.Match newMatch(final Synchronization pV) { | ||
364 | return HasMultipleOutgoingTrainsition.Match.newMatch(pV); | ||
365 | } | ||
366 | |||
367 | /** | ||
368 | * Retrieve the set of values that occur in matches for v. | ||
369 | * @return the Set of all values or empty set if there are no matches | ||
370 | * | ||
371 | */ | ||
372 | protected Stream<Synchronization> rawStreamAllValuesOfv(final Object[] parameters) { | ||
373 | return rawStreamAllValues(POSITION_V, parameters).map(Synchronization.class::cast); | ||
374 | } | ||
375 | |||
376 | /** | ||
377 | * Retrieve the set of values that occur in matches for v. | ||
378 | * @return the Set of all values or empty set if there are no matches | ||
379 | * | ||
380 | */ | ||
381 | public Set<Synchronization> getAllValuesOfv() { | ||
382 | return rawStreamAllValuesOfv(emptyArray()).collect(Collectors.toSet()); | ||
383 | } | ||
384 | |||
385 | /** | ||
386 | * Retrieve the set of values that occur in matches for v. | ||
387 | * @return the Set of all values or empty set if there are no matches | ||
388 | * | ||
389 | */ | ||
390 | public Stream<Synchronization> streamAllValuesOfv() { | ||
391 | return rawStreamAllValuesOfv(emptyArray()); | ||
392 | } | ||
393 | |||
394 | @Override | ||
395 | protected HasMultipleOutgoingTrainsition.Match tupleToMatch(final Tuple t) { | ||
396 | try { | ||
397 | return HasMultipleOutgoingTrainsition.Match.newMatch((Synchronization) t.get(POSITION_V)); | ||
398 | } catch(ClassCastException e) { | ||
399 | LOGGER.error("Element(s) in tuple not properly typed!",e); | ||
400 | return null; | ||
401 | } | ||
402 | } | ||
403 | |||
404 | @Override | ||
405 | protected HasMultipleOutgoingTrainsition.Match arrayToMatch(final Object[] match) { | ||
406 | try { | ||
407 | return HasMultipleOutgoingTrainsition.Match.newMatch((Synchronization) match[POSITION_V]); | ||
408 | } catch(ClassCastException e) { | ||
409 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
410 | return null; | ||
411 | } | ||
412 | } | ||
413 | |||
414 | @Override | ||
415 | protected HasMultipleOutgoingTrainsition.Match arrayToMatchMutable(final Object[] match) { | ||
416 | try { | ||
417 | return HasMultipleOutgoingTrainsition.Match.newMutableMatch((Synchronization) match[POSITION_V]); | ||
418 | } catch(ClassCastException e) { | ||
419 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
420 | return null; | ||
421 | } | ||
422 | } | ||
423 | |||
424 | /** | ||
425 | * @return the singleton instance of the query specification of this pattern | ||
426 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
427 | * | ||
428 | */ | ||
429 | public static IQuerySpecification<HasMultipleOutgoingTrainsition.Matcher> querySpecification() { | ||
430 | return HasMultipleOutgoingTrainsition.instance(); | ||
431 | } | ||
432 | } | ||
433 | |||
434 | private HasMultipleOutgoingTrainsition() { | ||
435 | super(GeneratedPQuery.INSTANCE); | ||
436 | } | ||
437 | |||
438 | /** | ||
439 | * @return the singleton instance of the query specification | ||
440 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
441 | * | ||
442 | */ | ||
443 | public static HasMultipleOutgoingTrainsition instance() { | ||
444 | try{ | ||
445 | return LazyHolder.INSTANCE; | ||
446 | } catch (ExceptionInInitializerError err) { | ||
447 | throw processInitializerError(err); | ||
448 | } | ||
449 | } | ||
450 | |||
451 | @Override | ||
452 | protected HasMultipleOutgoingTrainsition.Matcher instantiate(final ViatraQueryEngine engine) { | ||
453 | return HasMultipleOutgoingTrainsition.Matcher.on(engine); | ||
454 | } | ||
455 | |||
456 | @Override | ||
457 | public HasMultipleOutgoingTrainsition.Matcher instantiate() { | ||
458 | return HasMultipleOutgoingTrainsition.Matcher.create(); | ||
459 | } | ||
460 | |||
461 | @Override | ||
462 | public HasMultipleOutgoingTrainsition.Match newEmptyMatch() { | ||
463 | return HasMultipleOutgoingTrainsition.Match.newEmptyMatch(); | ||
464 | } | ||
465 | |||
466 | @Override | ||
467 | public HasMultipleOutgoingTrainsition.Match newMatch(final Object... parameters) { | ||
468 | return HasMultipleOutgoingTrainsition.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization) parameters[0]); | ||
469 | } | ||
470 | |||
471 | /** | ||
472 | * Inner class allowing the singleton instance of {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.HasMultipleOutgoingTrainsition (visibility: PUBLIC, simpleName: HasMultipleOutgoingTrainsition, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.HasMultipleOutgoingTrainsition, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created | ||
473 | * <b>not</b> at the class load time of the outer class, | ||
474 | * but rather at the first call to {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.HasMultipleOutgoingTrainsition (visibility: PUBLIC, simpleName: HasMultipleOutgoingTrainsition, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.HasMultipleOutgoingTrainsition, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. | ||
475 | * | ||
476 | * <p> This workaround is required e.g. to support recursion. | ||
477 | * | ||
478 | */ | ||
479 | private static class LazyHolder { | ||
480 | private final static HasMultipleOutgoingTrainsition INSTANCE = new HasMultipleOutgoingTrainsition(); | ||
481 | |||
482 | /** | ||
483 | * Statically initializes the query specification <b>after</b> the field {@link #INSTANCE} is assigned. | ||
484 | * This initialization order is required to support indirect recursion. | ||
485 | * | ||
486 | * <p> The static initializer is defined using a helper field to work around limitations of the code generator. | ||
487 | * | ||
488 | */ | ||
489 | private final static Object STATIC_INITIALIZER = ensureInitialized(); | ||
490 | |||
491 | public static Object ensureInitialized() { | ||
492 | INSTANCE.ensureInitializedInternal(); | ||
493 | return null; | ||
494 | } | ||
495 | } | ||
496 | |||
497 | private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { | ||
498 | private final static HasMultipleOutgoingTrainsition.GeneratedPQuery INSTANCE = new GeneratedPQuery(); | ||
499 | |||
500 | private final PParameter parameter_v = new PParameter("v", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Synchronization")), PParameterDirection.INOUT); | ||
501 | |||
502 | private final List<PParameter> parameters = Arrays.asList(parameter_v); | ||
503 | |||
504 | private GeneratedPQuery() { | ||
505 | super(PVisibility.PUBLIC); | ||
506 | } | ||
507 | |||
508 | @Override | ||
509 | public String getFullyQualifiedName() { | ||
510 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.hasMultipleOutgoingTrainsition"; | ||
511 | } | ||
512 | |||
513 | @Override | ||
514 | public List<String> getParameterNames() { | ||
515 | return Arrays.asList("v"); | ||
516 | } | ||
517 | |||
518 | @Override | ||
519 | public List<PParameter> getParameters() { | ||
520 | return parameters; | ||
521 | } | ||
522 | |||
523 | @Override | ||
524 | public Set<PBody> doGetContainedBodies() { | ||
525 | setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); | ||
526 | Set<PBody> bodies = new LinkedHashSet<>(); | ||
527 | { | ||
528 | PBody body = new PBody(this); | ||
529 | PVariable var_v = body.getOrCreateVariableByName("v"); | ||
530 | PVariable var___0_ = body.getOrCreateVariableByName("_<0>"); | ||
531 | PVariable var_trg1 = body.getOrCreateVariableByName("trg1"); | ||
532 | PVariable var___1_ = body.getOrCreateVariableByName("_<1>"); | ||
533 | PVariable var_trg2 = body.getOrCreateVariableByName("trg2"); | ||
534 | new TypeConstraint(body, Tuples.flatTupleOf(var_v), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Synchronization"))); | ||
535 | body.setSymbolicParameters(Arrays.<ExportedParameter>asList( | ||
536 | new ExportedParameter(body, var_v, parameter_v) | ||
537 | )); | ||
538 | // find transition(_, v, trg1) | ||
539 | new PositivePatternCall(body, Tuples.flatTupleOf(var___0_, var_v, var_trg1), Transition.instance().getInternalQueryRepresentation()); | ||
540 | // find transition(_, v, trg2) | ||
541 | new PositivePatternCall(body, Tuples.flatTupleOf(var___1_, var_v, var_trg2), Transition.instance().getInternalQueryRepresentation()); | ||
542 | // trg1 != trg2 | ||
543 | new Inequality(body, var_trg1, var_trg2); | ||
544 | bodies.add(body); | ||
545 | } | ||
546 | return bodies; | ||
547 | } | ||
548 | } | ||
549 | } | ||
diff --git a/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/HasMultipleRegions.java b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/HasMultipleRegions.java new file mode 100644 index 00000000..5542ccbb --- /dev/null +++ b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/HasMultipleRegions.java | |||
@@ -0,0 +1,555 @@ | |||
1 | /** | ||
2 | * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql | ||
3 | */ | ||
4 | package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; | ||
5 | |||
6 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.CompositeElement; | ||
7 | import java.util.Arrays; | ||
8 | import java.util.Collection; | ||
9 | import java.util.LinkedHashSet; | ||
10 | import java.util.List; | ||
11 | import java.util.Objects; | ||
12 | import java.util.Optional; | ||
13 | import java.util.Set; | ||
14 | import java.util.function.Consumer; | ||
15 | import java.util.stream.Collectors; | ||
16 | import java.util.stream.Stream; | ||
17 | import org.apache.log4j.Logger; | ||
18 | import org.eclipse.emf.ecore.EClass; | ||
19 | import org.eclipse.viatra.query.runtime.api.IPatternMatch; | ||
20 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification; | ||
21 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; | ||
22 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; | ||
23 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; | ||
24 | import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; | ||
25 | import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; | ||
26 | import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; | ||
27 | import org.eclipse.viatra.query.runtime.emf.types.EStructuralFeatureInstancesKey; | ||
28 | import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; | ||
29 | import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; | ||
30 | import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; | ||
31 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality; | ||
32 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; | ||
33 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Inequality; | ||
34 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; | ||
35 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; | ||
36 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; | ||
37 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; | ||
38 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; | ||
39 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | ||
40 | import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; | ||
41 | |||
42 | /** | ||
43 | * A pattern-specific query specification that can instantiate Matcher in a type-safe way. | ||
44 | * | ||
45 | * <p>Original source: | ||
46 | * <code><pre> | ||
47 | * pattern hasMultipleRegions(composite: CompositeElement) { | ||
48 | * CompositeElement.regions(composite,region1); | ||
49 | * CompositeElement.regions(composite,region2); | ||
50 | * region1 != region2; | ||
51 | * } | ||
52 | * </pre></code> | ||
53 | * | ||
54 | * @see Matcher | ||
55 | * @see Match | ||
56 | * | ||
57 | */ | ||
58 | @SuppressWarnings("all") | ||
59 | public final class HasMultipleRegions extends BaseGeneratedEMFQuerySpecification<HasMultipleRegions.Matcher> { | ||
60 | /** | ||
61 | * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.hasMultipleRegions pattern, | ||
62 | * to be used in conjunction with {@link Matcher}. | ||
63 | * | ||
64 | * <p>Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. | ||
65 | * Each instance is a (possibly partial) substitution of pattern parameters, | ||
66 | * usable to represent a match of the pattern in the result of a query, | ||
67 | * or to specify the bound (fixed) input parameters when issuing a query. | ||
68 | * | ||
69 | * @see Matcher | ||
70 | * | ||
71 | */ | ||
72 | public static abstract class Match extends BasePatternMatch { | ||
73 | private CompositeElement fComposite; | ||
74 | |||
75 | private static List<String> parameterNames = makeImmutableList("composite"); | ||
76 | |||
77 | private Match(final CompositeElement pComposite) { | ||
78 | this.fComposite = pComposite; | ||
79 | } | ||
80 | |||
81 | @Override | ||
82 | public Object get(final String parameterName) { | ||
83 | if ("composite".equals(parameterName)) return this.fComposite; | ||
84 | return null; | ||
85 | } | ||
86 | |||
87 | public CompositeElement getComposite() { | ||
88 | return this.fComposite; | ||
89 | } | ||
90 | |||
91 | @Override | ||
92 | public boolean set(final String parameterName, final Object newValue) { | ||
93 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
94 | if ("composite".equals(parameterName) ) { | ||
95 | this.fComposite = (CompositeElement) newValue; | ||
96 | return true; | ||
97 | } | ||
98 | return false; | ||
99 | } | ||
100 | |||
101 | public void setComposite(final CompositeElement pComposite) { | ||
102 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
103 | this.fComposite = pComposite; | ||
104 | } | ||
105 | |||
106 | @Override | ||
107 | public String patternName() { | ||
108 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.hasMultipleRegions"; | ||
109 | } | ||
110 | |||
111 | @Override | ||
112 | public List<String> parameterNames() { | ||
113 | return HasMultipleRegions.Match.parameterNames; | ||
114 | } | ||
115 | |||
116 | @Override | ||
117 | public Object[] toArray() { | ||
118 | return new Object[]{fComposite}; | ||
119 | } | ||
120 | |||
121 | @Override | ||
122 | public HasMultipleRegions.Match toImmutable() { | ||
123 | return isMutable() ? newMatch(fComposite) : this; | ||
124 | } | ||
125 | |||
126 | @Override | ||
127 | public String prettyPrint() { | ||
128 | StringBuilder result = new StringBuilder(); | ||
129 | result.append("\"composite\"=" + prettyPrintValue(fComposite)); | ||
130 | return result.toString(); | ||
131 | } | ||
132 | |||
133 | @Override | ||
134 | public int hashCode() { | ||
135 | return Objects.hash(fComposite); | ||
136 | } | ||
137 | |||
138 | @Override | ||
139 | public boolean equals(final Object obj) { | ||
140 | if (this == obj) | ||
141 | return true; | ||
142 | if (obj == null) { | ||
143 | return false; | ||
144 | } | ||
145 | if ((obj instanceof HasMultipleRegions.Match)) { | ||
146 | HasMultipleRegions.Match other = (HasMultipleRegions.Match) obj; | ||
147 | return Objects.equals(fComposite, other.fComposite); | ||
148 | } else { | ||
149 | // this should be infrequent | ||
150 | if (!(obj instanceof IPatternMatch)) { | ||
151 | return false; | ||
152 | } | ||
153 | IPatternMatch otherSig = (IPatternMatch) obj; | ||
154 | return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); | ||
155 | } | ||
156 | } | ||
157 | |||
158 | @Override | ||
159 | public HasMultipleRegions specification() { | ||
160 | return HasMultipleRegions.instance(); | ||
161 | } | ||
162 | |||
163 | /** | ||
164 | * Returns an empty, mutable match. | ||
165 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
166 | * | ||
167 | * @return the empty match. | ||
168 | * | ||
169 | */ | ||
170 | public static HasMultipleRegions.Match newEmptyMatch() { | ||
171 | return new Mutable(null); | ||
172 | } | ||
173 | |||
174 | /** | ||
175 | * Returns a mutable (partial) match. | ||
176 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
177 | * | ||
178 | * @param pComposite the fixed value of pattern parameter composite, or null if not bound. | ||
179 | * @return the new, mutable (partial) match object. | ||
180 | * | ||
181 | */ | ||
182 | public static HasMultipleRegions.Match newMutableMatch(final CompositeElement pComposite) { | ||
183 | return new Mutable(pComposite); | ||
184 | } | ||
185 | |||
186 | /** | ||
187 | * Returns a new (partial) match. | ||
188 | * This can be used e.g. to call the matcher with a partial match. | ||
189 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
190 | * @param pComposite the fixed value of pattern parameter composite, or null if not bound. | ||
191 | * @return the (partial) match object. | ||
192 | * | ||
193 | */ | ||
194 | public static HasMultipleRegions.Match newMatch(final CompositeElement pComposite) { | ||
195 | return new Immutable(pComposite); | ||
196 | } | ||
197 | |||
198 | private static final class Mutable extends HasMultipleRegions.Match { | ||
199 | Mutable(final CompositeElement pComposite) { | ||
200 | super(pComposite); | ||
201 | } | ||
202 | |||
203 | @Override | ||
204 | public boolean isMutable() { | ||
205 | return true; | ||
206 | } | ||
207 | } | ||
208 | |||
209 | private static final class Immutable extends HasMultipleRegions.Match { | ||
210 | Immutable(final CompositeElement pComposite) { | ||
211 | super(pComposite); | ||
212 | } | ||
213 | |||
214 | @Override | ||
215 | public boolean isMutable() { | ||
216 | return false; | ||
217 | } | ||
218 | } | ||
219 | } | ||
220 | |||
221 | /** | ||
222 | * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.hasMultipleRegions pattern, | ||
223 | * providing pattern-specific query methods. | ||
224 | * | ||
225 | * <p>Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, | ||
226 | * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. | ||
227 | * | ||
228 | * <p>Matches of the pattern will be represented as {@link Match}. | ||
229 | * | ||
230 | * <p>Original source: | ||
231 | * <code><pre> | ||
232 | * pattern hasMultipleRegions(composite: CompositeElement) { | ||
233 | * CompositeElement.regions(composite,region1); | ||
234 | * CompositeElement.regions(composite,region2); | ||
235 | * region1 != region2; | ||
236 | * } | ||
237 | * </pre></code> | ||
238 | * | ||
239 | * @see Match | ||
240 | * @see HasMultipleRegions | ||
241 | * | ||
242 | */ | ||
243 | public static class Matcher extends BaseMatcher<HasMultipleRegions.Match> { | ||
244 | /** | ||
245 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
246 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
247 | * | ||
248 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
249 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
250 | * | ||
251 | */ | ||
252 | public static HasMultipleRegions.Matcher on(final ViatraQueryEngine engine) { | ||
253 | // check if matcher already exists | ||
254 | Matcher matcher = engine.getExistingMatcher(querySpecification()); | ||
255 | if (matcher == null) { | ||
256 | matcher = (Matcher)engine.getMatcher(querySpecification()); | ||
257 | } | ||
258 | return matcher; | ||
259 | } | ||
260 | |||
261 | /** | ||
262 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
263 | * @return an initialized matcher | ||
264 | * @noreference This method is for internal matcher initialization by the framework, do not call it manually. | ||
265 | * | ||
266 | */ | ||
267 | public static HasMultipleRegions.Matcher create() { | ||
268 | return new Matcher(); | ||
269 | } | ||
270 | |||
271 | private final static int POSITION_COMPOSITE = 0; | ||
272 | |||
273 | private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(HasMultipleRegions.Matcher.class); | ||
274 | |||
275 | /** | ||
276 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
277 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
278 | * | ||
279 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
280 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
281 | * | ||
282 | */ | ||
283 | private Matcher() { | ||
284 | super(querySpecification()); | ||
285 | } | ||
286 | |||
287 | /** | ||
288 | * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. | ||
289 | * @param pComposite the fixed value of pattern parameter composite, or null if not bound. | ||
290 | * @return matches represented as a Match object. | ||
291 | * | ||
292 | */ | ||
293 | public Collection<HasMultipleRegions.Match> getAllMatches(final CompositeElement pComposite) { | ||
294 | return rawStreamAllMatches(new Object[]{pComposite}).collect(Collectors.toSet()); | ||
295 | } | ||
296 | |||
297 | /** | ||
298 | * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. | ||
299 | * </p> | ||
300 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
301 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
302 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
303 | * @param pComposite the fixed value of pattern parameter composite, or null if not bound. | ||
304 | * @return a stream of matches represented as a Match object. | ||
305 | * | ||
306 | */ | ||
307 | public Stream<HasMultipleRegions.Match> streamAllMatches(final CompositeElement pComposite) { | ||
308 | return rawStreamAllMatches(new Object[]{pComposite}); | ||
309 | } | ||
310 | |||
311 | /** | ||
312 | * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
313 | * Neither determinism nor randomness of selection is guaranteed. | ||
314 | * @param pComposite the fixed value of pattern parameter composite, or null if not bound. | ||
315 | * @return a match represented as a Match object, or null if no match is found. | ||
316 | * | ||
317 | */ | ||
318 | public Optional<HasMultipleRegions.Match> getOneArbitraryMatch(final CompositeElement pComposite) { | ||
319 | return rawGetOneArbitraryMatch(new Object[]{pComposite}); | ||
320 | } | ||
321 | |||
322 | /** | ||
323 | * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, | ||
324 | * under any possible substitution of the unspecified parameters (if any). | ||
325 | * @param pComposite the fixed value of pattern parameter composite, or null if not bound. | ||
326 | * @return true if the input is a valid (partial) match of the pattern. | ||
327 | * | ||
328 | */ | ||
329 | public boolean hasMatch(final CompositeElement pComposite) { | ||
330 | return rawHasMatch(new Object[]{pComposite}); | ||
331 | } | ||
332 | |||
333 | /** | ||
334 | * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. | ||
335 | * @param pComposite the fixed value of pattern parameter composite, or null if not bound. | ||
336 | * @return the number of pattern matches found. | ||
337 | * | ||
338 | */ | ||
339 | public int countMatches(final CompositeElement pComposite) { | ||
340 | return rawCountMatches(new Object[]{pComposite}); | ||
341 | } | ||
342 | |||
343 | /** | ||
344 | * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
345 | * Neither determinism nor randomness of selection is guaranteed. | ||
346 | * @param pComposite the fixed value of pattern parameter composite, or null if not bound. | ||
347 | * @param processor the action that will process the selected match. | ||
348 | * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked | ||
349 | * | ||
350 | */ | ||
351 | public boolean forOneArbitraryMatch(final CompositeElement pComposite, final Consumer<? super HasMultipleRegions.Match> processor) { | ||
352 | return rawForOneArbitraryMatch(new Object[]{pComposite}, processor); | ||
353 | } | ||
354 | |||
355 | /** | ||
356 | * Returns a new (partial) match. | ||
357 | * This can be used e.g. to call the matcher with a partial match. | ||
358 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
359 | * @param pComposite the fixed value of pattern parameter composite, or null if not bound. | ||
360 | * @return the (partial) match object. | ||
361 | * | ||
362 | */ | ||
363 | public HasMultipleRegions.Match newMatch(final CompositeElement pComposite) { | ||
364 | return HasMultipleRegions.Match.newMatch(pComposite); | ||
365 | } | ||
366 | |||
367 | /** | ||
368 | * Retrieve the set of values that occur in matches for composite. | ||
369 | * @return the Set of all values or empty set if there are no matches | ||
370 | * | ||
371 | */ | ||
372 | protected Stream<CompositeElement> rawStreamAllValuesOfcomposite(final Object[] parameters) { | ||
373 | return rawStreamAllValues(POSITION_COMPOSITE, parameters).map(CompositeElement.class::cast); | ||
374 | } | ||
375 | |||
376 | /** | ||
377 | * Retrieve the set of values that occur in matches for composite. | ||
378 | * @return the Set of all values or empty set if there are no matches | ||
379 | * | ||
380 | */ | ||
381 | public Set<CompositeElement> getAllValuesOfcomposite() { | ||
382 | return rawStreamAllValuesOfcomposite(emptyArray()).collect(Collectors.toSet()); | ||
383 | } | ||
384 | |||
385 | /** | ||
386 | * Retrieve the set of values that occur in matches for composite. | ||
387 | * @return the Set of all values or empty set if there are no matches | ||
388 | * | ||
389 | */ | ||
390 | public Stream<CompositeElement> streamAllValuesOfcomposite() { | ||
391 | return rawStreamAllValuesOfcomposite(emptyArray()); | ||
392 | } | ||
393 | |||
394 | @Override | ||
395 | protected HasMultipleRegions.Match tupleToMatch(final Tuple t) { | ||
396 | try { | ||
397 | return HasMultipleRegions.Match.newMatch((CompositeElement) t.get(POSITION_COMPOSITE)); | ||
398 | } catch(ClassCastException e) { | ||
399 | LOGGER.error("Element(s) in tuple not properly typed!",e); | ||
400 | return null; | ||
401 | } | ||
402 | } | ||
403 | |||
404 | @Override | ||
405 | protected HasMultipleRegions.Match arrayToMatch(final Object[] match) { | ||
406 | try { | ||
407 | return HasMultipleRegions.Match.newMatch((CompositeElement) match[POSITION_COMPOSITE]); | ||
408 | } catch(ClassCastException e) { | ||
409 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
410 | return null; | ||
411 | } | ||
412 | } | ||
413 | |||
414 | @Override | ||
415 | protected HasMultipleRegions.Match arrayToMatchMutable(final Object[] match) { | ||
416 | try { | ||
417 | return HasMultipleRegions.Match.newMutableMatch((CompositeElement) match[POSITION_COMPOSITE]); | ||
418 | } catch(ClassCastException e) { | ||
419 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
420 | return null; | ||
421 | } | ||
422 | } | ||
423 | |||
424 | /** | ||
425 | * @return the singleton instance of the query specification of this pattern | ||
426 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
427 | * | ||
428 | */ | ||
429 | public static IQuerySpecification<HasMultipleRegions.Matcher> querySpecification() { | ||
430 | return HasMultipleRegions.instance(); | ||
431 | } | ||
432 | } | ||
433 | |||
434 | private HasMultipleRegions() { | ||
435 | super(GeneratedPQuery.INSTANCE); | ||
436 | } | ||
437 | |||
438 | /** | ||
439 | * @return the singleton instance of the query specification | ||
440 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
441 | * | ||
442 | */ | ||
443 | public static HasMultipleRegions instance() { | ||
444 | try{ | ||
445 | return LazyHolder.INSTANCE; | ||
446 | } catch (ExceptionInInitializerError err) { | ||
447 | throw processInitializerError(err); | ||
448 | } | ||
449 | } | ||
450 | |||
451 | @Override | ||
452 | protected HasMultipleRegions.Matcher instantiate(final ViatraQueryEngine engine) { | ||
453 | return HasMultipleRegions.Matcher.on(engine); | ||
454 | } | ||
455 | |||
456 | @Override | ||
457 | public HasMultipleRegions.Matcher instantiate() { | ||
458 | return HasMultipleRegions.Matcher.create(); | ||
459 | } | ||
460 | |||
461 | @Override | ||
462 | public HasMultipleRegions.Match newEmptyMatch() { | ||
463 | return HasMultipleRegions.Match.newEmptyMatch(); | ||
464 | } | ||
465 | |||
466 | @Override | ||
467 | public HasMultipleRegions.Match newMatch(final Object... parameters) { | ||
468 | return HasMultipleRegions.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.CompositeElement) parameters[0]); | ||
469 | } | ||
470 | |||
471 | /** | ||
472 | * Inner class allowing the singleton instance of {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.HasMultipleRegions (visibility: PUBLIC, simpleName: HasMultipleRegions, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.HasMultipleRegions, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created | ||
473 | * <b>not</b> at the class load time of the outer class, | ||
474 | * but rather at the first call to {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.HasMultipleRegions (visibility: PUBLIC, simpleName: HasMultipleRegions, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.HasMultipleRegions, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. | ||
475 | * | ||
476 | * <p> This workaround is required e.g. to support recursion. | ||
477 | * | ||
478 | */ | ||
479 | private static class LazyHolder { | ||
480 | private final static HasMultipleRegions INSTANCE = new HasMultipleRegions(); | ||
481 | |||
482 | /** | ||
483 | * Statically initializes the query specification <b>after</b> the field {@link #INSTANCE} is assigned. | ||
484 | * This initialization order is required to support indirect recursion. | ||
485 | * | ||
486 | * <p> The static initializer is defined using a helper field to work around limitations of the code generator. | ||
487 | * | ||
488 | */ | ||
489 | private final static Object STATIC_INITIALIZER = ensureInitialized(); | ||
490 | |||
491 | public static Object ensureInitialized() { | ||
492 | INSTANCE.ensureInitializedInternal(); | ||
493 | return null; | ||
494 | } | ||
495 | } | ||
496 | |||
497 | private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { | ||
498 | private final static HasMultipleRegions.GeneratedPQuery INSTANCE = new GeneratedPQuery(); | ||
499 | |||
500 | private final PParameter parameter_composite = new PParameter("composite", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.CompositeElement", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "CompositeElement")), PParameterDirection.INOUT); | ||
501 | |||
502 | private final List<PParameter> parameters = Arrays.asList(parameter_composite); | ||
503 | |||
504 | private GeneratedPQuery() { | ||
505 | super(PVisibility.PUBLIC); | ||
506 | } | ||
507 | |||
508 | @Override | ||
509 | public String getFullyQualifiedName() { | ||
510 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.hasMultipleRegions"; | ||
511 | } | ||
512 | |||
513 | @Override | ||
514 | public List<String> getParameterNames() { | ||
515 | return Arrays.asList("composite"); | ||
516 | } | ||
517 | |||
518 | @Override | ||
519 | public List<PParameter> getParameters() { | ||
520 | return parameters; | ||
521 | } | ||
522 | |||
523 | @Override | ||
524 | public Set<PBody> doGetContainedBodies() { | ||
525 | setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); | ||
526 | Set<PBody> bodies = new LinkedHashSet<>(); | ||
527 | { | ||
528 | PBody body = new PBody(this); | ||
529 | PVariable var_composite = body.getOrCreateVariableByName("composite"); | ||
530 | PVariable var_region1 = body.getOrCreateVariableByName("region1"); | ||
531 | PVariable var_region2 = body.getOrCreateVariableByName("region2"); | ||
532 | new TypeConstraint(body, Tuples.flatTupleOf(var_composite), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "CompositeElement"))); | ||
533 | body.setSymbolicParameters(Arrays.<ExportedParameter>asList( | ||
534 | new ExportedParameter(body, var_composite, parameter_composite) | ||
535 | )); | ||
536 | // CompositeElement.regions(composite,region1) | ||
537 | new TypeConstraint(body, Tuples.flatTupleOf(var_composite), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "CompositeElement"))); | ||
538 | PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); | ||
539 | new TypeConstraint(body, Tuples.flatTupleOf(var_composite, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "CompositeElement", "regions"))); | ||
540 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Region"))); | ||
541 | new Equality(body, var__virtual_0_, var_region1); | ||
542 | // CompositeElement.regions(composite,region2) | ||
543 | new TypeConstraint(body, Tuples.flatTupleOf(var_composite), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "CompositeElement"))); | ||
544 | PVariable var__virtual_1_ = body.getOrCreateVariableByName(".virtual{1}"); | ||
545 | new TypeConstraint(body, Tuples.flatTupleOf(var_composite, var__virtual_1_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "CompositeElement", "regions"))); | ||
546 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_1_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Region"))); | ||
547 | new Equality(body, var__virtual_1_, var_region2); | ||
548 | // region1 != region2 | ||
549 | new Inequality(body, var_region1, var_region2); | ||
550 | bodies.add(body); | ||
551 | } | ||
552 | return bodies; | ||
553 | } | ||
554 | } | ||
555 | } | ||
diff --git a/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/IncomingToEntry.java b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/IncomingToEntry.java new file mode 100644 index 00000000..ed8ca3e5 --- /dev/null +++ b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/IncomingToEntry.java | |||
@@ -0,0 +1,703 @@ | |||
1 | /** | ||
2 | * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql | ||
3 | */ | ||
4 | package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; | ||
5 | |||
6 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Entry; | ||
7 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition; | ||
8 | import java.util.Arrays; | ||
9 | import java.util.Collection; | ||
10 | import java.util.LinkedHashSet; | ||
11 | import java.util.List; | ||
12 | import java.util.Objects; | ||
13 | import java.util.Optional; | ||
14 | import java.util.Set; | ||
15 | import java.util.function.Consumer; | ||
16 | import java.util.stream.Collectors; | ||
17 | import java.util.stream.Stream; | ||
18 | import org.apache.log4j.Logger; | ||
19 | import org.eclipse.emf.ecore.EClass; | ||
20 | import org.eclipse.viatra.query.runtime.api.IPatternMatch; | ||
21 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification; | ||
22 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; | ||
23 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; | ||
24 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; | ||
25 | import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; | ||
26 | import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; | ||
27 | import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; | ||
28 | import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; | ||
29 | import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; | ||
30 | import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; | ||
31 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; | ||
32 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; | ||
33 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; | ||
34 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall; | ||
35 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; | ||
36 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; | ||
37 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; | ||
38 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; | ||
39 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; | ||
40 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | ||
41 | import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; | ||
42 | |||
43 | /** | ||
44 | * A pattern-specific query specification that can instantiate Matcher in a type-safe way. | ||
45 | * | ||
46 | * <p>Original source: | ||
47 | * <code><pre> | ||
48 | * {@literal @}Constraint(severity="error", message="error", key = {e}) | ||
49 | * pattern incomingToEntry(t : Transition, e : Entry) { | ||
50 | * find transition(t, _, e); | ||
51 | * } | ||
52 | * </pre></code> | ||
53 | * | ||
54 | * @see Matcher | ||
55 | * @see Match | ||
56 | * | ||
57 | */ | ||
58 | @SuppressWarnings("all") | ||
59 | public final class IncomingToEntry extends BaseGeneratedEMFQuerySpecification<IncomingToEntry.Matcher> { | ||
60 | /** | ||
61 | * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.incomingToEntry pattern, | ||
62 | * to be used in conjunction with {@link Matcher}. | ||
63 | * | ||
64 | * <p>Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. | ||
65 | * Each instance is a (possibly partial) substitution of pattern parameters, | ||
66 | * usable to represent a match of the pattern in the result of a query, | ||
67 | * or to specify the bound (fixed) input parameters when issuing a query. | ||
68 | * | ||
69 | * @see Matcher | ||
70 | * | ||
71 | */ | ||
72 | public static abstract class Match extends BasePatternMatch { | ||
73 | private Transition fT; | ||
74 | |||
75 | private Entry fE; | ||
76 | |||
77 | private static List<String> parameterNames = makeImmutableList("t", "e"); | ||
78 | |||
79 | private Match(final Transition pT, final Entry pE) { | ||
80 | this.fT = pT; | ||
81 | this.fE = pE; | ||
82 | } | ||
83 | |||
84 | @Override | ||
85 | public Object get(final String parameterName) { | ||
86 | if ("t".equals(parameterName)) return this.fT; | ||
87 | if ("e".equals(parameterName)) return this.fE; | ||
88 | return null; | ||
89 | } | ||
90 | |||
91 | public Transition getT() { | ||
92 | return this.fT; | ||
93 | } | ||
94 | |||
95 | public Entry getE() { | ||
96 | return this.fE; | ||
97 | } | ||
98 | |||
99 | @Override | ||
100 | public boolean set(final String parameterName, final Object newValue) { | ||
101 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
102 | if ("t".equals(parameterName) ) { | ||
103 | this.fT = (Transition) newValue; | ||
104 | return true; | ||
105 | } | ||
106 | if ("e".equals(parameterName) ) { | ||
107 | this.fE = (Entry) newValue; | ||
108 | return true; | ||
109 | } | ||
110 | return false; | ||
111 | } | ||
112 | |||
113 | public void setT(final Transition pT) { | ||
114 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
115 | this.fT = pT; | ||
116 | } | ||
117 | |||
118 | public void setE(final Entry pE) { | ||
119 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
120 | this.fE = pE; | ||
121 | } | ||
122 | |||
123 | @Override | ||
124 | public String patternName() { | ||
125 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.incomingToEntry"; | ||
126 | } | ||
127 | |||
128 | @Override | ||
129 | public List<String> parameterNames() { | ||
130 | return IncomingToEntry.Match.parameterNames; | ||
131 | } | ||
132 | |||
133 | @Override | ||
134 | public Object[] toArray() { | ||
135 | return new Object[]{fT, fE}; | ||
136 | } | ||
137 | |||
138 | @Override | ||
139 | public IncomingToEntry.Match toImmutable() { | ||
140 | return isMutable() ? newMatch(fT, fE) : this; | ||
141 | } | ||
142 | |||
143 | @Override | ||
144 | public String prettyPrint() { | ||
145 | StringBuilder result = new StringBuilder(); | ||
146 | result.append("\"t\"=" + prettyPrintValue(fT) + ", "); | ||
147 | result.append("\"e\"=" + prettyPrintValue(fE)); | ||
148 | return result.toString(); | ||
149 | } | ||
150 | |||
151 | @Override | ||
152 | public int hashCode() { | ||
153 | return Objects.hash(fT, fE); | ||
154 | } | ||
155 | |||
156 | @Override | ||
157 | public boolean equals(final Object obj) { | ||
158 | if (this == obj) | ||
159 | return true; | ||
160 | if (obj == null) { | ||
161 | return false; | ||
162 | } | ||
163 | if ((obj instanceof IncomingToEntry.Match)) { | ||
164 | IncomingToEntry.Match other = (IncomingToEntry.Match) obj; | ||
165 | return Objects.equals(fT, other.fT) && Objects.equals(fE, other.fE); | ||
166 | } else { | ||
167 | // this should be infrequent | ||
168 | if (!(obj instanceof IPatternMatch)) { | ||
169 | return false; | ||
170 | } | ||
171 | IPatternMatch otherSig = (IPatternMatch) obj; | ||
172 | return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); | ||
173 | } | ||
174 | } | ||
175 | |||
176 | @Override | ||
177 | public IncomingToEntry specification() { | ||
178 | return IncomingToEntry.instance(); | ||
179 | } | ||
180 | |||
181 | /** | ||
182 | * Returns an empty, mutable match. | ||
183 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
184 | * | ||
185 | * @return the empty match. | ||
186 | * | ||
187 | */ | ||
188 | public static IncomingToEntry.Match newEmptyMatch() { | ||
189 | return new Mutable(null, null); | ||
190 | } | ||
191 | |||
192 | /** | ||
193 | * Returns a mutable (partial) match. | ||
194 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
195 | * | ||
196 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
197 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
198 | * @return the new, mutable (partial) match object. | ||
199 | * | ||
200 | */ | ||
201 | public static IncomingToEntry.Match newMutableMatch(final Transition pT, final Entry pE) { | ||
202 | return new Mutable(pT, pE); | ||
203 | } | ||
204 | |||
205 | /** | ||
206 | * Returns a new (partial) match. | ||
207 | * This can be used e.g. to call the matcher with a partial match. | ||
208 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
209 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
210 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
211 | * @return the (partial) match object. | ||
212 | * | ||
213 | */ | ||
214 | public static IncomingToEntry.Match newMatch(final Transition pT, final Entry pE) { | ||
215 | return new Immutable(pT, pE); | ||
216 | } | ||
217 | |||
218 | private static final class Mutable extends IncomingToEntry.Match { | ||
219 | Mutable(final Transition pT, final Entry pE) { | ||
220 | super(pT, pE); | ||
221 | } | ||
222 | |||
223 | @Override | ||
224 | public boolean isMutable() { | ||
225 | return true; | ||
226 | } | ||
227 | } | ||
228 | |||
229 | private static final class Immutable extends IncomingToEntry.Match { | ||
230 | Immutable(final Transition pT, final Entry pE) { | ||
231 | super(pT, pE); | ||
232 | } | ||
233 | |||
234 | @Override | ||
235 | public boolean isMutable() { | ||
236 | return false; | ||
237 | } | ||
238 | } | ||
239 | } | ||
240 | |||
241 | /** | ||
242 | * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.incomingToEntry pattern, | ||
243 | * providing pattern-specific query methods. | ||
244 | * | ||
245 | * <p>Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, | ||
246 | * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. | ||
247 | * | ||
248 | * <p>Matches of the pattern will be represented as {@link Match}. | ||
249 | * | ||
250 | * <p>Original source: | ||
251 | * <code><pre> | ||
252 | * {@literal @}Constraint(severity="error", message="error", key = {e}) | ||
253 | * pattern incomingToEntry(t : Transition, e : Entry) { | ||
254 | * find transition(t, _, e); | ||
255 | * } | ||
256 | * </pre></code> | ||
257 | * | ||
258 | * @see Match | ||
259 | * @see IncomingToEntry | ||
260 | * | ||
261 | */ | ||
262 | public static class Matcher extends BaseMatcher<IncomingToEntry.Match> { | ||
263 | /** | ||
264 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
265 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
266 | * | ||
267 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
268 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
269 | * | ||
270 | */ | ||
271 | public static IncomingToEntry.Matcher on(final ViatraQueryEngine engine) { | ||
272 | // check if matcher already exists | ||
273 | Matcher matcher = engine.getExistingMatcher(querySpecification()); | ||
274 | if (matcher == null) { | ||
275 | matcher = (Matcher)engine.getMatcher(querySpecification()); | ||
276 | } | ||
277 | return matcher; | ||
278 | } | ||
279 | |||
280 | /** | ||
281 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
282 | * @return an initialized matcher | ||
283 | * @noreference This method is for internal matcher initialization by the framework, do not call it manually. | ||
284 | * | ||
285 | */ | ||
286 | public static IncomingToEntry.Matcher create() { | ||
287 | return new Matcher(); | ||
288 | } | ||
289 | |||
290 | private final static int POSITION_T = 0; | ||
291 | |||
292 | private final static int POSITION_E = 1; | ||
293 | |||
294 | private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(IncomingToEntry.Matcher.class); | ||
295 | |||
296 | /** | ||
297 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
298 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
299 | * | ||
300 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
301 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
302 | * | ||
303 | */ | ||
304 | private Matcher() { | ||
305 | super(querySpecification()); | ||
306 | } | ||
307 | |||
308 | /** | ||
309 | * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. | ||
310 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
311 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
312 | * @return matches represented as a Match object. | ||
313 | * | ||
314 | */ | ||
315 | public Collection<IncomingToEntry.Match> getAllMatches(final Transition pT, final Entry pE) { | ||
316 | return rawStreamAllMatches(new Object[]{pT, pE}).collect(Collectors.toSet()); | ||
317 | } | ||
318 | |||
319 | /** | ||
320 | * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. | ||
321 | * </p> | ||
322 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
323 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
324 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
325 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
326 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
327 | * @return a stream of matches represented as a Match object. | ||
328 | * | ||
329 | */ | ||
330 | public Stream<IncomingToEntry.Match> streamAllMatches(final Transition pT, final Entry pE) { | ||
331 | return rawStreamAllMatches(new Object[]{pT, pE}); | ||
332 | } | ||
333 | |||
334 | /** | ||
335 | * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
336 | * Neither determinism nor randomness of selection is guaranteed. | ||
337 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
338 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
339 | * @return a match represented as a Match object, or null if no match is found. | ||
340 | * | ||
341 | */ | ||
342 | public Optional<IncomingToEntry.Match> getOneArbitraryMatch(final Transition pT, final Entry pE) { | ||
343 | return rawGetOneArbitraryMatch(new Object[]{pT, pE}); | ||
344 | } | ||
345 | |||
346 | /** | ||
347 | * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, | ||
348 | * under any possible substitution of the unspecified parameters (if any). | ||
349 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
350 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
351 | * @return true if the input is a valid (partial) match of the pattern. | ||
352 | * | ||
353 | */ | ||
354 | public boolean hasMatch(final Transition pT, final Entry pE) { | ||
355 | return rawHasMatch(new Object[]{pT, pE}); | ||
356 | } | ||
357 | |||
358 | /** | ||
359 | * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. | ||
360 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
361 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
362 | * @return the number of pattern matches found. | ||
363 | * | ||
364 | */ | ||
365 | public int countMatches(final Transition pT, final Entry pE) { | ||
366 | return rawCountMatches(new Object[]{pT, pE}); | ||
367 | } | ||
368 | |||
369 | /** | ||
370 | * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
371 | * Neither determinism nor randomness of selection is guaranteed. | ||
372 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
373 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
374 | * @param processor the action that will process the selected match. | ||
375 | * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked | ||
376 | * | ||
377 | */ | ||
378 | public boolean forOneArbitraryMatch(final Transition pT, final Entry pE, final Consumer<? super IncomingToEntry.Match> processor) { | ||
379 | return rawForOneArbitraryMatch(new Object[]{pT, pE}, processor); | ||
380 | } | ||
381 | |||
382 | /** | ||
383 | * Returns a new (partial) match. | ||
384 | * This can be used e.g. to call the matcher with a partial match. | ||
385 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
386 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
387 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
388 | * @return the (partial) match object. | ||
389 | * | ||
390 | */ | ||
391 | public IncomingToEntry.Match newMatch(final Transition pT, final Entry pE) { | ||
392 | return IncomingToEntry.Match.newMatch(pT, pE); | ||
393 | } | ||
394 | |||
395 | /** | ||
396 | * Retrieve the set of values that occur in matches for t. | ||
397 | * @return the Set of all values or empty set if there are no matches | ||
398 | * | ||
399 | */ | ||
400 | protected Stream<Transition> rawStreamAllValuesOft(final Object[] parameters) { | ||
401 | return rawStreamAllValues(POSITION_T, parameters).map(Transition.class::cast); | ||
402 | } | ||
403 | |||
404 | /** | ||
405 | * Retrieve the set of values that occur in matches for t. | ||
406 | * @return the Set of all values or empty set if there are no matches | ||
407 | * | ||
408 | */ | ||
409 | public Set<Transition> getAllValuesOft() { | ||
410 | return rawStreamAllValuesOft(emptyArray()).collect(Collectors.toSet()); | ||
411 | } | ||
412 | |||
413 | /** | ||
414 | * Retrieve the set of values that occur in matches for t. | ||
415 | * @return the Set of all values or empty set if there are no matches | ||
416 | * | ||
417 | */ | ||
418 | public Stream<Transition> streamAllValuesOft() { | ||
419 | return rawStreamAllValuesOft(emptyArray()); | ||
420 | } | ||
421 | |||
422 | /** | ||
423 | * Retrieve the set of values that occur in matches for t. | ||
424 | * </p> | ||
425 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
426 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
427 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
428 | * | ||
429 | * @return the Stream of all values or empty set if there are no matches | ||
430 | * | ||
431 | */ | ||
432 | public Stream<Transition> streamAllValuesOft(final IncomingToEntry.Match partialMatch) { | ||
433 | return rawStreamAllValuesOft(partialMatch.toArray()); | ||
434 | } | ||
435 | |||
436 | /** | ||
437 | * Retrieve the set of values that occur in matches for t. | ||
438 | * </p> | ||
439 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
440 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
441 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
442 | * | ||
443 | * @return the Stream of all values or empty set if there are no matches | ||
444 | * | ||
445 | */ | ||
446 | public Stream<Transition> streamAllValuesOft(final Entry pE) { | ||
447 | return rawStreamAllValuesOft(new Object[]{null, pE}); | ||
448 | } | ||
449 | |||
450 | /** | ||
451 | * Retrieve the set of values that occur in matches for t. | ||
452 | * @return the Set of all values or empty set if there are no matches | ||
453 | * | ||
454 | */ | ||
455 | public Set<Transition> getAllValuesOft(final IncomingToEntry.Match partialMatch) { | ||
456 | return rawStreamAllValuesOft(partialMatch.toArray()).collect(Collectors.toSet()); | ||
457 | } | ||
458 | |||
459 | /** | ||
460 | * Retrieve the set of values that occur in matches for t. | ||
461 | * @return the Set of all values or empty set if there are no matches | ||
462 | * | ||
463 | */ | ||
464 | public Set<Transition> getAllValuesOft(final Entry pE) { | ||
465 | return rawStreamAllValuesOft(new Object[]{null, pE}).collect(Collectors.toSet()); | ||
466 | } | ||
467 | |||
468 | /** | ||
469 | * Retrieve the set of values that occur in matches for e. | ||
470 | * @return the Set of all values or empty set if there are no matches | ||
471 | * | ||
472 | */ | ||
473 | protected Stream<Entry> rawStreamAllValuesOfe(final Object[] parameters) { | ||
474 | return rawStreamAllValues(POSITION_E, parameters).map(Entry.class::cast); | ||
475 | } | ||
476 | |||
477 | /** | ||
478 | * Retrieve the set of values that occur in matches for e. | ||
479 | * @return the Set of all values or empty set if there are no matches | ||
480 | * | ||
481 | */ | ||
482 | public Set<Entry> getAllValuesOfe() { | ||
483 | return rawStreamAllValuesOfe(emptyArray()).collect(Collectors.toSet()); | ||
484 | } | ||
485 | |||
486 | /** | ||
487 | * Retrieve the set of values that occur in matches for e. | ||
488 | * @return the Set of all values or empty set if there are no matches | ||
489 | * | ||
490 | */ | ||
491 | public Stream<Entry> streamAllValuesOfe() { | ||
492 | return rawStreamAllValuesOfe(emptyArray()); | ||
493 | } | ||
494 | |||
495 | /** | ||
496 | * Retrieve the set of values that occur in matches for e. | ||
497 | * </p> | ||
498 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
499 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
500 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
501 | * | ||
502 | * @return the Stream of all values or empty set if there are no matches | ||
503 | * | ||
504 | */ | ||
505 | public Stream<Entry> streamAllValuesOfe(final IncomingToEntry.Match partialMatch) { | ||
506 | return rawStreamAllValuesOfe(partialMatch.toArray()); | ||
507 | } | ||
508 | |||
509 | /** | ||
510 | * Retrieve the set of values that occur in matches for e. | ||
511 | * </p> | ||
512 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
513 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
514 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
515 | * | ||
516 | * @return the Stream of all values or empty set if there are no matches | ||
517 | * | ||
518 | */ | ||
519 | public Stream<Entry> streamAllValuesOfe(final Transition pT) { | ||
520 | return rawStreamAllValuesOfe(new Object[]{pT, null}); | ||
521 | } | ||
522 | |||
523 | /** | ||
524 | * Retrieve the set of values that occur in matches for e. | ||
525 | * @return the Set of all values or empty set if there are no matches | ||
526 | * | ||
527 | */ | ||
528 | public Set<Entry> getAllValuesOfe(final IncomingToEntry.Match partialMatch) { | ||
529 | return rawStreamAllValuesOfe(partialMatch.toArray()).collect(Collectors.toSet()); | ||
530 | } | ||
531 | |||
532 | /** | ||
533 | * Retrieve the set of values that occur in matches for e. | ||
534 | * @return the Set of all values or empty set if there are no matches | ||
535 | * | ||
536 | */ | ||
537 | public Set<Entry> getAllValuesOfe(final Transition pT) { | ||
538 | return rawStreamAllValuesOfe(new Object[]{pT, null}).collect(Collectors.toSet()); | ||
539 | } | ||
540 | |||
541 | @Override | ||
542 | protected IncomingToEntry.Match tupleToMatch(final Tuple t) { | ||
543 | try { | ||
544 | return IncomingToEntry.Match.newMatch((Transition) t.get(POSITION_T), (Entry) t.get(POSITION_E)); | ||
545 | } catch(ClassCastException e) { | ||
546 | LOGGER.error("Element(s) in tuple not properly typed!",e); | ||
547 | return null; | ||
548 | } | ||
549 | } | ||
550 | |||
551 | @Override | ||
552 | protected IncomingToEntry.Match arrayToMatch(final Object[] match) { | ||
553 | try { | ||
554 | return IncomingToEntry.Match.newMatch((Transition) match[POSITION_T], (Entry) match[POSITION_E]); | ||
555 | } catch(ClassCastException e) { | ||
556 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
557 | return null; | ||
558 | } | ||
559 | } | ||
560 | |||
561 | @Override | ||
562 | protected IncomingToEntry.Match arrayToMatchMutable(final Object[] match) { | ||
563 | try { | ||
564 | return IncomingToEntry.Match.newMutableMatch((Transition) match[POSITION_T], (Entry) match[POSITION_E]); | ||
565 | } catch(ClassCastException e) { | ||
566 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
567 | return null; | ||
568 | } | ||
569 | } | ||
570 | |||
571 | /** | ||
572 | * @return the singleton instance of the query specification of this pattern | ||
573 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
574 | * | ||
575 | */ | ||
576 | public static IQuerySpecification<IncomingToEntry.Matcher> querySpecification() { | ||
577 | return IncomingToEntry.instance(); | ||
578 | } | ||
579 | } | ||
580 | |||
581 | private IncomingToEntry() { | ||
582 | super(GeneratedPQuery.INSTANCE); | ||
583 | } | ||
584 | |||
585 | /** | ||
586 | * @return the singleton instance of the query specification | ||
587 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
588 | * | ||
589 | */ | ||
590 | public static IncomingToEntry instance() { | ||
591 | try{ | ||
592 | return LazyHolder.INSTANCE; | ||
593 | } catch (ExceptionInInitializerError err) { | ||
594 | throw processInitializerError(err); | ||
595 | } | ||
596 | } | ||
597 | |||
598 | @Override | ||
599 | protected IncomingToEntry.Matcher instantiate(final ViatraQueryEngine engine) { | ||
600 | return IncomingToEntry.Matcher.on(engine); | ||
601 | } | ||
602 | |||
603 | @Override | ||
604 | public IncomingToEntry.Matcher instantiate() { | ||
605 | return IncomingToEntry.Matcher.create(); | ||
606 | } | ||
607 | |||
608 | @Override | ||
609 | public IncomingToEntry.Match newEmptyMatch() { | ||
610 | return IncomingToEntry.Match.newEmptyMatch(); | ||
611 | } | ||
612 | |||
613 | @Override | ||
614 | public IncomingToEntry.Match newMatch(final Object... parameters) { | ||
615 | return IncomingToEntry.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition) parameters[0], (ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Entry) parameters[1]); | ||
616 | } | ||
617 | |||
618 | /** | ||
619 | * Inner class allowing the singleton instance of {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.IncomingToEntry (visibility: PUBLIC, simpleName: IncomingToEntry, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.IncomingToEntry, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created | ||
620 | * <b>not</b> at the class load time of the outer class, | ||
621 | * but rather at the first call to {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.IncomingToEntry (visibility: PUBLIC, simpleName: IncomingToEntry, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.IncomingToEntry, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. | ||
622 | * | ||
623 | * <p> This workaround is required e.g. to support recursion. | ||
624 | * | ||
625 | */ | ||
626 | private static class LazyHolder { | ||
627 | private final static IncomingToEntry INSTANCE = new IncomingToEntry(); | ||
628 | |||
629 | /** | ||
630 | * Statically initializes the query specification <b>after</b> the field {@link #INSTANCE} is assigned. | ||
631 | * This initialization order is required to support indirect recursion. | ||
632 | * | ||
633 | * <p> The static initializer is defined using a helper field to work around limitations of the code generator. | ||
634 | * | ||
635 | */ | ||
636 | private final static Object STATIC_INITIALIZER = ensureInitialized(); | ||
637 | |||
638 | public static Object ensureInitialized() { | ||
639 | INSTANCE.ensureInitializedInternal(); | ||
640 | return null; | ||
641 | } | ||
642 | } | ||
643 | |||
644 | private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { | ||
645 | private final static IncomingToEntry.GeneratedPQuery INSTANCE = new GeneratedPQuery(); | ||
646 | |||
647 | private final PParameter parameter_t = new PParameter("t", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Transition")), PParameterDirection.INOUT); | ||
648 | |||
649 | private final PParameter parameter_e = new PParameter("e", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Entry", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Entry")), PParameterDirection.INOUT); | ||
650 | |||
651 | private final List<PParameter> parameters = Arrays.asList(parameter_t, parameter_e); | ||
652 | |||
653 | private GeneratedPQuery() { | ||
654 | super(PVisibility.PUBLIC); | ||
655 | } | ||
656 | |||
657 | @Override | ||
658 | public String getFullyQualifiedName() { | ||
659 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.incomingToEntry"; | ||
660 | } | ||
661 | |||
662 | @Override | ||
663 | public List<String> getParameterNames() { | ||
664 | return Arrays.asList("t","e"); | ||
665 | } | ||
666 | |||
667 | @Override | ||
668 | public List<PParameter> getParameters() { | ||
669 | return parameters; | ||
670 | } | ||
671 | |||
672 | @Override | ||
673 | public Set<PBody> doGetContainedBodies() { | ||
674 | setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); | ||
675 | Set<PBody> bodies = new LinkedHashSet<>(); | ||
676 | { | ||
677 | PBody body = new PBody(this); | ||
678 | PVariable var_t = body.getOrCreateVariableByName("t"); | ||
679 | PVariable var_e = body.getOrCreateVariableByName("e"); | ||
680 | PVariable var___0_ = body.getOrCreateVariableByName("_<0>"); | ||
681 | new TypeConstraint(body, Tuples.flatTupleOf(var_t), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); | ||
682 | new TypeConstraint(body, Tuples.flatTupleOf(var_e), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Entry"))); | ||
683 | body.setSymbolicParameters(Arrays.<ExportedParameter>asList( | ||
684 | new ExportedParameter(body, var_t, parameter_t), | ||
685 | new ExportedParameter(body, var_e, parameter_e) | ||
686 | )); | ||
687 | // find transition(t, _, e) | ||
688 | new PositivePatternCall(body, Tuples.flatTupleOf(var_t, var___0_, var_e), ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.Transition.instance().getInternalQueryRepresentation()); | ||
689 | bodies.add(body); | ||
690 | } | ||
691 | { | ||
692 | PAnnotation annotation = new PAnnotation("Constraint"); | ||
693 | annotation.addAttribute("severity", "error"); | ||
694 | annotation.addAttribute("message", "error"); | ||
695 | annotation.addAttribute("key", Arrays.asList(new Object[] { | ||
696 | new ParameterReference("e") | ||
697 | })); | ||
698 | addAnnotation(annotation); | ||
699 | } | ||
700 | return bodies; | ||
701 | } | ||
702 | } | ||
703 | } | ||
diff --git a/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/MultipleTransitionFromEntry.java b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/MultipleTransitionFromEntry.java new file mode 100644 index 00000000..e4c1bac5 --- /dev/null +++ b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/MultipleTransitionFromEntry.java | |||
@@ -0,0 +1,827 @@ | |||
1 | /** | ||
2 | * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql | ||
3 | */ | ||
4 | package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; | ||
5 | |||
6 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Entry; | ||
7 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition; | ||
8 | import java.util.Arrays; | ||
9 | import java.util.Collection; | ||
10 | import java.util.LinkedHashSet; | ||
11 | import java.util.List; | ||
12 | import java.util.Objects; | ||
13 | import java.util.Optional; | ||
14 | import java.util.Set; | ||
15 | import java.util.function.Consumer; | ||
16 | import java.util.stream.Collectors; | ||
17 | import java.util.stream.Stream; | ||
18 | import org.apache.log4j.Logger; | ||
19 | import org.eclipse.emf.ecore.EClass; | ||
20 | import org.eclipse.viatra.query.runtime.api.IPatternMatch; | ||
21 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification; | ||
22 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; | ||
23 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; | ||
24 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; | ||
25 | import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; | ||
26 | import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; | ||
27 | import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; | ||
28 | import org.eclipse.viatra.query.runtime.emf.types.EStructuralFeatureInstancesKey; | ||
29 | import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; | ||
30 | import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; | ||
31 | import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; | ||
32 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; | ||
33 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; | ||
34 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality; | ||
35 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; | ||
36 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Inequality; | ||
37 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; | ||
38 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; | ||
39 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; | ||
40 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; | ||
41 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; | ||
42 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | ||
43 | import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; | ||
44 | |||
45 | /** | ||
46 | * A pattern-specific query specification that can instantiate Matcher in a type-safe way. | ||
47 | * | ||
48 | * <p>Original source: | ||
49 | * <code><pre> | ||
50 | * {@literal @}Constraint(severity="error", message="error", key = {e}) | ||
51 | * pattern multipleTransitionFromEntry(e : Entry, t1 : Transition, t2: Transition) { | ||
52 | * Entry.outgoingTransitions(e,t1); | ||
53 | * Entry.outgoingTransitions(e,t2); | ||
54 | * t1!=t2; | ||
55 | * } | ||
56 | * </pre></code> | ||
57 | * | ||
58 | * @see Matcher | ||
59 | * @see Match | ||
60 | * | ||
61 | */ | ||
62 | @SuppressWarnings("all") | ||
63 | public final class MultipleTransitionFromEntry extends BaseGeneratedEMFQuerySpecification<MultipleTransitionFromEntry.Matcher> { | ||
64 | /** | ||
65 | * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.multipleTransitionFromEntry pattern, | ||
66 | * to be used in conjunction with {@link Matcher}. | ||
67 | * | ||
68 | * <p>Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. | ||
69 | * Each instance is a (possibly partial) substitution of pattern parameters, | ||
70 | * usable to represent a match of the pattern in the result of a query, | ||
71 | * or to specify the bound (fixed) input parameters when issuing a query. | ||
72 | * | ||
73 | * @see Matcher | ||
74 | * | ||
75 | */ | ||
76 | public static abstract class Match extends BasePatternMatch { | ||
77 | private Entry fE; | ||
78 | |||
79 | private Transition fT1; | ||
80 | |||
81 | private Transition fT2; | ||
82 | |||
83 | private static List<String> parameterNames = makeImmutableList("e", "t1", "t2"); | ||
84 | |||
85 | private Match(final Entry pE, final Transition pT1, final Transition pT2) { | ||
86 | this.fE = pE; | ||
87 | this.fT1 = pT1; | ||
88 | this.fT2 = pT2; | ||
89 | } | ||
90 | |||
91 | @Override | ||
92 | public Object get(final String parameterName) { | ||
93 | if ("e".equals(parameterName)) return this.fE; | ||
94 | if ("t1".equals(parameterName)) return this.fT1; | ||
95 | if ("t2".equals(parameterName)) return this.fT2; | ||
96 | return null; | ||
97 | } | ||
98 | |||
99 | public Entry getE() { | ||
100 | return this.fE; | ||
101 | } | ||
102 | |||
103 | public Transition getT1() { | ||
104 | return this.fT1; | ||
105 | } | ||
106 | |||
107 | public Transition getT2() { | ||
108 | return this.fT2; | ||
109 | } | ||
110 | |||
111 | @Override | ||
112 | public boolean set(final String parameterName, final Object newValue) { | ||
113 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
114 | if ("e".equals(parameterName) ) { | ||
115 | this.fE = (Entry) newValue; | ||
116 | return true; | ||
117 | } | ||
118 | if ("t1".equals(parameterName) ) { | ||
119 | this.fT1 = (Transition) newValue; | ||
120 | return true; | ||
121 | } | ||
122 | if ("t2".equals(parameterName) ) { | ||
123 | this.fT2 = (Transition) newValue; | ||
124 | return true; | ||
125 | } | ||
126 | return false; | ||
127 | } | ||
128 | |||
129 | public void setE(final Entry pE) { | ||
130 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
131 | this.fE = pE; | ||
132 | } | ||
133 | |||
134 | public void setT1(final Transition pT1) { | ||
135 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
136 | this.fT1 = pT1; | ||
137 | } | ||
138 | |||
139 | public void setT2(final Transition pT2) { | ||
140 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
141 | this.fT2 = pT2; | ||
142 | } | ||
143 | |||
144 | @Override | ||
145 | public String patternName() { | ||
146 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.multipleTransitionFromEntry"; | ||
147 | } | ||
148 | |||
149 | @Override | ||
150 | public List<String> parameterNames() { | ||
151 | return MultipleTransitionFromEntry.Match.parameterNames; | ||
152 | } | ||
153 | |||
154 | @Override | ||
155 | public Object[] toArray() { | ||
156 | return new Object[]{fE, fT1, fT2}; | ||
157 | } | ||
158 | |||
159 | @Override | ||
160 | public MultipleTransitionFromEntry.Match toImmutable() { | ||
161 | return isMutable() ? newMatch(fE, fT1, fT2) : this; | ||
162 | } | ||
163 | |||
164 | @Override | ||
165 | public String prettyPrint() { | ||
166 | StringBuilder result = new StringBuilder(); | ||
167 | result.append("\"e\"=" + prettyPrintValue(fE) + ", "); | ||
168 | result.append("\"t1\"=" + prettyPrintValue(fT1) + ", "); | ||
169 | result.append("\"t2\"=" + prettyPrintValue(fT2)); | ||
170 | return result.toString(); | ||
171 | } | ||
172 | |||
173 | @Override | ||
174 | public int hashCode() { | ||
175 | return Objects.hash(fE, fT1, fT2); | ||
176 | } | ||
177 | |||
178 | @Override | ||
179 | public boolean equals(final Object obj) { | ||
180 | if (this == obj) | ||
181 | return true; | ||
182 | if (obj == null) { | ||
183 | return false; | ||
184 | } | ||
185 | if ((obj instanceof MultipleTransitionFromEntry.Match)) { | ||
186 | MultipleTransitionFromEntry.Match other = (MultipleTransitionFromEntry.Match) obj; | ||
187 | return Objects.equals(fE, other.fE) && Objects.equals(fT1, other.fT1) && Objects.equals(fT2, other.fT2); | ||
188 | } else { | ||
189 | // this should be infrequent | ||
190 | if (!(obj instanceof IPatternMatch)) { | ||
191 | return false; | ||
192 | } | ||
193 | IPatternMatch otherSig = (IPatternMatch) obj; | ||
194 | return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); | ||
195 | } | ||
196 | } | ||
197 | |||
198 | @Override | ||
199 | public MultipleTransitionFromEntry specification() { | ||
200 | return MultipleTransitionFromEntry.instance(); | ||
201 | } | ||
202 | |||
203 | /** | ||
204 | * Returns an empty, mutable match. | ||
205 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
206 | * | ||
207 | * @return the empty match. | ||
208 | * | ||
209 | */ | ||
210 | public static MultipleTransitionFromEntry.Match newEmptyMatch() { | ||
211 | return new Mutable(null, null, null); | ||
212 | } | ||
213 | |||
214 | /** | ||
215 | * Returns a mutable (partial) match. | ||
216 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
217 | * | ||
218 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
219 | * @param pT1 the fixed value of pattern parameter t1, or null if not bound. | ||
220 | * @param pT2 the fixed value of pattern parameter t2, or null if not bound. | ||
221 | * @return the new, mutable (partial) match object. | ||
222 | * | ||
223 | */ | ||
224 | public static MultipleTransitionFromEntry.Match newMutableMatch(final Entry pE, final Transition pT1, final Transition pT2) { | ||
225 | return new Mutable(pE, pT1, pT2); | ||
226 | } | ||
227 | |||
228 | /** | ||
229 | * Returns a new (partial) match. | ||
230 | * This can be used e.g. to call the matcher with a partial match. | ||
231 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
232 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
233 | * @param pT1 the fixed value of pattern parameter t1, or null if not bound. | ||
234 | * @param pT2 the fixed value of pattern parameter t2, or null if not bound. | ||
235 | * @return the (partial) match object. | ||
236 | * | ||
237 | */ | ||
238 | public static MultipleTransitionFromEntry.Match newMatch(final Entry pE, final Transition pT1, final Transition pT2) { | ||
239 | return new Immutable(pE, pT1, pT2); | ||
240 | } | ||
241 | |||
242 | private static final class Mutable extends MultipleTransitionFromEntry.Match { | ||
243 | Mutable(final Entry pE, final Transition pT1, final Transition pT2) { | ||
244 | super(pE, pT1, pT2); | ||
245 | } | ||
246 | |||
247 | @Override | ||
248 | public boolean isMutable() { | ||
249 | return true; | ||
250 | } | ||
251 | } | ||
252 | |||
253 | private static final class Immutable extends MultipleTransitionFromEntry.Match { | ||
254 | Immutable(final Entry pE, final Transition pT1, final Transition pT2) { | ||
255 | super(pE, pT1, pT2); | ||
256 | } | ||
257 | |||
258 | @Override | ||
259 | public boolean isMutable() { | ||
260 | return false; | ||
261 | } | ||
262 | } | ||
263 | } | ||
264 | |||
265 | /** | ||
266 | * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.multipleTransitionFromEntry pattern, | ||
267 | * providing pattern-specific query methods. | ||
268 | * | ||
269 | * <p>Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, | ||
270 | * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. | ||
271 | * | ||
272 | * <p>Matches of the pattern will be represented as {@link Match}. | ||
273 | * | ||
274 | * <p>Original source: | ||
275 | * <code><pre> | ||
276 | * {@literal @}Constraint(severity="error", message="error", key = {e}) | ||
277 | * pattern multipleTransitionFromEntry(e : Entry, t1 : Transition, t2: Transition) { | ||
278 | * Entry.outgoingTransitions(e,t1); | ||
279 | * Entry.outgoingTransitions(e,t2); | ||
280 | * t1!=t2; | ||
281 | * } | ||
282 | * </pre></code> | ||
283 | * | ||
284 | * @see Match | ||
285 | * @see MultipleTransitionFromEntry | ||
286 | * | ||
287 | */ | ||
288 | public static class Matcher extends BaseMatcher<MultipleTransitionFromEntry.Match> { | ||
289 | /** | ||
290 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
291 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
292 | * | ||
293 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
294 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
295 | * | ||
296 | */ | ||
297 | public static MultipleTransitionFromEntry.Matcher on(final ViatraQueryEngine engine) { | ||
298 | // check if matcher already exists | ||
299 | Matcher matcher = engine.getExistingMatcher(querySpecification()); | ||
300 | if (matcher == null) { | ||
301 | matcher = (Matcher)engine.getMatcher(querySpecification()); | ||
302 | } | ||
303 | return matcher; | ||
304 | } | ||
305 | |||
306 | /** | ||
307 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
308 | * @return an initialized matcher | ||
309 | * @noreference This method is for internal matcher initialization by the framework, do not call it manually. | ||
310 | * | ||
311 | */ | ||
312 | public static MultipleTransitionFromEntry.Matcher create() { | ||
313 | return new Matcher(); | ||
314 | } | ||
315 | |||
316 | private final static int POSITION_E = 0; | ||
317 | |||
318 | private final static int POSITION_T1 = 1; | ||
319 | |||
320 | private final static int POSITION_T2 = 2; | ||
321 | |||
322 | private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(MultipleTransitionFromEntry.Matcher.class); | ||
323 | |||
324 | /** | ||
325 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
326 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
327 | * | ||
328 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
329 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
330 | * | ||
331 | */ | ||
332 | private Matcher() { | ||
333 | super(querySpecification()); | ||
334 | } | ||
335 | |||
336 | /** | ||
337 | * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. | ||
338 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
339 | * @param pT1 the fixed value of pattern parameter t1, or null if not bound. | ||
340 | * @param pT2 the fixed value of pattern parameter t2, or null if not bound. | ||
341 | * @return matches represented as a Match object. | ||
342 | * | ||
343 | */ | ||
344 | public Collection<MultipleTransitionFromEntry.Match> getAllMatches(final Entry pE, final Transition pT1, final Transition pT2) { | ||
345 | return rawStreamAllMatches(new Object[]{pE, pT1, pT2}).collect(Collectors.toSet()); | ||
346 | } | ||
347 | |||
348 | /** | ||
349 | * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. | ||
350 | * </p> | ||
351 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
352 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
353 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
354 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
355 | * @param pT1 the fixed value of pattern parameter t1, or null if not bound. | ||
356 | * @param pT2 the fixed value of pattern parameter t2, or null if not bound. | ||
357 | * @return a stream of matches represented as a Match object. | ||
358 | * | ||
359 | */ | ||
360 | public Stream<MultipleTransitionFromEntry.Match> streamAllMatches(final Entry pE, final Transition pT1, final Transition pT2) { | ||
361 | return rawStreamAllMatches(new Object[]{pE, pT1, pT2}); | ||
362 | } | ||
363 | |||
364 | /** | ||
365 | * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
366 | * Neither determinism nor randomness of selection is guaranteed. | ||
367 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
368 | * @param pT1 the fixed value of pattern parameter t1, or null if not bound. | ||
369 | * @param pT2 the fixed value of pattern parameter t2, or null if not bound. | ||
370 | * @return a match represented as a Match object, or null if no match is found. | ||
371 | * | ||
372 | */ | ||
373 | public Optional<MultipleTransitionFromEntry.Match> getOneArbitraryMatch(final Entry pE, final Transition pT1, final Transition pT2) { | ||
374 | return rawGetOneArbitraryMatch(new Object[]{pE, pT1, pT2}); | ||
375 | } | ||
376 | |||
377 | /** | ||
378 | * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, | ||
379 | * under any possible substitution of the unspecified parameters (if any). | ||
380 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
381 | * @param pT1 the fixed value of pattern parameter t1, or null if not bound. | ||
382 | * @param pT2 the fixed value of pattern parameter t2, or null if not bound. | ||
383 | * @return true if the input is a valid (partial) match of the pattern. | ||
384 | * | ||
385 | */ | ||
386 | public boolean hasMatch(final Entry pE, final Transition pT1, final Transition pT2) { | ||
387 | return rawHasMatch(new Object[]{pE, pT1, pT2}); | ||
388 | } | ||
389 | |||
390 | /** | ||
391 | * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. | ||
392 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
393 | * @param pT1 the fixed value of pattern parameter t1, or null if not bound. | ||
394 | * @param pT2 the fixed value of pattern parameter t2, or null if not bound. | ||
395 | * @return the number of pattern matches found. | ||
396 | * | ||
397 | */ | ||
398 | public int countMatches(final Entry pE, final Transition pT1, final Transition pT2) { | ||
399 | return rawCountMatches(new Object[]{pE, pT1, pT2}); | ||
400 | } | ||
401 | |||
402 | /** | ||
403 | * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
404 | * Neither determinism nor randomness of selection is guaranteed. | ||
405 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
406 | * @param pT1 the fixed value of pattern parameter t1, or null if not bound. | ||
407 | * @param pT2 the fixed value of pattern parameter t2, or null if not bound. | ||
408 | * @param processor the action that will process the selected match. | ||
409 | * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked | ||
410 | * | ||
411 | */ | ||
412 | public boolean forOneArbitraryMatch(final Entry pE, final Transition pT1, final Transition pT2, final Consumer<? super MultipleTransitionFromEntry.Match> processor) { | ||
413 | return rawForOneArbitraryMatch(new Object[]{pE, pT1, pT2}, processor); | ||
414 | } | ||
415 | |||
416 | /** | ||
417 | * Returns a new (partial) match. | ||
418 | * This can be used e.g. to call the matcher with a partial match. | ||
419 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
420 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
421 | * @param pT1 the fixed value of pattern parameter t1, or null if not bound. | ||
422 | * @param pT2 the fixed value of pattern parameter t2, or null if not bound. | ||
423 | * @return the (partial) match object. | ||
424 | * | ||
425 | */ | ||
426 | public MultipleTransitionFromEntry.Match newMatch(final Entry pE, final Transition pT1, final Transition pT2) { | ||
427 | return MultipleTransitionFromEntry.Match.newMatch(pE, pT1, pT2); | ||
428 | } | ||
429 | |||
430 | /** | ||
431 | * Retrieve the set of values that occur in matches for e. | ||
432 | * @return the Set of all values or empty set if there are no matches | ||
433 | * | ||
434 | */ | ||
435 | protected Stream<Entry> rawStreamAllValuesOfe(final Object[] parameters) { | ||
436 | return rawStreamAllValues(POSITION_E, parameters).map(Entry.class::cast); | ||
437 | } | ||
438 | |||
439 | /** | ||
440 | * Retrieve the set of values that occur in matches for e. | ||
441 | * @return the Set of all values or empty set if there are no matches | ||
442 | * | ||
443 | */ | ||
444 | public Set<Entry> getAllValuesOfe() { | ||
445 | return rawStreamAllValuesOfe(emptyArray()).collect(Collectors.toSet()); | ||
446 | } | ||
447 | |||
448 | /** | ||
449 | * Retrieve the set of values that occur in matches for e. | ||
450 | * @return the Set of all values or empty set if there are no matches | ||
451 | * | ||
452 | */ | ||
453 | public Stream<Entry> streamAllValuesOfe() { | ||
454 | return rawStreamAllValuesOfe(emptyArray()); | ||
455 | } | ||
456 | |||
457 | /** | ||
458 | * Retrieve the set of values that occur in matches for e. | ||
459 | * </p> | ||
460 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
461 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
462 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
463 | * | ||
464 | * @return the Stream of all values or empty set if there are no matches | ||
465 | * | ||
466 | */ | ||
467 | public Stream<Entry> streamAllValuesOfe(final MultipleTransitionFromEntry.Match partialMatch) { | ||
468 | return rawStreamAllValuesOfe(partialMatch.toArray()); | ||
469 | } | ||
470 | |||
471 | /** | ||
472 | * Retrieve the set of values that occur in matches for e. | ||
473 | * </p> | ||
474 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
475 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
476 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
477 | * | ||
478 | * @return the Stream of all values or empty set if there are no matches | ||
479 | * | ||
480 | */ | ||
481 | public Stream<Entry> streamAllValuesOfe(final Transition pT1, final Transition pT2) { | ||
482 | return rawStreamAllValuesOfe(new Object[]{null, pT1, pT2}); | ||
483 | } | ||
484 | |||
485 | /** | ||
486 | * Retrieve the set of values that occur in matches for e. | ||
487 | * @return the Set of all values or empty set if there are no matches | ||
488 | * | ||
489 | */ | ||
490 | public Set<Entry> getAllValuesOfe(final MultipleTransitionFromEntry.Match partialMatch) { | ||
491 | return rawStreamAllValuesOfe(partialMatch.toArray()).collect(Collectors.toSet()); | ||
492 | } | ||
493 | |||
494 | /** | ||
495 | * Retrieve the set of values that occur in matches for e. | ||
496 | * @return the Set of all values or empty set if there are no matches | ||
497 | * | ||
498 | */ | ||
499 | public Set<Entry> getAllValuesOfe(final Transition pT1, final Transition pT2) { | ||
500 | return rawStreamAllValuesOfe(new Object[]{null, pT1, pT2}).collect(Collectors.toSet()); | ||
501 | } | ||
502 | |||
503 | /** | ||
504 | * Retrieve the set of values that occur in matches for t1. | ||
505 | * @return the Set of all values or empty set if there are no matches | ||
506 | * | ||
507 | */ | ||
508 | protected Stream<Transition> rawStreamAllValuesOft1(final Object[] parameters) { | ||
509 | return rawStreamAllValues(POSITION_T1, parameters).map(Transition.class::cast); | ||
510 | } | ||
511 | |||
512 | /** | ||
513 | * Retrieve the set of values that occur in matches for t1. | ||
514 | * @return the Set of all values or empty set if there are no matches | ||
515 | * | ||
516 | */ | ||
517 | public Set<Transition> getAllValuesOft1() { | ||
518 | return rawStreamAllValuesOft1(emptyArray()).collect(Collectors.toSet()); | ||
519 | } | ||
520 | |||
521 | /** | ||
522 | * Retrieve the set of values that occur in matches for t1. | ||
523 | * @return the Set of all values or empty set if there are no matches | ||
524 | * | ||
525 | */ | ||
526 | public Stream<Transition> streamAllValuesOft1() { | ||
527 | return rawStreamAllValuesOft1(emptyArray()); | ||
528 | } | ||
529 | |||
530 | /** | ||
531 | * Retrieve the set of values that occur in matches for t1. | ||
532 | * </p> | ||
533 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
534 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
535 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
536 | * | ||
537 | * @return the Stream of all values or empty set if there are no matches | ||
538 | * | ||
539 | */ | ||
540 | public Stream<Transition> streamAllValuesOft1(final MultipleTransitionFromEntry.Match partialMatch) { | ||
541 | return rawStreamAllValuesOft1(partialMatch.toArray()); | ||
542 | } | ||
543 | |||
544 | /** | ||
545 | * Retrieve the set of values that occur in matches for t1. | ||
546 | * </p> | ||
547 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
548 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
549 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
550 | * | ||
551 | * @return the Stream of all values or empty set if there are no matches | ||
552 | * | ||
553 | */ | ||
554 | public Stream<Transition> streamAllValuesOft1(final Entry pE, final Transition pT2) { | ||
555 | return rawStreamAllValuesOft1(new Object[]{pE, null, pT2}); | ||
556 | } | ||
557 | |||
558 | /** | ||
559 | * Retrieve the set of values that occur in matches for t1. | ||
560 | * @return the Set of all values or empty set if there are no matches | ||
561 | * | ||
562 | */ | ||
563 | public Set<Transition> getAllValuesOft1(final MultipleTransitionFromEntry.Match partialMatch) { | ||
564 | return rawStreamAllValuesOft1(partialMatch.toArray()).collect(Collectors.toSet()); | ||
565 | } | ||
566 | |||
567 | /** | ||
568 | * Retrieve the set of values that occur in matches for t1. | ||
569 | * @return the Set of all values or empty set if there are no matches | ||
570 | * | ||
571 | */ | ||
572 | public Set<Transition> getAllValuesOft1(final Entry pE, final Transition pT2) { | ||
573 | return rawStreamAllValuesOft1(new Object[]{pE, null, pT2}).collect(Collectors.toSet()); | ||
574 | } | ||
575 | |||
576 | /** | ||
577 | * Retrieve the set of values that occur in matches for t2. | ||
578 | * @return the Set of all values or empty set if there are no matches | ||
579 | * | ||
580 | */ | ||
581 | protected Stream<Transition> rawStreamAllValuesOft2(final Object[] parameters) { | ||
582 | return rawStreamAllValues(POSITION_T2, parameters).map(Transition.class::cast); | ||
583 | } | ||
584 | |||
585 | /** | ||
586 | * Retrieve the set of values that occur in matches for t2. | ||
587 | * @return the Set of all values or empty set if there are no matches | ||
588 | * | ||
589 | */ | ||
590 | public Set<Transition> getAllValuesOft2() { | ||
591 | return rawStreamAllValuesOft2(emptyArray()).collect(Collectors.toSet()); | ||
592 | } | ||
593 | |||
594 | /** | ||
595 | * Retrieve the set of values that occur in matches for t2. | ||
596 | * @return the Set of all values or empty set if there are no matches | ||
597 | * | ||
598 | */ | ||
599 | public Stream<Transition> streamAllValuesOft2() { | ||
600 | return rawStreamAllValuesOft2(emptyArray()); | ||
601 | } | ||
602 | |||
603 | /** | ||
604 | * Retrieve the set of values that occur in matches for t2. | ||
605 | * </p> | ||
606 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
607 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
608 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
609 | * | ||
610 | * @return the Stream of all values or empty set if there are no matches | ||
611 | * | ||
612 | */ | ||
613 | public Stream<Transition> streamAllValuesOft2(final MultipleTransitionFromEntry.Match partialMatch) { | ||
614 | return rawStreamAllValuesOft2(partialMatch.toArray()); | ||
615 | } | ||
616 | |||
617 | /** | ||
618 | * Retrieve the set of values that occur in matches for t2. | ||
619 | * </p> | ||
620 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
621 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
622 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
623 | * | ||
624 | * @return the Stream of all values or empty set if there are no matches | ||
625 | * | ||
626 | */ | ||
627 | public Stream<Transition> streamAllValuesOft2(final Entry pE, final Transition pT1) { | ||
628 | return rawStreamAllValuesOft2(new Object[]{pE, pT1, null}); | ||
629 | } | ||
630 | |||
631 | /** | ||
632 | * Retrieve the set of values that occur in matches for t2. | ||
633 | * @return the Set of all values or empty set if there are no matches | ||
634 | * | ||
635 | */ | ||
636 | public Set<Transition> getAllValuesOft2(final MultipleTransitionFromEntry.Match partialMatch) { | ||
637 | return rawStreamAllValuesOft2(partialMatch.toArray()).collect(Collectors.toSet()); | ||
638 | } | ||
639 | |||
640 | /** | ||
641 | * Retrieve the set of values that occur in matches for t2. | ||
642 | * @return the Set of all values or empty set if there are no matches | ||
643 | * | ||
644 | */ | ||
645 | public Set<Transition> getAllValuesOft2(final Entry pE, final Transition pT1) { | ||
646 | return rawStreamAllValuesOft2(new Object[]{pE, pT1, null}).collect(Collectors.toSet()); | ||
647 | } | ||
648 | |||
649 | @Override | ||
650 | protected MultipleTransitionFromEntry.Match tupleToMatch(final Tuple t) { | ||
651 | try { | ||
652 | return MultipleTransitionFromEntry.Match.newMatch((Entry) t.get(POSITION_E), (Transition) t.get(POSITION_T1), (Transition) t.get(POSITION_T2)); | ||
653 | } catch(ClassCastException e) { | ||
654 | LOGGER.error("Element(s) in tuple not properly typed!",e); | ||
655 | return null; | ||
656 | } | ||
657 | } | ||
658 | |||
659 | @Override | ||
660 | protected MultipleTransitionFromEntry.Match arrayToMatch(final Object[] match) { | ||
661 | try { | ||
662 | return MultipleTransitionFromEntry.Match.newMatch((Entry) match[POSITION_E], (Transition) match[POSITION_T1], (Transition) match[POSITION_T2]); | ||
663 | } catch(ClassCastException e) { | ||
664 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
665 | return null; | ||
666 | } | ||
667 | } | ||
668 | |||
669 | @Override | ||
670 | protected MultipleTransitionFromEntry.Match arrayToMatchMutable(final Object[] match) { | ||
671 | try { | ||
672 | return MultipleTransitionFromEntry.Match.newMutableMatch((Entry) match[POSITION_E], (Transition) match[POSITION_T1], (Transition) match[POSITION_T2]); | ||
673 | } catch(ClassCastException e) { | ||
674 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
675 | return null; | ||
676 | } | ||
677 | } | ||
678 | |||
679 | /** | ||
680 | * @return the singleton instance of the query specification of this pattern | ||
681 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
682 | * | ||
683 | */ | ||
684 | public static IQuerySpecification<MultipleTransitionFromEntry.Matcher> querySpecification() { | ||
685 | return MultipleTransitionFromEntry.instance(); | ||
686 | } | ||
687 | } | ||
688 | |||
689 | private MultipleTransitionFromEntry() { | ||
690 | super(GeneratedPQuery.INSTANCE); | ||
691 | } | ||
692 | |||
693 | /** | ||
694 | * @return the singleton instance of the query specification | ||
695 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
696 | * | ||
697 | */ | ||
698 | public static MultipleTransitionFromEntry instance() { | ||
699 | try{ | ||
700 | return LazyHolder.INSTANCE; | ||
701 | } catch (ExceptionInInitializerError err) { | ||
702 | throw processInitializerError(err); | ||
703 | } | ||
704 | } | ||
705 | |||
706 | @Override | ||
707 | protected MultipleTransitionFromEntry.Matcher instantiate(final ViatraQueryEngine engine) { | ||
708 | return MultipleTransitionFromEntry.Matcher.on(engine); | ||
709 | } | ||
710 | |||
711 | @Override | ||
712 | public MultipleTransitionFromEntry.Matcher instantiate() { | ||
713 | return MultipleTransitionFromEntry.Matcher.create(); | ||
714 | } | ||
715 | |||
716 | @Override | ||
717 | public MultipleTransitionFromEntry.Match newEmptyMatch() { | ||
718 | return MultipleTransitionFromEntry.Match.newEmptyMatch(); | ||
719 | } | ||
720 | |||
721 | @Override | ||
722 | public MultipleTransitionFromEntry.Match newMatch(final Object... parameters) { | ||
723 | return MultipleTransitionFromEntry.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Entry) parameters[0], (ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition) parameters[1], (ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition) parameters[2]); | ||
724 | } | ||
725 | |||
726 | /** | ||
727 | * Inner class allowing the singleton instance of {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.MultipleTransitionFromEntry (visibility: PUBLIC, simpleName: MultipleTransitionFromEntry, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.MultipleTransitionFromEntry, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created | ||
728 | * <b>not</b> at the class load time of the outer class, | ||
729 | * but rather at the first call to {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.MultipleTransitionFromEntry (visibility: PUBLIC, simpleName: MultipleTransitionFromEntry, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.MultipleTransitionFromEntry, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. | ||
730 | * | ||
731 | * <p> This workaround is required e.g. to support recursion. | ||
732 | * | ||
733 | */ | ||
734 | private static class LazyHolder { | ||
735 | private final static MultipleTransitionFromEntry INSTANCE = new MultipleTransitionFromEntry(); | ||
736 | |||
737 | /** | ||
738 | * Statically initializes the query specification <b>after</b> the field {@link #INSTANCE} is assigned. | ||
739 | * This initialization order is required to support indirect recursion. | ||
740 | * | ||
741 | * <p> The static initializer is defined using a helper field to work around limitations of the code generator. | ||
742 | * | ||
743 | */ | ||
744 | private final static Object STATIC_INITIALIZER = ensureInitialized(); | ||
745 | |||
746 | public static Object ensureInitialized() { | ||
747 | INSTANCE.ensureInitializedInternal(); | ||
748 | return null; | ||
749 | } | ||
750 | } | ||
751 | |||
752 | private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { | ||
753 | private final static MultipleTransitionFromEntry.GeneratedPQuery INSTANCE = new GeneratedPQuery(); | ||
754 | |||
755 | private final PParameter parameter_e = new PParameter("e", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Entry", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Entry")), PParameterDirection.INOUT); | ||
756 | |||
757 | private final PParameter parameter_t1 = new PParameter("t1", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Transition")), PParameterDirection.INOUT); | ||
758 | |||
759 | private final PParameter parameter_t2 = new PParameter("t2", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Transition")), PParameterDirection.INOUT); | ||
760 | |||
761 | private final List<PParameter> parameters = Arrays.asList(parameter_e, parameter_t1, parameter_t2); | ||
762 | |||
763 | private GeneratedPQuery() { | ||
764 | super(PVisibility.PUBLIC); | ||
765 | } | ||
766 | |||
767 | @Override | ||
768 | public String getFullyQualifiedName() { | ||
769 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.multipleTransitionFromEntry"; | ||
770 | } | ||
771 | |||
772 | @Override | ||
773 | public List<String> getParameterNames() { | ||
774 | return Arrays.asList("e","t1","t2"); | ||
775 | } | ||
776 | |||
777 | @Override | ||
778 | public List<PParameter> getParameters() { | ||
779 | return parameters; | ||
780 | } | ||
781 | |||
782 | @Override | ||
783 | public Set<PBody> doGetContainedBodies() { | ||
784 | setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); | ||
785 | Set<PBody> bodies = new LinkedHashSet<>(); | ||
786 | { | ||
787 | PBody body = new PBody(this); | ||
788 | PVariable var_e = body.getOrCreateVariableByName("e"); | ||
789 | PVariable var_t1 = body.getOrCreateVariableByName("t1"); | ||
790 | PVariable var_t2 = body.getOrCreateVariableByName("t2"); | ||
791 | new TypeConstraint(body, Tuples.flatTupleOf(var_e), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Entry"))); | ||
792 | new TypeConstraint(body, Tuples.flatTupleOf(var_t1), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); | ||
793 | new TypeConstraint(body, Tuples.flatTupleOf(var_t2), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); | ||
794 | body.setSymbolicParameters(Arrays.<ExportedParameter>asList( | ||
795 | new ExportedParameter(body, var_e, parameter_e), | ||
796 | new ExportedParameter(body, var_t1, parameter_t1), | ||
797 | new ExportedParameter(body, var_t2, parameter_t2) | ||
798 | )); | ||
799 | // Entry.outgoingTransitions(e,t1) | ||
800 | new TypeConstraint(body, Tuples.flatTupleOf(var_e), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Entry"))); | ||
801 | PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); | ||
802 | new TypeConstraint(body, Tuples.flatTupleOf(var_e, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Vertex", "outgoingTransitions"))); | ||
803 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); | ||
804 | new Equality(body, var__virtual_0_, var_t1); | ||
805 | // Entry.outgoingTransitions(e,t2) | ||
806 | new TypeConstraint(body, Tuples.flatTupleOf(var_e), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Entry"))); | ||
807 | PVariable var__virtual_1_ = body.getOrCreateVariableByName(".virtual{1}"); | ||
808 | new TypeConstraint(body, Tuples.flatTupleOf(var_e, var__virtual_1_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Vertex", "outgoingTransitions"))); | ||
809 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_1_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); | ||
810 | new Equality(body, var__virtual_1_, var_t2); | ||
811 | // t1!=t2 | ||
812 | new Inequality(body, var_t1, var_t2); | ||
813 | bodies.add(body); | ||
814 | } | ||
815 | { | ||
816 | PAnnotation annotation = new PAnnotation("Constraint"); | ||
817 | annotation.addAttribute("severity", "error"); | ||
818 | annotation.addAttribute("message", "error"); | ||
819 | annotation.addAttribute("key", Arrays.asList(new Object[] { | ||
820 | new ParameterReference("e") | ||
821 | })); | ||
822 | addAnnotation(annotation); | ||
823 | } | ||
824 | return bodies; | ||
825 | } | ||
826 | } | ||
827 | } | ||
diff --git a/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/NoEntryInRegion.java b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/NoEntryInRegion.java new file mode 100644 index 00000000..c1f7df4a --- /dev/null +++ b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/NoEntryInRegion.java | |||
@@ -0,0 +1,550 @@ | |||
1 | /** | ||
2 | * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql | ||
3 | */ | ||
4 | package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; | ||
5 | |||
6 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Region; | ||
7 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.EntryInRegion; | ||
8 | import java.util.Arrays; | ||
9 | import java.util.Collection; | ||
10 | import java.util.LinkedHashSet; | ||
11 | import java.util.List; | ||
12 | import java.util.Objects; | ||
13 | import java.util.Optional; | ||
14 | import java.util.Set; | ||
15 | import java.util.function.Consumer; | ||
16 | import java.util.stream.Collectors; | ||
17 | import java.util.stream.Stream; | ||
18 | import org.apache.log4j.Logger; | ||
19 | import org.eclipse.emf.ecore.EClass; | ||
20 | import org.eclipse.viatra.query.runtime.api.IPatternMatch; | ||
21 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification; | ||
22 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; | ||
23 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; | ||
24 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; | ||
25 | import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; | ||
26 | import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; | ||
27 | import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; | ||
28 | import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; | ||
29 | import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; | ||
30 | import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; | ||
31 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; | ||
32 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; | ||
33 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; | ||
34 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.NegativePatternCall; | ||
35 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; | ||
36 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; | ||
37 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; | ||
38 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; | ||
39 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; | ||
40 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | ||
41 | import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; | ||
42 | |||
43 | /** | ||
44 | * A pattern-specific query specification that can instantiate Matcher in a type-safe way. | ||
45 | * | ||
46 | * <p>Original source: | ||
47 | * <code><pre> | ||
48 | * {@literal @}Constraint(severity="error", message="error", key = {r1}) | ||
49 | * pattern noEntryInRegion(r1 : Region) { | ||
50 | * neg find entryInRegion(r1, _); | ||
51 | * } | ||
52 | * </pre></code> | ||
53 | * | ||
54 | * @see Matcher | ||
55 | * @see Match | ||
56 | * | ||
57 | */ | ||
58 | @SuppressWarnings("all") | ||
59 | public final class NoEntryInRegion extends BaseGeneratedEMFQuerySpecification<NoEntryInRegion.Matcher> { | ||
60 | /** | ||
61 | * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.noEntryInRegion pattern, | ||
62 | * to be used in conjunction with {@link Matcher}. | ||
63 | * | ||
64 | * <p>Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. | ||
65 | * Each instance is a (possibly partial) substitution of pattern parameters, | ||
66 | * usable to represent a match of the pattern in the result of a query, | ||
67 | * or to specify the bound (fixed) input parameters when issuing a query. | ||
68 | * | ||
69 | * @see Matcher | ||
70 | * | ||
71 | */ | ||
72 | public static abstract class Match extends BasePatternMatch { | ||
73 | private Region fR1; | ||
74 | |||
75 | private static List<String> parameterNames = makeImmutableList("r1"); | ||
76 | |||
77 | private Match(final Region pR1) { | ||
78 | this.fR1 = pR1; | ||
79 | } | ||
80 | |||
81 | @Override | ||
82 | public Object get(final String parameterName) { | ||
83 | if ("r1".equals(parameterName)) return this.fR1; | ||
84 | return null; | ||
85 | } | ||
86 | |||
87 | public Region getR1() { | ||
88 | return this.fR1; | ||
89 | } | ||
90 | |||
91 | @Override | ||
92 | public boolean set(final String parameterName, final Object newValue) { | ||
93 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
94 | if ("r1".equals(parameterName) ) { | ||
95 | this.fR1 = (Region) newValue; | ||
96 | return true; | ||
97 | } | ||
98 | return false; | ||
99 | } | ||
100 | |||
101 | public void setR1(final Region pR1) { | ||
102 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
103 | this.fR1 = pR1; | ||
104 | } | ||
105 | |||
106 | @Override | ||
107 | public String patternName() { | ||
108 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.noEntryInRegion"; | ||
109 | } | ||
110 | |||
111 | @Override | ||
112 | public List<String> parameterNames() { | ||
113 | return NoEntryInRegion.Match.parameterNames; | ||
114 | } | ||
115 | |||
116 | @Override | ||
117 | public Object[] toArray() { | ||
118 | return new Object[]{fR1}; | ||
119 | } | ||
120 | |||
121 | @Override | ||
122 | public NoEntryInRegion.Match toImmutable() { | ||
123 | return isMutable() ? newMatch(fR1) : this; | ||
124 | } | ||
125 | |||
126 | @Override | ||
127 | public String prettyPrint() { | ||
128 | StringBuilder result = new StringBuilder(); | ||
129 | result.append("\"r1\"=" + prettyPrintValue(fR1)); | ||
130 | return result.toString(); | ||
131 | } | ||
132 | |||
133 | @Override | ||
134 | public int hashCode() { | ||
135 | return Objects.hash(fR1); | ||
136 | } | ||
137 | |||
138 | @Override | ||
139 | public boolean equals(final Object obj) { | ||
140 | if (this == obj) | ||
141 | return true; | ||
142 | if (obj == null) { | ||
143 | return false; | ||
144 | } | ||
145 | if ((obj instanceof NoEntryInRegion.Match)) { | ||
146 | NoEntryInRegion.Match other = (NoEntryInRegion.Match) obj; | ||
147 | return Objects.equals(fR1, other.fR1); | ||
148 | } else { | ||
149 | // this should be infrequent | ||
150 | if (!(obj instanceof IPatternMatch)) { | ||
151 | return false; | ||
152 | } | ||
153 | IPatternMatch otherSig = (IPatternMatch) obj; | ||
154 | return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); | ||
155 | } | ||
156 | } | ||
157 | |||
158 | @Override | ||
159 | public NoEntryInRegion specification() { | ||
160 | return NoEntryInRegion.instance(); | ||
161 | } | ||
162 | |||
163 | /** | ||
164 | * Returns an empty, mutable match. | ||
165 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
166 | * | ||
167 | * @return the empty match. | ||
168 | * | ||
169 | */ | ||
170 | public static NoEntryInRegion.Match newEmptyMatch() { | ||
171 | return new Mutable(null); | ||
172 | } | ||
173 | |||
174 | /** | ||
175 | * Returns a mutable (partial) match. | ||
176 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
177 | * | ||
178 | * @param pR1 the fixed value of pattern parameter r1, or null if not bound. | ||
179 | * @return the new, mutable (partial) match object. | ||
180 | * | ||
181 | */ | ||
182 | public static NoEntryInRegion.Match newMutableMatch(final Region pR1) { | ||
183 | return new Mutable(pR1); | ||
184 | } | ||
185 | |||
186 | /** | ||
187 | * Returns a new (partial) match. | ||
188 | * This can be used e.g. to call the matcher with a partial match. | ||
189 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
190 | * @param pR1 the fixed value of pattern parameter r1, or null if not bound. | ||
191 | * @return the (partial) match object. | ||
192 | * | ||
193 | */ | ||
194 | public static NoEntryInRegion.Match newMatch(final Region pR1) { | ||
195 | return new Immutable(pR1); | ||
196 | } | ||
197 | |||
198 | private static final class Mutable extends NoEntryInRegion.Match { | ||
199 | Mutable(final Region pR1) { | ||
200 | super(pR1); | ||
201 | } | ||
202 | |||
203 | @Override | ||
204 | public boolean isMutable() { | ||
205 | return true; | ||
206 | } | ||
207 | } | ||
208 | |||
209 | private static final class Immutable extends NoEntryInRegion.Match { | ||
210 | Immutable(final Region pR1) { | ||
211 | super(pR1); | ||
212 | } | ||
213 | |||
214 | @Override | ||
215 | public boolean isMutable() { | ||
216 | return false; | ||
217 | } | ||
218 | } | ||
219 | } | ||
220 | |||
221 | /** | ||
222 | * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.noEntryInRegion pattern, | ||
223 | * providing pattern-specific query methods. | ||
224 | * | ||
225 | * <p>Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, | ||
226 | * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. | ||
227 | * | ||
228 | * <p>Matches of the pattern will be represented as {@link Match}. | ||
229 | * | ||
230 | * <p>Original source: | ||
231 | * <code><pre> | ||
232 | * {@literal @}Constraint(severity="error", message="error", key = {r1}) | ||
233 | * pattern noEntryInRegion(r1 : Region) { | ||
234 | * neg find entryInRegion(r1, _); | ||
235 | * } | ||
236 | * </pre></code> | ||
237 | * | ||
238 | * @see Match | ||
239 | * @see NoEntryInRegion | ||
240 | * | ||
241 | */ | ||
242 | public static class Matcher extends BaseMatcher<NoEntryInRegion.Match> { | ||
243 | /** | ||
244 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
245 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
246 | * | ||
247 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
248 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
249 | * | ||
250 | */ | ||
251 | public static NoEntryInRegion.Matcher on(final ViatraQueryEngine engine) { | ||
252 | // check if matcher already exists | ||
253 | Matcher matcher = engine.getExistingMatcher(querySpecification()); | ||
254 | if (matcher == null) { | ||
255 | matcher = (Matcher)engine.getMatcher(querySpecification()); | ||
256 | } | ||
257 | return matcher; | ||
258 | } | ||
259 | |||
260 | /** | ||
261 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
262 | * @return an initialized matcher | ||
263 | * @noreference This method is for internal matcher initialization by the framework, do not call it manually. | ||
264 | * | ||
265 | */ | ||
266 | public static NoEntryInRegion.Matcher create() { | ||
267 | return new Matcher(); | ||
268 | } | ||
269 | |||
270 | private final static int POSITION_R1 = 0; | ||
271 | |||
272 | private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(NoEntryInRegion.Matcher.class); | ||
273 | |||
274 | /** | ||
275 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
276 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
277 | * | ||
278 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
279 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
280 | * | ||
281 | */ | ||
282 | private Matcher() { | ||
283 | super(querySpecification()); | ||
284 | } | ||
285 | |||
286 | /** | ||
287 | * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. | ||
288 | * @param pR1 the fixed value of pattern parameter r1, or null if not bound. | ||
289 | * @return matches represented as a Match object. | ||
290 | * | ||
291 | */ | ||
292 | public Collection<NoEntryInRegion.Match> getAllMatches(final Region pR1) { | ||
293 | return rawStreamAllMatches(new Object[]{pR1}).collect(Collectors.toSet()); | ||
294 | } | ||
295 | |||
296 | /** | ||
297 | * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. | ||
298 | * </p> | ||
299 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
300 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
301 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
302 | * @param pR1 the fixed value of pattern parameter r1, or null if not bound. | ||
303 | * @return a stream of matches represented as a Match object. | ||
304 | * | ||
305 | */ | ||
306 | public Stream<NoEntryInRegion.Match> streamAllMatches(final Region pR1) { | ||
307 | return rawStreamAllMatches(new Object[]{pR1}); | ||
308 | } | ||
309 | |||
310 | /** | ||
311 | * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
312 | * Neither determinism nor randomness of selection is guaranteed. | ||
313 | * @param pR1 the fixed value of pattern parameter r1, or null if not bound. | ||
314 | * @return a match represented as a Match object, or null if no match is found. | ||
315 | * | ||
316 | */ | ||
317 | public Optional<NoEntryInRegion.Match> getOneArbitraryMatch(final Region pR1) { | ||
318 | return rawGetOneArbitraryMatch(new Object[]{pR1}); | ||
319 | } | ||
320 | |||
321 | /** | ||
322 | * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, | ||
323 | * under any possible substitution of the unspecified parameters (if any). | ||
324 | * @param pR1 the fixed value of pattern parameter r1, or null if not bound. | ||
325 | * @return true if the input is a valid (partial) match of the pattern. | ||
326 | * | ||
327 | */ | ||
328 | public boolean hasMatch(final Region pR1) { | ||
329 | return rawHasMatch(new Object[]{pR1}); | ||
330 | } | ||
331 | |||
332 | /** | ||
333 | * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. | ||
334 | * @param pR1 the fixed value of pattern parameter r1, or null if not bound. | ||
335 | * @return the number of pattern matches found. | ||
336 | * | ||
337 | */ | ||
338 | public int countMatches(final Region pR1) { | ||
339 | return rawCountMatches(new Object[]{pR1}); | ||
340 | } | ||
341 | |||
342 | /** | ||
343 | * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
344 | * Neither determinism nor randomness of selection is guaranteed. | ||
345 | * @param pR1 the fixed value of pattern parameter r1, or null if not bound. | ||
346 | * @param processor the action that will process the selected match. | ||
347 | * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked | ||
348 | * | ||
349 | */ | ||
350 | public boolean forOneArbitraryMatch(final Region pR1, final Consumer<? super NoEntryInRegion.Match> processor) { | ||
351 | return rawForOneArbitraryMatch(new Object[]{pR1}, processor); | ||
352 | } | ||
353 | |||
354 | /** | ||
355 | * Returns a new (partial) match. | ||
356 | * This can be used e.g. to call the matcher with a partial match. | ||
357 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
358 | * @param pR1 the fixed value of pattern parameter r1, or null if not bound. | ||
359 | * @return the (partial) match object. | ||
360 | * | ||
361 | */ | ||
362 | public NoEntryInRegion.Match newMatch(final Region pR1) { | ||
363 | return NoEntryInRegion.Match.newMatch(pR1); | ||
364 | } | ||
365 | |||
366 | /** | ||
367 | * Retrieve the set of values that occur in matches for r1. | ||
368 | * @return the Set of all values or empty set if there are no matches | ||
369 | * | ||
370 | */ | ||
371 | protected Stream<Region> rawStreamAllValuesOfr1(final Object[] parameters) { | ||
372 | return rawStreamAllValues(POSITION_R1, parameters).map(Region.class::cast); | ||
373 | } | ||
374 | |||
375 | /** | ||
376 | * Retrieve the set of values that occur in matches for r1. | ||
377 | * @return the Set of all values or empty set if there are no matches | ||
378 | * | ||
379 | */ | ||
380 | public Set<Region> getAllValuesOfr1() { | ||
381 | return rawStreamAllValuesOfr1(emptyArray()).collect(Collectors.toSet()); | ||
382 | } | ||
383 | |||
384 | /** | ||
385 | * Retrieve the set of values that occur in matches for r1. | ||
386 | * @return the Set of all values or empty set if there are no matches | ||
387 | * | ||
388 | */ | ||
389 | public Stream<Region> streamAllValuesOfr1() { | ||
390 | return rawStreamAllValuesOfr1(emptyArray()); | ||
391 | } | ||
392 | |||
393 | @Override | ||
394 | protected NoEntryInRegion.Match tupleToMatch(final Tuple t) { | ||
395 | try { | ||
396 | return NoEntryInRegion.Match.newMatch((Region) t.get(POSITION_R1)); | ||
397 | } catch(ClassCastException e) { | ||
398 | LOGGER.error("Element(s) in tuple not properly typed!",e); | ||
399 | return null; | ||
400 | } | ||
401 | } | ||
402 | |||
403 | @Override | ||
404 | protected NoEntryInRegion.Match arrayToMatch(final Object[] match) { | ||
405 | try { | ||
406 | return NoEntryInRegion.Match.newMatch((Region) match[POSITION_R1]); | ||
407 | } catch(ClassCastException e) { | ||
408 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
409 | return null; | ||
410 | } | ||
411 | } | ||
412 | |||
413 | @Override | ||
414 | protected NoEntryInRegion.Match arrayToMatchMutable(final Object[] match) { | ||
415 | try { | ||
416 | return NoEntryInRegion.Match.newMutableMatch((Region) match[POSITION_R1]); | ||
417 | } catch(ClassCastException e) { | ||
418 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
419 | return null; | ||
420 | } | ||
421 | } | ||
422 | |||
423 | /** | ||
424 | * @return the singleton instance of the query specification of this pattern | ||
425 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
426 | * | ||
427 | */ | ||
428 | public static IQuerySpecification<NoEntryInRegion.Matcher> querySpecification() { | ||
429 | return NoEntryInRegion.instance(); | ||
430 | } | ||
431 | } | ||
432 | |||
433 | private NoEntryInRegion() { | ||
434 | super(GeneratedPQuery.INSTANCE); | ||
435 | } | ||
436 | |||
437 | /** | ||
438 | * @return the singleton instance of the query specification | ||
439 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
440 | * | ||
441 | */ | ||
442 | public static NoEntryInRegion instance() { | ||
443 | try{ | ||
444 | return LazyHolder.INSTANCE; | ||
445 | } catch (ExceptionInInitializerError err) { | ||
446 | throw processInitializerError(err); | ||
447 | } | ||
448 | } | ||
449 | |||
450 | @Override | ||
451 | protected NoEntryInRegion.Matcher instantiate(final ViatraQueryEngine engine) { | ||
452 | return NoEntryInRegion.Matcher.on(engine); | ||
453 | } | ||
454 | |||
455 | @Override | ||
456 | public NoEntryInRegion.Matcher instantiate() { | ||
457 | return NoEntryInRegion.Matcher.create(); | ||
458 | } | ||
459 | |||
460 | @Override | ||
461 | public NoEntryInRegion.Match newEmptyMatch() { | ||
462 | return NoEntryInRegion.Match.newEmptyMatch(); | ||
463 | } | ||
464 | |||
465 | @Override | ||
466 | public NoEntryInRegion.Match newMatch(final Object... parameters) { | ||
467 | return NoEntryInRegion.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Region) parameters[0]); | ||
468 | } | ||
469 | |||
470 | /** | ||
471 | * Inner class allowing the singleton instance of {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.NoEntryInRegion (visibility: PUBLIC, simpleName: NoEntryInRegion, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.NoEntryInRegion, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created | ||
472 | * <b>not</b> at the class load time of the outer class, | ||
473 | * but rather at the first call to {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.NoEntryInRegion (visibility: PUBLIC, simpleName: NoEntryInRegion, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.NoEntryInRegion, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. | ||
474 | * | ||
475 | * <p> This workaround is required e.g. to support recursion. | ||
476 | * | ||
477 | */ | ||
478 | private static class LazyHolder { | ||
479 | private final static NoEntryInRegion INSTANCE = new NoEntryInRegion(); | ||
480 | |||
481 | /** | ||
482 | * Statically initializes the query specification <b>after</b> the field {@link #INSTANCE} is assigned. | ||
483 | * This initialization order is required to support indirect recursion. | ||
484 | * | ||
485 | * <p> The static initializer is defined using a helper field to work around limitations of the code generator. | ||
486 | * | ||
487 | */ | ||
488 | private final static Object STATIC_INITIALIZER = ensureInitialized(); | ||
489 | |||
490 | public static Object ensureInitialized() { | ||
491 | INSTANCE.ensureInitializedInternal(); | ||
492 | return null; | ||
493 | } | ||
494 | } | ||
495 | |||
496 | private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { | ||
497 | private final static NoEntryInRegion.GeneratedPQuery INSTANCE = new GeneratedPQuery(); | ||
498 | |||
499 | private final PParameter parameter_r1 = new PParameter("r1", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Region", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Region")), PParameterDirection.INOUT); | ||
500 | |||
501 | private final List<PParameter> parameters = Arrays.asList(parameter_r1); | ||
502 | |||
503 | private GeneratedPQuery() { | ||
504 | super(PVisibility.PUBLIC); | ||
505 | } | ||
506 | |||
507 | @Override | ||
508 | public String getFullyQualifiedName() { | ||
509 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.noEntryInRegion"; | ||
510 | } | ||
511 | |||
512 | @Override | ||
513 | public List<String> getParameterNames() { | ||
514 | return Arrays.asList("r1"); | ||
515 | } | ||
516 | |||
517 | @Override | ||
518 | public List<PParameter> getParameters() { | ||
519 | return parameters; | ||
520 | } | ||
521 | |||
522 | @Override | ||
523 | public Set<PBody> doGetContainedBodies() { | ||
524 | setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); | ||
525 | Set<PBody> bodies = new LinkedHashSet<>(); | ||
526 | { | ||
527 | PBody body = new PBody(this); | ||
528 | PVariable var_r1 = body.getOrCreateVariableByName("r1"); | ||
529 | PVariable var___0_ = body.getOrCreateVariableByName("_<0>"); | ||
530 | new TypeConstraint(body, Tuples.flatTupleOf(var_r1), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Region"))); | ||
531 | body.setSymbolicParameters(Arrays.<ExportedParameter>asList( | ||
532 | new ExportedParameter(body, var_r1, parameter_r1) | ||
533 | )); | ||
534 | // neg find entryInRegion(r1, _) | ||
535 | new NegativePatternCall(body, Tuples.flatTupleOf(var_r1, var___0_), EntryInRegion.instance().getInternalQueryRepresentation()); | ||
536 | bodies.add(body); | ||
537 | } | ||
538 | { | ||
539 | PAnnotation annotation = new PAnnotation("Constraint"); | ||
540 | annotation.addAttribute("severity", "error"); | ||
541 | annotation.addAttribute("message", "error"); | ||
542 | annotation.addAttribute("key", Arrays.asList(new Object[] { | ||
543 | new ParameterReference("r1") | ||
544 | })); | ||
545 | addAnnotation(annotation); | ||
546 | } | ||
547 | return bodies; | ||
548 | } | ||
549 | } | ||
550 | } | ||
diff --git a/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/NoOutgoingTransitionFromEntry.java b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/NoOutgoingTransitionFromEntry.java new file mode 100644 index 00000000..d9a3de50 --- /dev/null +++ b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/NoOutgoingTransitionFromEntry.java | |||
@@ -0,0 +1,551 @@ | |||
1 | /** | ||
2 | * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql | ||
3 | */ | ||
4 | package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; | ||
5 | |||
6 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Entry; | ||
7 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.Transition; | ||
8 | import java.util.Arrays; | ||
9 | import java.util.Collection; | ||
10 | import java.util.LinkedHashSet; | ||
11 | import java.util.List; | ||
12 | import java.util.Objects; | ||
13 | import java.util.Optional; | ||
14 | import java.util.Set; | ||
15 | import java.util.function.Consumer; | ||
16 | import java.util.stream.Collectors; | ||
17 | import java.util.stream.Stream; | ||
18 | import org.apache.log4j.Logger; | ||
19 | import org.eclipse.emf.ecore.EClass; | ||
20 | import org.eclipse.viatra.query.runtime.api.IPatternMatch; | ||
21 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification; | ||
22 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; | ||
23 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; | ||
24 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; | ||
25 | import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; | ||
26 | import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; | ||
27 | import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; | ||
28 | import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; | ||
29 | import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; | ||
30 | import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; | ||
31 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; | ||
32 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; | ||
33 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; | ||
34 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.NegativePatternCall; | ||
35 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; | ||
36 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; | ||
37 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; | ||
38 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; | ||
39 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; | ||
40 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | ||
41 | import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; | ||
42 | |||
43 | /** | ||
44 | * A pattern-specific query specification that can instantiate Matcher in a type-safe way. | ||
45 | * | ||
46 | * <p>Original source: | ||
47 | * <code><pre> | ||
48 | * {@literal @}Constraint(severity="error", message="error", key = {e}) | ||
49 | * pattern noOutgoingTransitionFromEntry(e : Entry) { | ||
50 | * neg find transition(_, e, _); | ||
51 | * } | ||
52 | * </pre></code> | ||
53 | * | ||
54 | * @see Matcher | ||
55 | * @see Match | ||
56 | * | ||
57 | */ | ||
58 | @SuppressWarnings("all") | ||
59 | public final class NoOutgoingTransitionFromEntry extends BaseGeneratedEMFQuerySpecification<NoOutgoingTransitionFromEntry.Matcher> { | ||
60 | /** | ||
61 | * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.noOutgoingTransitionFromEntry pattern, | ||
62 | * to be used in conjunction with {@link Matcher}. | ||
63 | * | ||
64 | * <p>Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. | ||
65 | * Each instance is a (possibly partial) substitution of pattern parameters, | ||
66 | * usable to represent a match of the pattern in the result of a query, | ||
67 | * or to specify the bound (fixed) input parameters when issuing a query. | ||
68 | * | ||
69 | * @see Matcher | ||
70 | * | ||
71 | */ | ||
72 | public static abstract class Match extends BasePatternMatch { | ||
73 | private Entry fE; | ||
74 | |||
75 | private static List<String> parameterNames = makeImmutableList("e"); | ||
76 | |||
77 | private Match(final Entry pE) { | ||
78 | this.fE = pE; | ||
79 | } | ||
80 | |||
81 | @Override | ||
82 | public Object get(final String parameterName) { | ||
83 | if ("e".equals(parameterName)) return this.fE; | ||
84 | return null; | ||
85 | } | ||
86 | |||
87 | public Entry getE() { | ||
88 | return this.fE; | ||
89 | } | ||
90 | |||
91 | @Override | ||
92 | public boolean set(final String parameterName, final Object newValue) { | ||
93 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
94 | if ("e".equals(parameterName) ) { | ||
95 | this.fE = (Entry) newValue; | ||
96 | return true; | ||
97 | } | ||
98 | return false; | ||
99 | } | ||
100 | |||
101 | public void setE(final Entry pE) { | ||
102 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
103 | this.fE = pE; | ||
104 | } | ||
105 | |||
106 | @Override | ||
107 | public String patternName() { | ||
108 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.noOutgoingTransitionFromEntry"; | ||
109 | } | ||
110 | |||
111 | @Override | ||
112 | public List<String> parameterNames() { | ||
113 | return NoOutgoingTransitionFromEntry.Match.parameterNames; | ||
114 | } | ||
115 | |||
116 | @Override | ||
117 | public Object[] toArray() { | ||
118 | return new Object[]{fE}; | ||
119 | } | ||
120 | |||
121 | @Override | ||
122 | public NoOutgoingTransitionFromEntry.Match toImmutable() { | ||
123 | return isMutable() ? newMatch(fE) : this; | ||
124 | } | ||
125 | |||
126 | @Override | ||
127 | public String prettyPrint() { | ||
128 | StringBuilder result = new StringBuilder(); | ||
129 | result.append("\"e\"=" + prettyPrintValue(fE)); | ||
130 | return result.toString(); | ||
131 | } | ||
132 | |||
133 | @Override | ||
134 | public int hashCode() { | ||
135 | return Objects.hash(fE); | ||
136 | } | ||
137 | |||
138 | @Override | ||
139 | public boolean equals(final Object obj) { | ||
140 | if (this == obj) | ||
141 | return true; | ||
142 | if (obj == null) { | ||
143 | return false; | ||
144 | } | ||
145 | if ((obj instanceof NoOutgoingTransitionFromEntry.Match)) { | ||
146 | NoOutgoingTransitionFromEntry.Match other = (NoOutgoingTransitionFromEntry.Match) obj; | ||
147 | return Objects.equals(fE, other.fE); | ||
148 | } else { | ||
149 | // this should be infrequent | ||
150 | if (!(obj instanceof IPatternMatch)) { | ||
151 | return false; | ||
152 | } | ||
153 | IPatternMatch otherSig = (IPatternMatch) obj; | ||
154 | return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); | ||
155 | } | ||
156 | } | ||
157 | |||
158 | @Override | ||
159 | public NoOutgoingTransitionFromEntry specification() { | ||
160 | return NoOutgoingTransitionFromEntry.instance(); | ||
161 | } | ||
162 | |||
163 | /** | ||
164 | * Returns an empty, mutable match. | ||
165 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
166 | * | ||
167 | * @return the empty match. | ||
168 | * | ||
169 | */ | ||
170 | public static NoOutgoingTransitionFromEntry.Match newEmptyMatch() { | ||
171 | return new Mutable(null); | ||
172 | } | ||
173 | |||
174 | /** | ||
175 | * Returns a mutable (partial) match. | ||
176 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
177 | * | ||
178 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
179 | * @return the new, mutable (partial) match object. | ||
180 | * | ||
181 | */ | ||
182 | public static NoOutgoingTransitionFromEntry.Match newMutableMatch(final Entry pE) { | ||
183 | return new Mutable(pE); | ||
184 | } | ||
185 | |||
186 | /** | ||
187 | * Returns a new (partial) match. | ||
188 | * This can be used e.g. to call the matcher with a partial match. | ||
189 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
190 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
191 | * @return the (partial) match object. | ||
192 | * | ||
193 | */ | ||
194 | public static NoOutgoingTransitionFromEntry.Match newMatch(final Entry pE) { | ||
195 | return new Immutable(pE); | ||
196 | } | ||
197 | |||
198 | private static final class Mutable extends NoOutgoingTransitionFromEntry.Match { | ||
199 | Mutable(final Entry pE) { | ||
200 | super(pE); | ||
201 | } | ||
202 | |||
203 | @Override | ||
204 | public boolean isMutable() { | ||
205 | return true; | ||
206 | } | ||
207 | } | ||
208 | |||
209 | private static final class Immutable extends NoOutgoingTransitionFromEntry.Match { | ||
210 | Immutable(final Entry pE) { | ||
211 | super(pE); | ||
212 | } | ||
213 | |||
214 | @Override | ||
215 | public boolean isMutable() { | ||
216 | return false; | ||
217 | } | ||
218 | } | ||
219 | } | ||
220 | |||
221 | /** | ||
222 | * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.noOutgoingTransitionFromEntry pattern, | ||
223 | * providing pattern-specific query methods. | ||
224 | * | ||
225 | * <p>Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, | ||
226 | * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. | ||
227 | * | ||
228 | * <p>Matches of the pattern will be represented as {@link Match}. | ||
229 | * | ||
230 | * <p>Original source: | ||
231 | * <code><pre> | ||
232 | * {@literal @}Constraint(severity="error", message="error", key = {e}) | ||
233 | * pattern noOutgoingTransitionFromEntry(e : Entry) { | ||
234 | * neg find transition(_, e, _); | ||
235 | * } | ||
236 | * </pre></code> | ||
237 | * | ||
238 | * @see Match | ||
239 | * @see NoOutgoingTransitionFromEntry | ||
240 | * | ||
241 | */ | ||
242 | public static class Matcher extends BaseMatcher<NoOutgoingTransitionFromEntry.Match> { | ||
243 | /** | ||
244 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
245 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
246 | * | ||
247 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
248 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
249 | * | ||
250 | */ | ||
251 | public static NoOutgoingTransitionFromEntry.Matcher on(final ViatraQueryEngine engine) { | ||
252 | // check if matcher already exists | ||
253 | Matcher matcher = engine.getExistingMatcher(querySpecification()); | ||
254 | if (matcher == null) { | ||
255 | matcher = (Matcher)engine.getMatcher(querySpecification()); | ||
256 | } | ||
257 | return matcher; | ||
258 | } | ||
259 | |||
260 | /** | ||
261 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
262 | * @return an initialized matcher | ||
263 | * @noreference This method is for internal matcher initialization by the framework, do not call it manually. | ||
264 | * | ||
265 | */ | ||
266 | public static NoOutgoingTransitionFromEntry.Matcher create() { | ||
267 | return new Matcher(); | ||
268 | } | ||
269 | |||
270 | private final static int POSITION_E = 0; | ||
271 | |||
272 | private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(NoOutgoingTransitionFromEntry.Matcher.class); | ||
273 | |||
274 | /** | ||
275 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
276 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
277 | * | ||
278 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
279 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
280 | * | ||
281 | */ | ||
282 | private Matcher() { | ||
283 | super(querySpecification()); | ||
284 | } | ||
285 | |||
286 | /** | ||
287 | * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. | ||
288 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
289 | * @return matches represented as a Match object. | ||
290 | * | ||
291 | */ | ||
292 | public Collection<NoOutgoingTransitionFromEntry.Match> getAllMatches(final Entry pE) { | ||
293 | return rawStreamAllMatches(new Object[]{pE}).collect(Collectors.toSet()); | ||
294 | } | ||
295 | |||
296 | /** | ||
297 | * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. | ||
298 | * </p> | ||
299 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
300 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
301 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
302 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
303 | * @return a stream of matches represented as a Match object. | ||
304 | * | ||
305 | */ | ||
306 | public Stream<NoOutgoingTransitionFromEntry.Match> streamAllMatches(final Entry pE) { | ||
307 | return rawStreamAllMatches(new Object[]{pE}); | ||
308 | } | ||
309 | |||
310 | /** | ||
311 | * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
312 | * Neither determinism nor randomness of selection is guaranteed. | ||
313 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
314 | * @return a match represented as a Match object, or null if no match is found. | ||
315 | * | ||
316 | */ | ||
317 | public Optional<NoOutgoingTransitionFromEntry.Match> getOneArbitraryMatch(final Entry pE) { | ||
318 | return rawGetOneArbitraryMatch(new Object[]{pE}); | ||
319 | } | ||
320 | |||
321 | /** | ||
322 | * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, | ||
323 | * under any possible substitution of the unspecified parameters (if any). | ||
324 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
325 | * @return true if the input is a valid (partial) match of the pattern. | ||
326 | * | ||
327 | */ | ||
328 | public boolean hasMatch(final Entry pE) { | ||
329 | return rawHasMatch(new Object[]{pE}); | ||
330 | } | ||
331 | |||
332 | /** | ||
333 | * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. | ||
334 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
335 | * @return the number of pattern matches found. | ||
336 | * | ||
337 | */ | ||
338 | public int countMatches(final Entry pE) { | ||
339 | return rawCountMatches(new Object[]{pE}); | ||
340 | } | ||
341 | |||
342 | /** | ||
343 | * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
344 | * Neither determinism nor randomness of selection is guaranteed. | ||
345 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
346 | * @param processor the action that will process the selected match. | ||
347 | * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked | ||
348 | * | ||
349 | */ | ||
350 | public boolean forOneArbitraryMatch(final Entry pE, final Consumer<? super NoOutgoingTransitionFromEntry.Match> processor) { | ||
351 | return rawForOneArbitraryMatch(new Object[]{pE}, processor); | ||
352 | } | ||
353 | |||
354 | /** | ||
355 | * Returns a new (partial) match. | ||
356 | * This can be used e.g. to call the matcher with a partial match. | ||
357 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
358 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
359 | * @return the (partial) match object. | ||
360 | * | ||
361 | */ | ||
362 | public NoOutgoingTransitionFromEntry.Match newMatch(final Entry pE) { | ||
363 | return NoOutgoingTransitionFromEntry.Match.newMatch(pE); | ||
364 | } | ||
365 | |||
366 | /** | ||
367 | * Retrieve the set of values that occur in matches for e. | ||
368 | * @return the Set of all values or empty set if there are no matches | ||
369 | * | ||
370 | */ | ||
371 | protected Stream<Entry> rawStreamAllValuesOfe(final Object[] parameters) { | ||
372 | return rawStreamAllValues(POSITION_E, parameters).map(Entry.class::cast); | ||
373 | } | ||
374 | |||
375 | /** | ||
376 | * Retrieve the set of values that occur in matches for e. | ||
377 | * @return the Set of all values or empty set if there are no matches | ||
378 | * | ||
379 | */ | ||
380 | public Set<Entry> getAllValuesOfe() { | ||
381 | return rawStreamAllValuesOfe(emptyArray()).collect(Collectors.toSet()); | ||
382 | } | ||
383 | |||
384 | /** | ||
385 | * Retrieve the set of values that occur in matches for e. | ||
386 | * @return the Set of all values or empty set if there are no matches | ||
387 | * | ||
388 | */ | ||
389 | public Stream<Entry> streamAllValuesOfe() { | ||
390 | return rawStreamAllValuesOfe(emptyArray()); | ||
391 | } | ||
392 | |||
393 | @Override | ||
394 | protected NoOutgoingTransitionFromEntry.Match tupleToMatch(final Tuple t) { | ||
395 | try { | ||
396 | return NoOutgoingTransitionFromEntry.Match.newMatch((Entry) t.get(POSITION_E)); | ||
397 | } catch(ClassCastException e) { | ||
398 | LOGGER.error("Element(s) in tuple not properly typed!",e); | ||
399 | return null; | ||
400 | } | ||
401 | } | ||
402 | |||
403 | @Override | ||
404 | protected NoOutgoingTransitionFromEntry.Match arrayToMatch(final Object[] match) { | ||
405 | try { | ||
406 | return NoOutgoingTransitionFromEntry.Match.newMatch((Entry) match[POSITION_E]); | ||
407 | } catch(ClassCastException e) { | ||
408 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
409 | return null; | ||
410 | } | ||
411 | } | ||
412 | |||
413 | @Override | ||
414 | protected NoOutgoingTransitionFromEntry.Match arrayToMatchMutable(final Object[] match) { | ||
415 | try { | ||
416 | return NoOutgoingTransitionFromEntry.Match.newMutableMatch((Entry) match[POSITION_E]); | ||
417 | } catch(ClassCastException e) { | ||
418 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
419 | return null; | ||
420 | } | ||
421 | } | ||
422 | |||
423 | /** | ||
424 | * @return the singleton instance of the query specification of this pattern | ||
425 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
426 | * | ||
427 | */ | ||
428 | public static IQuerySpecification<NoOutgoingTransitionFromEntry.Matcher> querySpecification() { | ||
429 | return NoOutgoingTransitionFromEntry.instance(); | ||
430 | } | ||
431 | } | ||
432 | |||
433 | private NoOutgoingTransitionFromEntry() { | ||
434 | super(GeneratedPQuery.INSTANCE); | ||
435 | } | ||
436 | |||
437 | /** | ||
438 | * @return the singleton instance of the query specification | ||
439 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
440 | * | ||
441 | */ | ||
442 | public static NoOutgoingTransitionFromEntry instance() { | ||
443 | try{ | ||
444 | return LazyHolder.INSTANCE; | ||
445 | } catch (ExceptionInInitializerError err) { | ||
446 | throw processInitializerError(err); | ||
447 | } | ||
448 | } | ||
449 | |||
450 | @Override | ||
451 | protected NoOutgoingTransitionFromEntry.Matcher instantiate(final ViatraQueryEngine engine) { | ||
452 | return NoOutgoingTransitionFromEntry.Matcher.on(engine); | ||
453 | } | ||
454 | |||
455 | @Override | ||
456 | public NoOutgoingTransitionFromEntry.Matcher instantiate() { | ||
457 | return NoOutgoingTransitionFromEntry.Matcher.create(); | ||
458 | } | ||
459 | |||
460 | @Override | ||
461 | public NoOutgoingTransitionFromEntry.Match newEmptyMatch() { | ||
462 | return NoOutgoingTransitionFromEntry.Match.newEmptyMatch(); | ||
463 | } | ||
464 | |||
465 | @Override | ||
466 | public NoOutgoingTransitionFromEntry.Match newMatch(final Object... parameters) { | ||
467 | return NoOutgoingTransitionFromEntry.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Entry) parameters[0]); | ||
468 | } | ||
469 | |||
470 | /** | ||
471 | * Inner class allowing the singleton instance of {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.NoOutgoingTransitionFromEntry (visibility: PUBLIC, simpleName: NoOutgoingTransitionFromEntry, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.NoOutgoingTransitionFromEntry, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created | ||
472 | * <b>not</b> at the class load time of the outer class, | ||
473 | * but rather at the first call to {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.NoOutgoingTransitionFromEntry (visibility: PUBLIC, simpleName: NoOutgoingTransitionFromEntry, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.NoOutgoingTransitionFromEntry, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. | ||
474 | * | ||
475 | * <p> This workaround is required e.g. to support recursion. | ||
476 | * | ||
477 | */ | ||
478 | private static class LazyHolder { | ||
479 | private final static NoOutgoingTransitionFromEntry INSTANCE = new NoOutgoingTransitionFromEntry(); | ||
480 | |||
481 | /** | ||
482 | * Statically initializes the query specification <b>after</b> the field {@link #INSTANCE} is assigned. | ||
483 | * This initialization order is required to support indirect recursion. | ||
484 | * | ||
485 | * <p> The static initializer is defined using a helper field to work around limitations of the code generator. | ||
486 | * | ||
487 | */ | ||
488 | private final static Object STATIC_INITIALIZER = ensureInitialized(); | ||
489 | |||
490 | public static Object ensureInitialized() { | ||
491 | INSTANCE.ensureInitializedInternal(); | ||
492 | return null; | ||
493 | } | ||
494 | } | ||
495 | |||
496 | private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { | ||
497 | private final static NoOutgoingTransitionFromEntry.GeneratedPQuery INSTANCE = new GeneratedPQuery(); | ||
498 | |||
499 | private final PParameter parameter_e = new PParameter("e", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Entry", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Entry")), PParameterDirection.INOUT); | ||
500 | |||
501 | private final List<PParameter> parameters = Arrays.asList(parameter_e); | ||
502 | |||
503 | private GeneratedPQuery() { | ||
504 | super(PVisibility.PUBLIC); | ||
505 | } | ||
506 | |||
507 | @Override | ||
508 | public String getFullyQualifiedName() { | ||
509 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.noOutgoingTransitionFromEntry"; | ||
510 | } | ||
511 | |||
512 | @Override | ||
513 | public List<String> getParameterNames() { | ||
514 | return Arrays.asList("e"); | ||
515 | } | ||
516 | |||
517 | @Override | ||
518 | public List<PParameter> getParameters() { | ||
519 | return parameters; | ||
520 | } | ||
521 | |||
522 | @Override | ||
523 | public Set<PBody> doGetContainedBodies() { | ||
524 | setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); | ||
525 | Set<PBody> bodies = new LinkedHashSet<>(); | ||
526 | { | ||
527 | PBody body = new PBody(this); | ||
528 | PVariable var_e = body.getOrCreateVariableByName("e"); | ||
529 | PVariable var___0_ = body.getOrCreateVariableByName("_<0>"); | ||
530 | PVariable var___1_ = body.getOrCreateVariableByName("_<1>"); | ||
531 | new TypeConstraint(body, Tuples.flatTupleOf(var_e), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Entry"))); | ||
532 | body.setSymbolicParameters(Arrays.<ExportedParameter>asList( | ||
533 | new ExportedParameter(body, var_e, parameter_e) | ||
534 | )); | ||
535 | // neg find transition(_, e, _) | ||
536 | new NegativePatternCall(body, Tuples.flatTupleOf(var___0_, var_e, var___1_), Transition.instance().getInternalQueryRepresentation()); | ||
537 | bodies.add(body); | ||
538 | } | ||
539 | { | ||
540 | PAnnotation annotation = new PAnnotation("Constraint"); | ||
541 | annotation.addAttribute("severity", "error"); | ||
542 | annotation.addAttribute("message", "error"); | ||
543 | annotation.addAttribute("key", Arrays.asList(new Object[] { | ||
544 | new ParameterReference("e") | ||
545 | })); | ||
546 | addAnnotation(annotation); | ||
547 | } | ||
548 | return bodies; | ||
549 | } | ||
550 | } | ||
551 | } | ||
diff --git a/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/NoStateInRegion.java b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/NoStateInRegion.java new file mode 100644 index 00000000..841339ae --- /dev/null +++ b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/NoStateInRegion.java | |||
@@ -0,0 +1,558 @@ | |||
1 | /** | ||
2 | * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql | ||
3 | */ | ||
4 | package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; | ||
5 | |||
6 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Region; | ||
7 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.StateInRegion; | ||
8 | import java.util.Arrays; | ||
9 | import java.util.Collection; | ||
10 | import java.util.LinkedHashSet; | ||
11 | import java.util.List; | ||
12 | import java.util.Objects; | ||
13 | import java.util.Optional; | ||
14 | import java.util.Set; | ||
15 | import java.util.function.Consumer; | ||
16 | import java.util.stream.Collectors; | ||
17 | import java.util.stream.Stream; | ||
18 | import org.apache.log4j.Logger; | ||
19 | import org.eclipse.emf.ecore.EClass; | ||
20 | import org.eclipse.viatra.query.runtime.api.IPatternMatch; | ||
21 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification; | ||
22 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; | ||
23 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; | ||
24 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; | ||
25 | import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; | ||
26 | import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; | ||
27 | import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; | ||
28 | import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; | ||
29 | import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; | ||
30 | import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; | ||
31 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; | ||
32 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; | ||
33 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; | ||
34 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.NegativePatternCall; | ||
35 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; | ||
36 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; | ||
37 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; | ||
38 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; | ||
39 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; | ||
40 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | ||
41 | import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; | ||
42 | |||
43 | /** | ||
44 | * A pattern-specific query specification that can instantiate Matcher in a type-safe way. | ||
45 | * | ||
46 | * <p>Original source: | ||
47 | * <code><pre> | ||
48 | * ///////// | ||
49 | * // State vs Region | ||
50 | * ///////// | ||
51 | * | ||
52 | * {@literal @}Constraint(severity="error", message="error", key = {region}) | ||
53 | * pattern noStateInRegion(region: Region) { | ||
54 | * neg find StateInRegion(region,_); | ||
55 | * } | ||
56 | * </pre></code> | ||
57 | * | ||
58 | * @see Matcher | ||
59 | * @see Match | ||
60 | * | ||
61 | */ | ||
62 | @SuppressWarnings("all") | ||
63 | public final class NoStateInRegion extends BaseGeneratedEMFQuerySpecification<NoStateInRegion.Matcher> { | ||
64 | /** | ||
65 | * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.noStateInRegion pattern, | ||
66 | * to be used in conjunction with {@link Matcher}. | ||
67 | * | ||
68 | * <p>Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. | ||
69 | * Each instance is a (possibly partial) substitution of pattern parameters, | ||
70 | * usable to represent a match of the pattern in the result of a query, | ||
71 | * or to specify the bound (fixed) input parameters when issuing a query. | ||
72 | * | ||
73 | * @see Matcher | ||
74 | * | ||
75 | */ | ||
76 | public static abstract class Match extends BasePatternMatch { | ||
77 | private Region fRegion; | ||
78 | |||
79 | private static List<String> parameterNames = makeImmutableList("region"); | ||
80 | |||
81 | private Match(final Region pRegion) { | ||
82 | this.fRegion = pRegion; | ||
83 | } | ||
84 | |||
85 | @Override | ||
86 | public Object get(final String parameterName) { | ||
87 | if ("region".equals(parameterName)) return this.fRegion; | ||
88 | return null; | ||
89 | } | ||
90 | |||
91 | public Region getRegion() { | ||
92 | return this.fRegion; | ||
93 | } | ||
94 | |||
95 | @Override | ||
96 | public boolean set(final String parameterName, final Object newValue) { | ||
97 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
98 | if ("region".equals(parameterName) ) { | ||
99 | this.fRegion = (Region) newValue; | ||
100 | return true; | ||
101 | } | ||
102 | return false; | ||
103 | } | ||
104 | |||
105 | public void setRegion(final Region pRegion) { | ||
106 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
107 | this.fRegion = pRegion; | ||
108 | } | ||
109 | |||
110 | @Override | ||
111 | public String patternName() { | ||
112 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.noStateInRegion"; | ||
113 | } | ||
114 | |||
115 | @Override | ||
116 | public List<String> parameterNames() { | ||
117 | return NoStateInRegion.Match.parameterNames; | ||
118 | } | ||
119 | |||
120 | @Override | ||
121 | public Object[] toArray() { | ||
122 | return new Object[]{fRegion}; | ||
123 | } | ||
124 | |||
125 | @Override | ||
126 | public NoStateInRegion.Match toImmutable() { | ||
127 | return isMutable() ? newMatch(fRegion) : this; | ||
128 | } | ||
129 | |||
130 | @Override | ||
131 | public String prettyPrint() { | ||
132 | StringBuilder result = new StringBuilder(); | ||
133 | result.append("\"region\"=" + prettyPrintValue(fRegion)); | ||
134 | return result.toString(); | ||
135 | } | ||
136 | |||
137 | @Override | ||
138 | public int hashCode() { | ||
139 | return Objects.hash(fRegion); | ||
140 | } | ||
141 | |||
142 | @Override | ||
143 | public boolean equals(final Object obj) { | ||
144 | if (this == obj) | ||
145 | return true; | ||
146 | if (obj == null) { | ||
147 | return false; | ||
148 | } | ||
149 | if ((obj instanceof NoStateInRegion.Match)) { | ||
150 | NoStateInRegion.Match other = (NoStateInRegion.Match) obj; | ||
151 | return Objects.equals(fRegion, other.fRegion); | ||
152 | } else { | ||
153 | // this should be infrequent | ||
154 | if (!(obj instanceof IPatternMatch)) { | ||
155 | return false; | ||
156 | } | ||
157 | IPatternMatch otherSig = (IPatternMatch) obj; | ||
158 | return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); | ||
159 | } | ||
160 | } | ||
161 | |||
162 | @Override | ||
163 | public NoStateInRegion specification() { | ||
164 | return NoStateInRegion.instance(); | ||
165 | } | ||
166 | |||
167 | /** | ||
168 | * Returns an empty, mutable match. | ||
169 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
170 | * | ||
171 | * @return the empty match. | ||
172 | * | ||
173 | */ | ||
174 | public static NoStateInRegion.Match newEmptyMatch() { | ||
175 | return new Mutable(null); | ||
176 | } | ||
177 | |||
178 | /** | ||
179 | * Returns a mutable (partial) match. | ||
180 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
181 | * | ||
182 | * @param pRegion the fixed value of pattern parameter region, or null if not bound. | ||
183 | * @return the new, mutable (partial) match object. | ||
184 | * | ||
185 | */ | ||
186 | public static NoStateInRegion.Match newMutableMatch(final Region pRegion) { | ||
187 | return new Mutable(pRegion); | ||
188 | } | ||
189 | |||
190 | /** | ||
191 | * Returns a new (partial) match. | ||
192 | * This can be used e.g. to call the matcher with a partial match. | ||
193 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
194 | * @param pRegion the fixed value of pattern parameter region, or null if not bound. | ||
195 | * @return the (partial) match object. | ||
196 | * | ||
197 | */ | ||
198 | public static NoStateInRegion.Match newMatch(final Region pRegion) { | ||
199 | return new Immutable(pRegion); | ||
200 | } | ||
201 | |||
202 | private static final class Mutable extends NoStateInRegion.Match { | ||
203 | Mutable(final Region pRegion) { | ||
204 | super(pRegion); | ||
205 | } | ||
206 | |||
207 | @Override | ||
208 | public boolean isMutable() { | ||
209 | return true; | ||
210 | } | ||
211 | } | ||
212 | |||
213 | private static final class Immutable extends NoStateInRegion.Match { | ||
214 | Immutable(final Region pRegion) { | ||
215 | super(pRegion); | ||
216 | } | ||
217 | |||
218 | @Override | ||
219 | public boolean isMutable() { | ||
220 | return false; | ||
221 | } | ||
222 | } | ||
223 | } | ||
224 | |||
225 | /** | ||
226 | * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.noStateInRegion pattern, | ||
227 | * providing pattern-specific query methods. | ||
228 | * | ||
229 | * <p>Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, | ||
230 | * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. | ||
231 | * | ||
232 | * <p>Matches of the pattern will be represented as {@link Match}. | ||
233 | * | ||
234 | * <p>Original source: | ||
235 | * <code><pre> | ||
236 | * ///////// | ||
237 | * // State vs Region | ||
238 | * ///////// | ||
239 | * | ||
240 | * {@literal @}Constraint(severity="error", message="error", key = {region}) | ||
241 | * pattern noStateInRegion(region: Region) { | ||
242 | * neg find StateInRegion(region,_); | ||
243 | * } | ||
244 | * </pre></code> | ||
245 | * | ||
246 | * @see Match | ||
247 | * @see NoStateInRegion | ||
248 | * | ||
249 | */ | ||
250 | public static class Matcher extends BaseMatcher<NoStateInRegion.Match> { | ||
251 | /** | ||
252 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
253 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
254 | * | ||
255 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
256 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
257 | * | ||
258 | */ | ||
259 | public static NoStateInRegion.Matcher on(final ViatraQueryEngine engine) { | ||
260 | // check if matcher already exists | ||
261 | Matcher matcher = engine.getExistingMatcher(querySpecification()); | ||
262 | if (matcher == null) { | ||
263 | matcher = (Matcher)engine.getMatcher(querySpecification()); | ||
264 | } | ||
265 | return matcher; | ||
266 | } | ||
267 | |||
268 | /** | ||
269 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
270 | * @return an initialized matcher | ||
271 | * @noreference This method is for internal matcher initialization by the framework, do not call it manually. | ||
272 | * | ||
273 | */ | ||
274 | public static NoStateInRegion.Matcher create() { | ||
275 | return new Matcher(); | ||
276 | } | ||
277 | |||
278 | private final static int POSITION_REGION = 0; | ||
279 | |||
280 | private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(NoStateInRegion.Matcher.class); | ||
281 | |||
282 | /** | ||
283 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
284 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
285 | * | ||
286 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
287 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
288 | * | ||
289 | */ | ||
290 | private Matcher() { | ||
291 | super(querySpecification()); | ||
292 | } | ||
293 | |||
294 | /** | ||
295 | * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. | ||
296 | * @param pRegion the fixed value of pattern parameter region, or null if not bound. | ||
297 | * @return matches represented as a Match object. | ||
298 | * | ||
299 | */ | ||
300 | public Collection<NoStateInRegion.Match> getAllMatches(final Region pRegion) { | ||
301 | return rawStreamAllMatches(new Object[]{pRegion}).collect(Collectors.toSet()); | ||
302 | } | ||
303 | |||
304 | /** | ||
305 | * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. | ||
306 | * </p> | ||
307 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
308 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
309 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
310 | * @param pRegion the fixed value of pattern parameter region, or null if not bound. | ||
311 | * @return a stream of matches represented as a Match object. | ||
312 | * | ||
313 | */ | ||
314 | public Stream<NoStateInRegion.Match> streamAllMatches(final Region pRegion) { | ||
315 | return rawStreamAllMatches(new Object[]{pRegion}); | ||
316 | } | ||
317 | |||
318 | /** | ||
319 | * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
320 | * Neither determinism nor randomness of selection is guaranteed. | ||
321 | * @param pRegion the fixed value of pattern parameter region, or null if not bound. | ||
322 | * @return a match represented as a Match object, or null if no match is found. | ||
323 | * | ||
324 | */ | ||
325 | public Optional<NoStateInRegion.Match> getOneArbitraryMatch(final Region pRegion) { | ||
326 | return rawGetOneArbitraryMatch(new Object[]{pRegion}); | ||
327 | } | ||
328 | |||
329 | /** | ||
330 | * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, | ||
331 | * under any possible substitution of the unspecified parameters (if any). | ||
332 | * @param pRegion the fixed value of pattern parameter region, or null if not bound. | ||
333 | * @return true if the input is a valid (partial) match of the pattern. | ||
334 | * | ||
335 | */ | ||
336 | public boolean hasMatch(final Region pRegion) { | ||
337 | return rawHasMatch(new Object[]{pRegion}); | ||
338 | } | ||
339 | |||
340 | /** | ||
341 | * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. | ||
342 | * @param pRegion the fixed value of pattern parameter region, or null if not bound. | ||
343 | * @return the number of pattern matches found. | ||
344 | * | ||
345 | */ | ||
346 | public int countMatches(final Region pRegion) { | ||
347 | return rawCountMatches(new Object[]{pRegion}); | ||
348 | } | ||
349 | |||
350 | /** | ||
351 | * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
352 | * Neither determinism nor randomness of selection is guaranteed. | ||
353 | * @param pRegion the fixed value of pattern parameter region, or null if not bound. | ||
354 | * @param processor the action that will process the selected match. | ||
355 | * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked | ||
356 | * | ||
357 | */ | ||
358 | public boolean forOneArbitraryMatch(final Region pRegion, final Consumer<? super NoStateInRegion.Match> processor) { | ||
359 | return rawForOneArbitraryMatch(new Object[]{pRegion}, processor); | ||
360 | } | ||
361 | |||
362 | /** | ||
363 | * Returns a new (partial) match. | ||
364 | * This can be used e.g. to call the matcher with a partial match. | ||
365 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
366 | * @param pRegion the fixed value of pattern parameter region, or null if not bound. | ||
367 | * @return the (partial) match object. | ||
368 | * | ||
369 | */ | ||
370 | public NoStateInRegion.Match newMatch(final Region pRegion) { | ||
371 | return NoStateInRegion.Match.newMatch(pRegion); | ||
372 | } | ||
373 | |||
374 | /** | ||
375 | * Retrieve the set of values that occur in matches for region. | ||
376 | * @return the Set of all values or empty set if there are no matches | ||
377 | * | ||
378 | */ | ||
379 | protected Stream<Region> rawStreamAllValuesOfregion(final Object[] parameters) { | ||
380 | return rawStreamAllValues(POSITION_REGION, parameters).map(Region.class::cast); | ||
381 | } | ||
382 | |||
383 | /** | ||
384 | * Retrieve the set of values that occur in matches for region. | ||
385 | * @return the Set of all values or empty set if there are no matches | ||
386 | * | ||
387 | */ | ||
388 | public Set<Region> getAllValuesOfregion() { | ||
389 | return rawStreamAllValuesOfregion(emptyArray()).collect(Collectors.toSet()); | ||
390 | } | ||
391 | |||
392 | /** | ||
393 | * Retrieve the set of values that occur in matches for region. | ||
394 | * @return the Set of all values or empty set if there are no matches | ||
395 | * | ||
396 | */ | ||
397 | public Stream<Region> streamAllValuesOfregion() { | ||
398 | return rawStreamAllValuesOfregion(emptyArray()); | ||
399 | } | ||
400 | |||
401 | @Override | ||
402 | protected NoStateInRegion.Match tupleToMatch(final Tuple t) { | ||
403 | try { | ||
404 | return NoStateInRegion.Match.newMatch((Region) t.get(POSITION_REGION)); | ||
405 | } catch(ClassCastException e) { | ||
406 | LOGGER.error("Element(s) in tuple not properly typed!",e); | ||
407 | return null; | ||
408 | } | ||
409 | } | ||
410 | |||
411 | @Override | ||
412 | protected NoStateInRegion.Match arrayToMatch(final Object[] match) { | ||
413 | try { | ||
414 | return NoStateInRegion.Match.newMatch((Region) match[POSITION_REGION]); | ||
415 | } catch(ClassCastException e) { | ||
416 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
417 | return null; | ||
418 | } | ||
419 | } | ||
420 | |||
421 | @Override | ||
422 | protected NoStateInRegion.Match arrayToMatchMutable(final Object[] match) { | ||
423 | try { | ||
424 | return NoStateInRegion.Match.newMutableMatch((Region) match[POSITION_REGION]); | ||
425 | } catch(ClassCastException e) { | ||
426 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
427 | return null; | ||
428 | } | ||
429 | } | ||
430 | |||
431 | /** | ||
432 | * @return the singleton instance of the query specification of this pattern | ||
433 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
434 | * | ||
435 | */ | ||
436 | public static IQuerySpecification<NoStateInRegion.Matcher> querySpecification() { | ||
437 | return NoStateInRegion.instance(); | ||
438 | } | ||
439 | } | ||
440 | |||
441 | private NoStateInRegion() { | ||
442 | super(GeneratedPQuery.INSTANCE); | ||
443 | } | ||
444 | |||
445 | /** | ||
446 | * @return the singleton instance of the query specification | ||
447 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
448 | * | ||
449 | */ | ||
450 | public static NoStateInRegion instance() { | ||
451 | try{ | ||
452 | return LazyHolder.INSTANCE; | ||
453 | } catch (ExceptionInInitializerError err) { | ||
454 | throw processInitializerError(err); | ||
455 | } | ||
456 | } | ||
457 | |||
458 | @Override | ||
459 | protected NoStateInRegion.Matcher instantiate(final ViatraQueryEngine engine) { | ||
460 | return NoStateInRegion.Matcher.on(engine); | ||
461 | } | ||
462 | |||
463 | @Override | ||
464 | public NoStateInRegion.Matcher instantiate() { | ||
465 | return NoStateInRegion.Matcher.create(); | ||
466 | } | ||
467 | |||
468 | @Override | ||
469 | public NoStateInRegion.Match newEmptyMatch() { | ||
470 | return NoStateInRegion.Match.newEmptyMatch(); | ||
471 | } | ||
472 | |||
473 | @Override | ||
474 | public NoStateInRegion.Match newMatch(final Object... parameters) { | ||
475 | return NoStateInRegion.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Region) parameters[0]); | ||
476 | } | ||
477 | |||
478 | /** | ||
479 | * Inner class allowing the singleton instance of {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.NoStateInRegion (visibility: PUBLIC, simpleName: NoStateInRegion, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.NoStateInRegion, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created | ||
480 | * <b>not</b> at the class load time of the outer class, | ||
481 | * but rather at the first call to {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.NoStateInRegion (visibility: PUBLIC, simpleName: NoStateInRegion, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.NoStateInRegion, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. | ||
482 | * | ||
483 | * <p> This workaround is required e.g. to support recursion. | ||
484 | * | ||
485 | */ | ||
486 | private static class LazyHolder { | ||
487 | private final static NoStateInRegion INSTANCE = new NoStateInRegion(); | ||
488 | |||
489 | /** | ||
490 | * Statically initializes the query specification <b>after</b> the field {@link #INSTANCE} is assigned. | ||
491 | * This initialization order is required to support indirect recursion. | ||
492 | * | ||
493 | * <p> The static initializer is defined using a helper field to work around limitations of the code generator. | ||
494 | * | ||
495 | */ | ||
496 | private final static Object STATIC_INITIALIZER = ensureInitialized(); | ||
497 | |||
498 | public static Object ensureInitialized() { | ||
499 | INSTANCE.ensureInitializedInternal(); | ||
500 | return null; | ||
501 | } | ||
502 | } | ||
503 | |||
504 | private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { | ||
505 | private final static NoStateInRegion.GeneratedPQuery INSTANCE = new GeneratedPQuery(); | ||
506 | |||
507 | private final PParameter parameter_region = new PParameter("region", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Region", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Region")), PParameterDirection.INOUT); | ||
508 | |||
509 | private final List<PParameter> parameters = Arrays.asList(parameter_region); | ||
510 | |||
511 | private GeneratedPQuery() { | ||
512 | super(PVisibility.PUBLIC); | ||
513 | } | ||
514 | |||
515 | @Override | ||
516 | public String getFullyQualifiedName() { | ||
517 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.noStateInRegion"; | ||
518 | } | ||
519 | |||
520 | @Override | ||
521 | public List<String> getParameterNames() { | ||
522 | return Arrays.asList("region"); | ||
523 | } | ||
524 | |||
525 | @Override | ||
526 | public List<PParameter> getParameters() { | ||
527 | return parameters; | ||
528 | } | ||
529 | |||
530 | @Override | ||
531 | public Set<PBody> doGetContainedBodies() { | ||
532 | setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); | ||
533 | Set<PBody> bodies = new LinkedHashSet<>(); | ||
534 | { | ||
535 | PBody body = new PBody(this); | ||
536 | PVariable var_region = body.getOrCreateVariableByName("region"); | ||
537 | PVariable var___0_ = body.getOrCreateVariableByName("_<0>"); | ||
538 | new TypeConstraint(body, Tuples.flatTupleOf(var_region), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Region"))); | ||
539 | body.setSymbolicParameters(Arrays.<ExportedParameter>asList( | ||
540 | new ExportedParameter(body, var_region, parameter_region) | ||
541 | )); | ||
542 | // neg find StateInRegion(region,_) | ||
543 | new NegativePatternCall(body, Tuples.flatTupleOf(var_region, var___0_), StateInRegion.instance().getInternalQueryRepresentation()); | ||
544 | bodies.add(body); | ||
545 | } | ||
546 | { | ||
547 | PAnnotation annotation = new PAnnotation("Constraint"); | ||
548 | annotation.addAttribute("severity", "error"); | ||
549 | annotation.addAttribute("message", "error"); | ||
550 | annotation.addAttribute("key", Arrays.asList(new Object[] { | ||
551 | new ParameterReference("region") | ||
552 | })); | ||
553 | addAnnotation(annotation); | ||
554 | } | ||
555 | return bodies; | ||
556 | } | ||
557 | } | ||
558 | } | ||
diff --git a/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/NotSynchronizingStates.java b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/NotSynchronizingStates.java new file mode 100644 index 00000000..b9a60ca9 --- /dev/null +++ b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/NotSynchronizingStates.java | |||
@@ -0,0 +1,554 @@ | |||
1 | /** | ||
2 | * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql | ||
3 | */ | ||
4 | package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; | ||
5 | |||
6 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization; | ||
7 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.HasMultipleIncomingTrainsition; | ||
8 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.HasMultipleOutgoingTrainsition; | ||
9 | import java.util.Arrays; | ||
10 | import java.util.Collection; | ||
11 | import java.util.LinkedHashSet; | ||
12 | import java.util.List; | ||
13 | import java.util.Objects; | ||
14 | import java.util.Optional; | ||
15 | import java.util.Set; | ||
16 | import java.util.function.Consumer; | ||
17 | import java.util.stream.Collectors; | ||
18 | import java.util.stream.Stream; | ||
19 | import org.apache.log4j.Logger; | ||
20 | import org.eclipse.emf.ecore.EClass; | ||
21 | import org.eclipse.viatra.query.runtime.api.IPatternMatch; | ||
22 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification; | ||
23 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; | ||
24 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; | ||
25 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; | ||
26 | import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; | ||
27 | import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; | ||
28 | import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; | ||
29 | import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; | ||
30 | import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; | ||
31 | import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; | ||
32 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; | ||
33 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; | ||
34 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; | ||
35 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.NegativePatternCall; | ||
36 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; | ||
37 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; | ||
38 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; | ||
39 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; | ||
40 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; | ||
41 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | ||
42 | import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; | ||
43 | |||
44 | /** | ||
45 | * A pattern-specific query specification that can instantiate Matcher in a type-safe way. | ||
46 | * | ||
47 | * <p>Original source: | ||
48 | * <code><pre> | ||
49 | * {@literal @}Constraint(severity="error", message="error", key = {s}) | ||
50 | * pattern notSynchronizingStates(s : Synchronization) { | ||
51 | * neg find hasMultipleOutgoingTrainsition(s); | ||
52 | * neg find hasMultipleIncomingTrainsition(s); | ||
53 | * } | ||
54 | * </pre></code> | ||
55 | * | ||
56 | * @see Matcher | ||
57 | * @see Match | ||
58 | * | ||
59 | */ | ||
60 | @SuppressWarnings("all") | ||
61 | public final class NotSynchronizingStates extends BaseGeneratedEMFQuerySpecification<NotSynchronizingStates.Matcher> { | ||
62 | /** | ||
63 | * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.notSynchronizingStates pattern, | ||
64 | * to be used in conjunction with {@link Matcher}. | ||
65 | * | ||
66 | * <p>Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. | ||
67 | * Each instance is a (possibly partial) substitution of pattern parameters, | ||
68 | * usable to represent a match of the pattern in the result of a query, | ||
69 | * or to specify the bound (fixed) input parameters when issuing a query. | ||
70 | * | ||
71 | * @see Matcher | ||
72 | * | ||
73 | */ | ||
74 | public static abstract class Match extends BasePatternMatch { | ||
75 | private Synchronization fS; | ||
76 | |||
77 | private static List<String> parameterNames = makeImmutableList("s"); | ||
78 | |||
79 | private Match(final Synchronization pS) { | ||
80 | this.fS = pS; | ||
81 | } | ||
82 | |||
83 | @Override | ||
84 | public Object get(final String parameterName) { | ||
85 | if ("s".equals(parameterName)) return this.fS; | ||
86 | return null; | ||
87 | } | ||
88 | |||
89 | public Synchronization getS() { | ||
90 | return this.fS; | ||
91 | } | ||
92 | |||
93 | @Override | ||
94 | public boolean set(final String parameterName, final Object newValue) { | ||
95 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
96 | if ("s".equals(parameterName) ) { | ||
97 | this.fS = (Synchronization) newValue; | ||
98 | return true; | ||
99 | } | ||
100 | return false; | ||
101 | } | ||
102 | |||
103 | public void setS(final Synchronization pS) { | ||
104 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
105 | this.fS = pS; | ||
106 | } | ||
107 | |||
108 | @Override | ||
109 | public String patternName() { | ||
110 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.notSynchronizingStates"; | ||
111 | } | ||
112 | |||
113 | @Override | ||
114 | public List<String> parameterNames() { | ||
115 | return NotSynchronizingStates.Match.parameterNames; | ||
116 | } | ||
117 | |||
118 | @Override | ||
119 | public Object[] toArray() { | ||
120 | return new Object[]{fS}; | ||
121 | } | ||
122 | |||
123 | @Override | ||
124 | public NotSynchronizingStates.Match toImmutable() { | ||
125 | return isMutable() ? newMatch(fS) : this; | ||
126 | } | ||
127 | |||
128 | @Override | ||
129 | public String prettyPrint() { | ||
130 | StringBuilder result = new StringBuilder(); | ||
131 | result.append("\"s\"=" + prettyPrintValue(fS)); | ||
132 | return result.toString(); | ||
133 | } | ||
134 | |||
135 | @Override | ||
136 | public int hashCode() { | ||
137 | return Objects.hash(fS); | ||
138 | } | ||
139 | |||
140 | @Override | ||
141 | public boolean equals(final Object obj) { | ||
142 | if (this == obj) | ||
143 | return true; | ||
144 | if (obj == null) { | ||
145 | return false; | ||
146 | } | ||
147 | if ((obj instanceof NotSynchronizingStates.Match)) { | ||
148 | NotSynchronizingStates.Match other = (NotSynchronizingStates.Match) obj; | ||
149 | return Objects.equals(fS, other.fS); | ||
150 | } else { | ||
151 | // this should be infrequent | ||
152 | if (!(obj instanceof IPatternMatch)) { | ||
153 | return false; | ||
154 | } | ||
155 | IPatternMatch otherSig = (IPatternMatch) obj; | ||
156 | return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); | ||
157 | } | ||
158 | } | ||
159 | |||
160 | @Override | ||
161 | public NotSynchronizingStates specification() { | ||
162 | return NotSynchronizingStates.instance(); | ||
163 | } | ||
164 | |||
165 | /** | ||
166 | * Returns an empty, mutable match. | ||
167 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
168 | * | ||
169 | * @return the empty match. | ||
170 | * | ||
171 | */ | ||
172 | public static NotSynchronizingStates.Match newEmptyMatch() { | ||
173 | return new Mutable(null); | ||
174 | } | ||
175 | |||
176 | /** | ||
177 | * Returns a mutable (partial) match. | ||
178 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
179 | * | ||
180 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
181 | * @return the new, mutable (partial) match object. | ||
182 | * | ||
183 | */ | ||
184 | public static NotSynchronizingStates.Match newMutableMatch(final Synchronization pS) { | ||
185 | return new Mutable(pS); | ||
186 | } | ||
187 | |||
188 | /** | ||
189 | * Returns a new (partial) match. | ||
190 | * This can be used e.g. to call the matcher with a partial match. | ||
191 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
192 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
193 | * @return the (partial) match object. | ||
194 | * | ||
195 | */ | ||
196 | public static NotSynchronizingStates.Match newMatch(final Synchronization pS) { | ||
197 | return new Immutable(pS); | ||
198 | } | ||
199 | |||
200 | private static final class Mutable extends NotSynchronizingStates.Match { | ||
201 | Mutable(final Synchronization pS) { | ||
202 | super(pS); | ||
203 | } | ||
204 | |||
205 | @Override | ||
206 | public boolean isMutable() { | ||
207 | return true; | ||
208 | } | ||
209 | } | ||
210 | |||
211 | private static final class Immutable extends NotSynchronizingStates.Match { | ||
212 | Immutable(final Synchronization pS) { | ||
213 | super(pS); | ||
214 | } | ||
215 | |||
216 | @Override | ||
217 | public boolean isMutable() { | ||
218 | return false; | ||
219 | } | ||
220 | } | ||
221 | } | ||
222 | |||
223 | /** | ||
224 | * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.notSynchronizingStates pattern, | ||
225 | * providing pattern-specific query methods. | ||
226 | * | ||
227 | * <p>Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, | ||
228 | * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. | ||
229 | * | ||
230 | * <p>Matches of the pattern will be represented as {@link Match}. | ||
231 | * | ||
232 | * <p>Original source: | ||
233 | * <code><pre> | ||
234 | * {@literal @}Constraint(severity="error", message="error", key = {s}) | ||
235 | * pattern notSynchronizingStates(s : Synchronization) { | ||
236 | * neg find hasMultipleOutgoingTrainsition(s); | ||
237 | * neg find hasMultipleIncomingTrainsition(s); | ||
238 | * } | ||
239 | * </pre></code> | ||
240 | * | ||
241 | * @see Match | ||
242 | * @see NotSynchronizingStates | ||
243 | * | ||
244 | */ | ||
245 | public static class Matcher extends BaseMatcher<NotSynchronizingStates.Match> { | ||
246 | /** | ||
247 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
248 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
249 | * | ||
250 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
251 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
252 | * | ||
253 | */ | ||
254 | public static NotSynchronizingStates.Matcher on(final ViatraQueryEngine engine) { | ||
255 | // check if matcher already exists | ||
256 | Matcher matcher = engine.getExistingMatcher(querySpecification()); | ||
257 | if (matcher == null) { | ||
258 | matcher = (Matcher)engine.getMatcher(querySpecification()); | ||
259 | } | ||
260 | return matcher; | ||
261 | } | ||
262 | |||
263 | /** | ||
264 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
265 | * @return an initialized matcher | ||
266 | * @noreference This method is for internal matcher initialization by the framework, do not call it manually. | ||
267 | * | ||
268 | */ | ||
269 | public static NotSynchronizingStates.Matcher create() { | ||
270 | return new Matcher(); | ||
271 | } | ||
272 | |||
273 | private final static int POSITION_S = 0; | ||
274 | |||
275 | private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(NotSynchronizingStates.Matcher.class); | ||
276 | |||
277 | /** | ||
278 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
279 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
280 | * | ||
281 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
282 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
283 | * | ||
284 | */ | ||
285 | private Matcher() { | ||
286 | super(querySpecification()); | ||
287 | } | ||
288 | |||
289 | /** | ||
290 | * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. | ||
291 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
292 | * @return matches represented as a Match object. | ||
293 | * | ||
294 | */ | ||
295 | public Collection<NotSynchronizingStates.Match> getAllMatches(final Synchronization pS) { | ||
296 | return rawStreamAllMatches(new Object[]{pS}).collect(Collectors.toSet()); | ||
297 | } | ||
298 | |||
299 | /** | ||
300 | * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. | ||
301 | * </p> | ||
302 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
303 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
304 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
305 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
306 | * @return a stream of matches represented as a Match object. | ||
307 | * | ||
308 | */ | ||
309 | public Stream<NotSynchronizingStates.Match> streamAllMatches(final Synchronization pS) { | ||
310 | return rawStreamAllMatches(new Object[]{pS}); | ||
311 | } | ||
312 | |||
313 | /** | ||
314 | * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
315 | * Neither determinism nor randomness of selection is guaranteed. | ||
316 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
317 | * @return a match represented as a Match object, or null if no match is found. | ||
318 | * | ||
319 | */ | ||
320 | public Optional<NotSynchronizingStates.Match> getOneArbitraryMatch(final Synchronization pS) { | ||
321 | return rawGetOneArbitraryMatch(new Object[]{pS}); | ||
322 | } | ||
323 | |||
324 | /** | ||
325 | * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, | ||
326 | * under any possible substitution of the unspecified parameters (if any). | ||
327 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
328 | * @return true if the input is a valid (partial) match of the pattern. | ||
329 | * | ||
330 | */ | ||
331 | public boolean hasMatch(final Synchronization pS) { | ||
332 | return rawHasMatch(new Object[]{pS}); | ||
333 | } | ||
334 | |||
335 | /** | ||
336 | * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. | ||
337 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
338 | * @return the number of pattern matches found. | ||
339 | * | ||
340 | */ | ||
341 | public int countMatches(final Synchronization pS) { | ||
342 | return rawCountMatches(new Object[]{pS}); | ||
343 | } | ||
344 | |||
345 | /** | ||
346 | * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
347 | * Neither determinism nor randomness of selection is guaranteed. | ||
348 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
349 | * @param processor the action that will process the selected match. | ||
350 | * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked | ||
351 | * | ||
352 | */ | ||
353 | public boolean forOneArbitraryMatch(final Synchronization pS, final Consumer<? super NotSynchronizingStates.Match> processor) { | ||
354 | return rawForOneArbitraryMatch(new Object[]{pS}, processor); | ||
355 | } | ||
356 | |||
357 | /** | ||
358 | * Returns a new (partial) match. | ||
359 | * This can be used e.g. to call the matcher with a partial match. | ||
360 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
361 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
362 | * @return the (partial) match object. | ||
363 | * | ||
364 | */ | ||
365 | public NotSynchronizingStates.Match newMatch(final Synchronization pS) { | ||
366 | return NotSynchronizingStates.Match.newMatch(pS); | ||
367 | } | ||
368 | |||
369 | /** | ||
370 | * Retrieve the set of values that occur in matches for s. | ||
371 | * @return the Set of all values or empty set if there are no matches | ||
372 | * | ||
373 | */ | ||
374 | protected Stream<Synchronization> rawStreamAllValuesOfs(final Object[] parameters) { | ||
375 | return rawStreamAllValues(POSITION_S, parameters).map(Synchronization.class::cast); | ||
376 | } | ||
377 | |||
378 | /** | ||
379 | * Retrieve the set of values that occur in matches for s. | ||
380 | * @return the Set of all values or empty set if there are no matches | ||
381 | * | ||
382 | */ | ||
383 | public Set<Synchronization> getAllValuesOfs() { | ||
384 | return rawStreamAllValuesOfs(emptyArray()).collect(Collectors.toSet()); | ||
385 | } | ||
386 | |||
387 | /** | ||
388 | * Retrieve the set of values that occur in matches for s. | ||
389 | * @return the Set of all values or empty set if there are no matches | ||
390 | * | ||
391 | */ | ||
392 | public Stream<Synchronization> streamAllValuesOfs() { | ||
393 | return rawStreamAllValuesOfs(emptyArray()); | ||
394 | } | ||
395 | |||
396 | @Override | ||
397 | protected NotSynchronizingStates.Match tupleToMatch(final Tuple t) { | ||
398 | try { | ||
399 | return NotSynchronizingStates.Match.newMatch((Synchronization) t.get(POSITION_S)); | ||
400 | } catch(ClassCastException e) { | ||
401 | LOGGER.error("Element(s) in tuple not properly typed!",e); | ||
402 | return null; | ||
403 | } | ||
404 | } | ||
405 | |||
406 | @Override | ||
407 | protected NotSynchronizingStates.Match arrayToMatch(final Object[] match) { | ||
408 | try { | ||
409 | return NotSynchronizingStates.Match.newMatch((Synchronization) match[POSITION_S]); | ||
410 | } catch(ClassCastException e) { | ||
411 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
412 | return null; | ||
413 | } | ||
414 | } | ||
415 | |||
416 | @Override | ||
417 | protected NotSynchronizingStates.Match arrayToMatchMutable(final Object[] match) { | ||
418 | try { | ||
419 | return NotSynchronizingStates.Match.newMutableMatch((Synchronization) match[POSITION_S]); | ||
420 | } catch(ClassCastException e) { | ||
421 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
422 | return null; | ||
423 | } | ||
424 | } | ||
425 | |||
426 | /** | ||
427 | * @return the singleton instance of the query specification of this pattern | ||
428 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
429 | * | ||
430 | */ | ||
431 | public static IQuerySpecification<NotSynchronizingStates.Matcher> querySpecification() { | ||
432 | return NotSynchronizingStates.instance(); | ||
433 | } | ||
434 | } | ||
435 | |||
436 | private NotSynchronizingStates() { | ||
437 | super(GeneratedPQuery.INSTANCE); | ||
438 | } | ||
439 | |||
440 | /** | ||
441 | * @return the singleton instance of the query specification | ||
442 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
443 | * | ||
444 | */ | ||
445 | public static NotSynchronizingStates instance() { | ||
446 | try{ | ||
447 | return LazyHolder.INSTANCE; | ||
448 | } catch (ExceptionInInitializerError err) { | ||
449 | throw processInitializerError(err); | ||
450 | } | ||
451 | } | ||
452 | |||
453 | @Override | ||
454 | protected NotSynchronizingStates.Matcher instantiate(final ViatraQueryEngine engine) { | ||
455 | return NotSynchronizingStates.Matcher.on(engine); | ||
456 | } | ||
457 | |||
458 | @Override | ||
459 | public NotSynchronizingStates.Matcher instantiate() { | ||
460 | return NotSynchronizingStates.Matcher.create(); | ||
461 | } | ||
462 | |||
463 | @Override | ||
464 | public NotSynchronizingStates.Match newEmptyMatch() { | ||
465 | return NotSynchronizingStates.Match.newEmptyMatch(); | ||
466 | } | ||
467 | |||
468 | @Override | ||
469 | public NotSynchronizingStates.Match newMatch(final Object... parameters) { | ||
470 | return NotSynchronizingStates.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization) parameters[0]); | ||
471 | } | ||
472 | |||
473 | /** | ||
474 | * Inner class allowing the singleton instance of {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.NotSynchronizingStates (visibility: PUBLIC, simpleName: NotSynchronizingStates, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.NotSynchronizingStates, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created | ||
475 | * <b>not</b> at the class load time of the outer class, | ||
476 | * but rather at the first call to {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.NotSynchronizingStates (visibility: PUBLIC, simpleName: NotSynchronizingStates, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.NotSynchronizingStates, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. | ||
477 | * | ||
478 | * <p> This workaround is required e.g. to support recursion. | ||
479 | * | ||
480 | */ | ||
481 | private static class LazyHolder { | ||
482 | private final static NotSynchronizingStates INSTANCE = new NotSynchronizingStates(); | ||
483 | |||
484 | /** | ||
485 | * Statically initializes the query specification <b>after</b> the field {@link #INSTANCE} is assigned. | ||
486 | * This initialization order is required to support indirect recursion. | ||
487 | * | ||
488 | * <p> The static initializer is defined using a helper field to work around limitations of the code generator. | ||
489 | * | ||
490 | */ | ||
491 | private final static Object STATIC_INITIALIZER = ensureInitialized(); | ||
492 | |||
493 | public static Object ensureInitialized() { | ||
494 | INSTANCE.ensureInitializedInternal(); | ||
495 | return null; | ||
496 | } | ||
497 | } | ||
498 | |||
499 | private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { | ||
500 | private final static NotSynchronizingStates.GeneratedPQuery INSTANCE = new GeneratedPQuery(); | ||
501 | |||
502 | private final PParameter parameter_s = new PParameter("s", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Synchronization")), PParameterDirection.INOUT); | ||
503 | |||
504 | private final List<PParameter> parameters = Arrays.asList(parameter_s); | ||
505 | |||
506 | private GeneratedPQuery() { | ||
507 | super(PVisibility.PUBLIC); | ||
508 | } | ||
509 | |||
510 | @Override | ||
511 | public String getFullyQualifiedName() { | ||
512 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.notSynchronizingStates"; | ||
513 | } | ||
514 | |||
515 | @Override | ||
516 | public List<String> getParameterNames() { | ||
517 | return Arrays.asList("s"); | ||
518 | } | ||
519 | |||
520 | @Override | ||
521 | public List<PParameter> getParameters() { | ||
522 | return parameters; | ||
523 | } | ||
524 | |||
525 | @Override | ||
526 | public Set<PBody> doGetContainedBodies() { | ||
527 | setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); | ||
528 | Set<PBody> bodies = new LinkedHashSet<>(); | ||
529 | { | ||
530 | PBody body = new PBody(this); | ||
531 | PVariable var_s = body.getOrCreateVariableByName("s"); | ||
532 | new TypeConstraint(body, Tuples.flatTupleOf(var_s), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Synchronization"))); | ||
533 | body.setSymbolicParameters(Arrays.<ExportedParameter>asList( | ||
534 | new ExportedParameter(body, var_s, parameter_s) | ||
535 | )); | ||
536 | // neg find hasMultipleOutgoingTrainsition(s) | ||
537 | new NegativePatternCall(body, Tuples.flatTupleOf(var_s), HasMultipleOutgoingTrainsition.instance().getInternalQueryRepresentation()); | ||
538 | // neg find hasMultipleIncomingTrainsition(s) | ||
539 | new NegativePatternCall(body, Tuples.flatTupleOf(var_s), HasMultipleIncomingTrainsition.instance().getInternalQueryRepresentation()); | ||
540 | bodies.add(body); | ||
541 | } | ||
542 | { | ||
543 | PAnnotation annotation = new PAnnotation("Constraint"); | ||
544 | annotation.addAttribute("severity", "error"); | ||
545 | annotation.addAttribute("message", "error"); | ||
546 | annotation.addAttribute("key", Arrays.asList(new Object[] { | ||
547 | new ParameterReference("s") | ||
548 | })); | ||
549 | addAnnotation(annotation); | ||
550 | } | ||
551 | return bodies; | ||
552 | } | ||
553 | } | ||
554 | } | ||
diff --git a/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/OutgoingFromExit.java b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/OutgoingFromExit.java new file mode 100644 index 00000000..10f0e056 --- /dev/null +++ b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/OutgoingFromExit.java | |||
@@ -0,0 +1,715 @@ | |||
1 | /** | ||
2 | * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql | ||
3 | */ | ||
4 | package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; | ||
5 | |||
6 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Exit; | ||
7 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition; | ||
8 | import java.util.Arrays; | ||
9 | import java.util.Collection; | ||
10 | import java.util.LinkedHashSet; | ||
11 | import java.util.List; | ||
12 | import java.util.Objects; | ||
13 | import java.util.Optional; | ||
14 | import java.util.Set; | ||
15 | import java.util.function.Consumer; | ||
16 | import java.util.stream.Collectors; | ||
17 | import java.util.stream.Stream; | ||
18 | import org.apache.log4j.Logger; | ||
19 | import org.eclipse.emf.ecore.EClass; | ||
20 | import org.eclipse.viatra.query.runtime.api.IPatternMatch; | ||
21 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification; | ||
22 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; | ||
23 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; | ||
24 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; | ||
25 | import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; | ||
26 | import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; | ||
27 | import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; | ||
28 | import org.eclipse.viatra.query.runtime.emf.types.EStructuralFeatureInstancesKey; | ||
29 | import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; | ||
30 | import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; | ||
31 | import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; | ||
32 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; | ||
33 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; | ||
34 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality; | ||
35 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; | ||
36 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; | ||
37 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; | ||
38 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; | ||
39 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; | ||
40 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; | ||
41 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | ||
42 | import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; | ||
43 | |||
44 | /** | ||
45 | * A pattern-specific query specification that can instantiate Matcher in a type-safe way. | ||
46 | * | ||
47 | * <p>Original source: | ||
48 | * <code><pre> | ||
49 | * ///////// | ||
50 | * // Exit | ||
51 | * ///////// | ||
52 | * | ||
53 | * {@literal @}Constraint(severity="error", message="error", key = {e}) | ||
54 | * pattern outgoingFromExit(t : Transition, e : Exit) { | ||
55 | * Exit.outgoingTransitions(e,t); | ||
56 | * } | ||
57 | * </pre></code> | ||
58 | * | ||
59 | * @see Matcher | ||
60 | * @see Match | ||
61 | * | ||
62 | */ | ||
63 | @SuppressWarnings("all") | ||
64 | public final class OutgoingFromExit extends BaseGeneratedEMFQuerySpecification<OutgoingFromExit.Matcher> { | ||
65 | /** | ||
66 | * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.outgoingFromExit pattern, | ||
67 | * to be used in conjunction with {@link Matcher}. | ||
68 | * | ||
69 | * <p>Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. | ||
70 | * Each instance is a (possibly partial) substitution of pattern parameters, | ||
71 | * usable to represent a match of the pattern in the result of a query, | ||
72 | * or to specify the bound (fixed) input parameters when issuing a query. | ||
73 | * | ||
74 | * @see Matcher | ||
75 | * | ||
76 | */ | ||
77 | public static abstract class Match extends BasePatternMatch { | ||
78 | private Transition fT; | ||
79 | |||
80 | private Exit fE; | ||
81 | |||
82 | private static List<String> parameterNames = makeImmutableList("t", "e"); | ||
83 | |||
84 | private Match(final Transition pT, final Exit pE) { | ||
85 | this.fT = pT; | ||
86 | this.fE = pE; | ||
87 | } | ||
88 | |||
89 | @Override | ||
90 | public Object get(final String parameterName) { | ||
91 | if ("t".equals(parameterName)) return this.fT; | ||
92 | if ("e".equals(parameterName)) return this.fE; | ||
93 | return null; | ||
94 | } | ||
95 | |||
96 | public Transition getT() { | ||
97 | return this.fT; | ||
98 | } | ||
99 | |||
100 | public Exit getE() { | ||
101 | return this.fE; | ||
102 | } | ||
103 | |||
104 | @Override | ||
105 | public boolean set(final String parameterName, final Object newValue) { | ||
106 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
107 | if ("t".equals(parameterName) ) { | ||
108 | this.fT = (Transition) newValue; | ||
109 | return true; | ||
110 | } | ||
111 | if ("e".equals(parameterName) ) { | ||
112 | this.fE = (Exit) newValue; | ||
113 | return true; | ||
114 | } | ||
115 | return false; | ||
116 | } | ||
117 | |||
118 | public void setT(final Transition pT) { | ||
119 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
120 | this.fT = pT; | ||
121 | } | ||
122 | |||
123 | public void setE(final Exit pE) { | ||
124 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
125 | this.fE = pE; | ||
126 | } | ||
127 | |||
128 | @Override | ||
129 | public String patternName() { | ||
130 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.outgoingFromExit"; | ||
131 | } | ||
132 | |||
133 | @Override | ||
134 | public List<String> parameterNames() { | ||
135 | return OutgoingFromExit.Match.parameterNames; | ||
136 | } | ||
137 | |||
138 | @Override | ||
139 | public Object[] toArray() { | ||
140 | return new Object[]{fT, fE}; | ||
141 | } | ||
142 | |||
143 | @Override | ||
144 | public OutgoingFromExit.Match toImmutable() { | ||
145 | return isMutable() ? newMatch(fT, fE) : this; | ||
146 | } | ||
147 | |||
148 | @Override | ||
149 | public String prettyPrint() { | ||
150 | StringBuilder result = new StringBuilder(); | ||
151 | result.append("\"t\"=" + prettyPrintValue(fT) + ", "); | ||
152 | result.append("\"e\"=" + prettyPrintValue(fE)); | ||
153 | return result.toString(); | ||
154 | } | ||
155 | |||
156 | @Override | ||
157 | public int hashCode() { | ||
158 | return Objects.hash(fT, fE); | ||
159 | } | ||
160 | |||
161 | @Override | ||
162 | public boolean equals(final Object obj) { | ||
163 | if (this == obj) | ||
164 | return true; | ||
165 | if (obj == null) { | ||
166 | return false; | ||
167 | } | ||
168 | if ((obj instanceof OutgoingFromExit.Match)) { | ||
169 | OutgoingFromExit.Match other = (OutgoingFromExit.Match) obj; | ||
170 | return Objects.equals(fT, other.fT) && Objects.equals(fE, other.fE); | ||
171 | } else { | ||
172 | // this should be infrequent | ||
173 | if (!(obj instanceof IPatternMatch)) { | ||
174 | return false; | ||
175 | } | ||
176 | IPatternMatch otherSig = (IPatternMatch) obj; | ||
177 | return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); | ||
178 | } | ||
179 | } | ||
180 | |||
181 | @Override | ||
182 | public OutgoingFromExit specification() { | ||
183 | return OutgoingFromExit.instance(); | ||
184 | } | ||
185 | |||
186 | /** | ||
187 | * Returns an empty, mutable match. | ||
188 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
189 | * | ||
190 | * @return the empty match. | ||
191 | * | ||
192 | */ | ||
193 | public static OutgoingFromExit.Match newEmptyMatch() { | ||
194 | return new Mutable(null, null); | ||
195 | } | ||
196 | |||
197 | /** | ||
198 | * Returns a mutable (partial) match. | ||
199 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
200 | * | ||
201 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
202 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
203 | * @return the new, mutable (partial) match object. | ||
204 | * | ||
205 | */ | ||
206 | public static OutgoingFromExit.Match newMutableMatch(final Transition pT, final Exit pE) { | ||
207 | return new Mutable(pT, pE); | ||
208 | } | ||
209 | |||
210 | /** | ||
211 | * Returns a new (partial) match. | ||
212 | * This can be used e.g. to call the matcher with a partial match. | ||
213 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
214 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
215 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
216 | * @return the (partial) match object. | ||
217 | * | ||
218 | */ | ||
219 | public static OutgoingFromExit.Match newMatch(final Transition pT, final Exit pE) { | ||
220 | return new Immutable(pT, pE); | ||
221 | } | ||
222 | |||
223 | private static final class Mutable extends OutgoingFromExit.Match { | ||
224 | Mutable(final Transition pT, final Exit pE) { | ||
225 | super(pT, pE); | ||
226 | } | ||
227 | |||
228 | @Override | ||
229 | public boolean isMutable() { | ||
230 | return true; | ||
231 | } | ||
232 | } | ||
233 | |||
234 | private static final class Immutable extends OutgoingFromExit.Match { | ||
235 | Immutable(final Transition pT, final Exit pE) { | ||
236 | super(pT, pE); | ||
237 | } | ||
238 | |||
239 | @Override | ||
240 | public boolean isMutable() { | ||
241 | return false; | ||
242 | } | ||
243 | } | ||
244 | } | ||
245 | |||
246 | /** | ||
247 | * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.outgoingFromExit pattern, | ||
248 | * providing pattern-specific query methods. | ||
249 | * | ||
250 | * <p>Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, | ||
251 | * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. | ||
252 | * | ||
253 | * <p>Matches of the pattern will be represented as {@link Match}. | ||
254 | * | ||
255 | * <p>Original source: | ||
256 | * <code><pre> | ||
257 | * ///////// | ||
258 | * // Exit | ||
259 | * ///////// | ||
260 | * | ||
261 | * {@literal @}Constraint(severity="error", message="error", key = {e}) | ||
262 | * pattern outgoingFromExit(t : Transition, e : Exit) { | ||
263 | * Exit.outgoingTransitions(e,t); | ||
264 | * } | ||
265 | * </pre></code> | ||
266 | * | ||
267 | * @see Match | ||
268 | * @see OutgoingFromExit | ||
269 | * | ||
270 | */ | ||
271 | public static class Matcher extends BaseMatcher<OutgoingFromExit.Match> { | ||
272 | /** | ||
273 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
274 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
275 | * | ||
276 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
277 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
278 | * | ||
279 | */ | ||
280 | public static OutgoingFromExit.Matcher on(final ViatraQueryEngine engine) { | ||
281 | // check if matcher already exists | ||
282 | Matcher matcher = engine.getExistingMatcher(querySpecification()); | ||
283 | if (matcher == null) { | ||
284 | matcher = (Matcher)engine.getMatcher(querySpecification()); | ||
285 | } | ||
286 | return matcher; | ||
287 | } | ||
288 | |||
289 | /** | ||
290 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
291 | * @return an initialized matcher | ||
292 | * @noreference This method is for internal matcher initialization by the framework, do not call it manually. | ||
293 | * | ||
294 | */ | ||
295 | public static OutgoingFromExit.Matcher create() { | ||
296 | return new Matcher(); | ||
297 | } | ||
298 | |||
299 | private final static int POSITION_T = 0; | ||
300 | |||
301 | private final static int POSITION_E = 1; | ||
302 | |||
303 | private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(OutgoingFromExit.Matcher.class); | ||
304 | |||
305 | /** | ||
306 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
307 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
308 | * | ||
309 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
310 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
311 | * | ||
312 | */ | ||
313 | private Matcher() { | ||
314 | super(querySpecification()); | ||
315 | } | ||
316 | |||
317 | /** | ||
318 | * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. | ||
319 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
320 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
321 | * @return matches represented as a Match object. | ||
322 | * | ||
323 | */ | ||
324 | public Collection<OutgoingFromExit.Match> getAllMatches(final Transition pT, final Exit pE) { | ||
325 | return rawStreamAllMatches(new Object[]{pT, pE}).collect(Collectors.toSet()); | ||
326 | } | ||
327 | |||
328 | /** | ||
329 | * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. | ||
330 | * </p> | ||
331 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
332 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
333 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
334 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
335 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
336 | * @return a stream of matches represented as a Match object. | ||
337 | * | ||
338 | */ | ||
339 | public Stream<OutgoingFromExit.Match> streamAllMatches(final Transition pT, final Exit pE) { | ||
340 | return rawStreamAllMatches(new Object[]{pT, pE}); | ||
341 | } | ||
342 | |||
343 | /** | ||
344 | * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
345 | * Neither determinism nor randomness of selection is guaranteed. | ||
346 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
347 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
348 | * @return a match represented as a Match object, or null if no match is found. | ||
349 | * | ||
350 | */ | ||
351 | public Optional<OutgoingFromExit.Match> getOneArbitraryMatch(final Transition pT, final Exit pE) { | ||
352 | return rawGetOneArbitraryMatch(new Object[]{pT, pE}); | ||
353 | } | ||
354 | |||
355 | /** | ||
356 | * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, | ||
357 | * under any possible substitution of the unspecified parameters (if any). | ||
358 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
359 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
360 | * @return true if the input is a valid (partial) match of the pattern. | ||
361 | * | ||
362 | */ | ||
363 | public boolean hasMatch(final Transition pT, final Exit pE) { | ||
364 | return rawHasMatch(new Object[]{pT, pE}); | ||
365 | } | ||
366 | |||
367 | /** | ||
368 | * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. | ||
369 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
370 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
371 | * @return the number of pattern matches found. | ||
372 | * | ||
373 | */ | ||
374 | public int countMatches(final Transition pT, final Exit pE) { | ||
375 | return rawCountMatches(new Object[]{pT, pE}); | ||
376 | } | ||
377 | |||
378 | /** | ||
379 | * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
380 | * Neither determinism nor randomness of selection is guaranteed. | ||
381 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
382 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
383 | * @param processor the action that will process the selected match. | ||
384 | * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked | ||
385 | * | ||
386 | */ | ||
387 | public boolean forOneArbitraryMatch(final Transition pT, final Exit pE, final Consumer<? super OutgoingFromExit.Match> processor) { | ||
388 | return rawForOneArbitraryMatch(new Object[]{pT, pE}, processor); | ||
389 | } | ||
390 | |||
391 | /** | ||
392 | * Returns a new (partial) match. | ||
393 | * This can be used e.g. to call the matcher with a partial match. | ||
394 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
395 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
396 | * @param pE the fixed value of pattern parameter e, or null if not bound. | ||
397 | * @return the (partial) match object. | ||
398 | * | ||
399 | */ | ||
400 | public OutgoingFromExit.Match newMatch(final Transition pT, final Exit pE) { | ||
401 | return OutgoingFromExit.Match.newMatch(pT, pE); | ||
402 | } | ||
403 | |||
404 | /** | ||
405 | * Retrieve the set of values that occur in matches for t. | ||
406 | * @return the Set of all values or empty set if there are no matches | ||
407 | * | ||
408 | */ | ||
409 | protected Stream<Transition> rawStreamAllValuesOft(final Object[] parameters) { | ||
410 | return rawStreamAllValues(POSITION_T, parameters).map(Transition.class::cast); | ||
411 | } | ||
412 | |||
413 | /** | ||
414 | * Retrieve the set of values that occur in matches for t. | ||
415 | * @return the Set of all values or empty set if there are no matches | ||
416 | * | ||
417 | */ | ||
418 | public Set<Transition> getAllValuesOft() { | ||
419 | return rawStreamAllValuesOft(emptyArray()).collect(Collectors.toSet()); | ||
420 | } | ||
421 | |||
422 | /** | ||
423 | * Retrieve the set of values that occur in matches for t. | ||
424 | * @return the Set of all values or empty set if there are no matches | ||
425 | * | ||
426 | */ | ||
427 | public Stream<Transition> streamAllValuesOft() { | ||
428 | return rawStreamAllValuesOft(emptyArray()); | ||
429 | } | ||
430 | |||
431 | /** | ||
432 | * Retrieve the set of values that occur in matches for t. | ||
433 | * </p> | ||
434 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
435 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
436 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
437 | * | ||
438 | * @return the Stream of all values or empty set if there are no matches | ||
439 | * | ||
440 | */ | ||
441 | public Stream<Transition> streamAllValuesOft(final OutgoingFromExit.Match partialMatch) { | ||
442 | return rawStreamAllValuesOft(partialMatch.toArray()); | ||
443 | } | ||
444 | |||
445 | /** | ||
446 | * Retrieve the set of values that occur in matches for t. | ||
447 | * </p> | ||
448 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
449 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
450 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
451 | * | ||
452 | * @return the Stream of all values or empty set if there are no matches | ||
453 | * | ||
454 | */ | ||
455 | public Stream<Transition> streamAllValuesOft(final Exit pE) { | ||
456 | return rawStreamAllValuesOft(new Object[]{null, pE}); | ||
457 | } | ||
458 | |||
459 | /** | ||
460 | * Retrieve the set of values that occur in matches for t. | ||
461 | * @return the Set of all values or empty set if there are no matches | ||
462 | * | ||
463 | */ | ||
464 | public Set<Transition> getAllValuesOft(final OutgoingFromExit.Match partialMatch) { | ||
465 | return rawStreamAllValuesOft(partialMatch.toArray()).collect(Collectors.toSet()); | ||
466 | } | ||
467 | |||
468 | /** | ||
469 | * Retrieve the set of values that occur in matches for t. | ||
470 | * @return the Set of all values or empty set if there are no matches | ||
471 | * | ||
472 | */ | ||
473 | public Set<Transition> getAllValuesOft(final Exit pE) { | ||
474 | return rawStreamAllValuesOft(new Object[]{null, pE}).collect(Collectors.toSet()); | ||
475 | } | ||
476 | |||
477 | /** | ||
478 | * Retrieve the set of values that occur in matches for e. | ||
479 | * @return the Set of all values or empty set if there are no matches | ||
480 | * | ||
481 | */ | ||
482 | protected Stream<Exit> rawStreamAllValuesOfe(final Object[] parameters) { | ||
483 | return rawStreamAllValues(POSITION_E, parameters).map(Exit.class::cast); | ||
484 | } | ||
485 | |||
486 | /** | ||
487 | * Retrieve the set of values that occur in matches for e. | ||
488 | * @return the Set of all values or empty set if there are no matches | ||
489 | * | ||
490 | */ | ||
491 | public Set<Exit> getAllValuesOfe() { | ||
492 | return rawStreamAllValuesOfe(emptyArray()).collect(Collectors.toSet()); | ||
493 | } | ||
494 | |||
495 | /** | ||
496 | * Retrieve the set of values that occur in matches for e. | ||
497 | * @return the Set of all values or empty set if there are no matches | ||
498 | * | ||
499 | */ | ||
500 | public Stream<Exit> streamAllValuesOfe() { | ||
501 | return rawStreamAllValuesOfe(emptyArray()); | ||
502 | } | ||
503 | |||
504 | /** | ||
505 | * Retrieve the set of values that occur in matches for e. | ||
506 | * </p> | ||
507 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
508 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
509 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
510 | * | ||
511 | * @return the Stream of all values or empty set if there are no matches | ||
512 | * | ||
513 | */ | ||
514 | public Stream<Exit> streamAllValuesOfe(final OutgoingFromExit.Match partialMatch) { | ||
515 | return rawStreamAllValuesOfe(partialMatch.toArray()); | ||
516 | } | ||
517 | |||
518 | /** | ||
519 | * Retrieve the set of values that occur in matches for e. | ||
520 | * </p> | ||
521 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
522 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
523 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
524 | * | ||
525 | * @return the Stream of all values or empty set if there are no matches | ||
526 | * | ||
527 | */ | ||
528 | public Stream<Exit> streamAllValuesOfe(final Transition pT) { | ||
529 | return rawStreamAllValuesOfe(new Object[]{pT, null}); | ||
530 | } | ||
531 | |||
532 | /** | ||
533 | * Retrieve the set of values that occur in matches for e. | ||
534 | * @return the Set of all values or empty set if there are no matches | ||
535 | * | ||
536 | */ | ||
537 | public Set<Exit> getAllValuesOfe(final OutgoingFromExit.Match partialMatch) { | ||
538 | return rawStreamAllValuesOfe(partialMatch.toArray()).collect(Collectors.toSet()); | ||
539 | } | ||
540 | |||
541 | /** | ||
542 | * Retrieve the set of values that occur in matches for e. | ||
543 | * @return the Set of all values or empty set if there are no matches | ||
544 | * | ||
545 | */ | ||
546 | public Set<Exit> getAllValuesOfe(final Transition pT) { | ||
547 | return rawStreamAllValuesOfe(new Object[]{pT, null}).collect(Collectors.toSet()); | ||
548 | } | ||
549 | |||
550 | @Override | ||
551 | protected OutgoingFromExit.Match tupleToMatch(final Tuple t) { | ||
552 | try { | ||
553 | return OutgoingFromExit.Match.newMatch((Transition) t.get(POSITION_T), (Exit) t.get(POSITION_E)); | ||
554 | } catch(ClassCastException e) { | ||
555 | LOGGER.error("Element(s) in tuple not properly typed!",e); | ||
556 | return null; | ||
557 | } | ||
558 | } | ||
559 | |||
560 | @Override | ||
561 | protected OutgoingFromExit.Match arrayToMatch(final Object[] match) { | ||
562 | try { | ||
563 | return OutgoingFromExit.Match.newMatch((Transition) match[POSITION_T], (Exit) match[POSITION_E]); | ||
564 | } catch(ClassCastException e) { | ||
565 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
566 | return null; | ||
567 | } | ||
568 | } | ||
569 | |||
570 | @Override | ||
571 | protected OutgoingFromExit.Match arrayToMatchMutable(final Object[] match) { | ||
572 | try { | ||
573 | return OutgoingFromExit.Match.newMutableMatch((Transition) match[POSITION_T], (Exit) match[POSITION_E]); | ||
574 | } catch(ClassCastException e) { | ||
575 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
576 | return null; | ||
577 | } | ||
578 | } | ||
579 | |||
580 | /** | ||
581 | * @return the singleton instance of the query specification of this pattern | ||
582 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
583 | * | ||
584 | */ | ||
585 | public static IQuerySpecification<OutgoingFromExit.Matcher> querySpecification() { | ||
586 | return OutgoingFromExit.instance(); | ||
587 | } | ||
588 | } | ||
589 | |||
590 | private OutgoingFromExit() { | ||
591 | super(GeneratedPQuery.INSTANCE); | ||
592 | } | ||
593 | |||
594 | /** | ||
595 | * @return the singleton instance of the query specification | ||
596 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
597 | * | ||
598 | */ | ||
599 | public static OutgoingFromExit instance() { | ||
600 | try{ | ||
601 | return LazyHolder.INSTANCE; | ||
602 | } catch (ExceptionInInitializerError err) { | ||
603 | throw processInitializerError(err); | ||
604 | } | ||
605 | } | ||
606 | |||
607 | @Override | ||
608 | protected OutgoingFromExit.Matcher instantiate(final ViatraQueryEngine engine) { | ||
609 | return OutgoingFromExit.Matcher.on(engine); | ||
610 | } | ||
611 | |||
612 | @Override | ||
613 | public OutgoingFromExit.Matcher instantiate() { | ||
614 | return OutgoingFromExit.Matcher.create(); | ||
615 | } | ||
616 | |||
617 | @Override | ||
618 | public OutgoingFromExit.Match newEmptyMatch() { | ||
619 | return OutgoingFromExit.Match.newEmptyMatch(); | ||
620 | } | ||
621 | |||
622 | @Override | ||
623 | public OutgoingFromExit.Match newMatch(final Object... parameters) { | ||
624 | return OutgoingFromExit.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition) parameters[0], (ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Exit) parameters[1]); | ||
625 | } | ||
626 | |||
627 | /** | ||
628 | * Inner class allowing the singleton instance of {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.OutgoingFromExit (visibility: PUBLIC, simpleName: OutgoingFromExit, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.OutgoingFromExit, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created | ||
629 | * <b>not</b> at the class load time of the outer class, | ||
630 | * but rather at the first call to {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.OutgoingFromExit (visibility: PUBLIC, simpleName: OutgoingFromExit, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.OutgoingFromExit, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. | ||
631 | * | ||
632 | * <p> This workaround is required e.g. to support recursion. | ||
633 | * | ||
634 | */ | ||
635 | private static class LazyHolder { | ||
636 | private final static OutgoingFromExit INSTANCE = new OutgoingFromExit(); | ||
637 | |||
638 | /** | ||
639 | * Statically initializes the query specification <b>after</b> the field {@link #INSTANCE} is assigned. | ||
640 | * This initialization order is required to support indirect recursion. | ||
641 | * | ||
642 | * <p> The static initializer is defined using a helper field to work around limitations of the code generator. | ||
643 | * | ||
644 | */ | ||
645 | private final static Object STATIC_INITIALIZER = ensureInitialized(); | ||
646 | |||
647 | public static Object ensureInitialized() { | ||
648 | INSTANCE.ensureInitializedInternal(); | ||
649 | return null; | ||
650 | } | ||
651 | } | ||
652 | |||
653 | private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { | ||
654 | private final static OutgoingFromExit.GeneratedPQuery INSTANCE = new GeneratedPQuery(); | ||
655 | |||
656 | private final PParameter parameter_t = new PParameter("t", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Transition")), PParameterDirection.INOUT); | ||
657 | |||
658 | private final PParameter parameter_e = new PParameter("e", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Exit", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Exit")), PParameterDirection.INOUT); | ||
659 | |||
660 | private final List<PParameter> parameters = Arrays.asList(parameter_t, parameter_e); | ||
661 | |||
662 | private GeneratedPQuery() { | ||
663 | super(PVisibility.PUBLIC); | ||
664 | } | ||
665 | |||
666 | @Override | ||
667 | public String getFullyQualifiedName() { | ||
668 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.outgoingFromExit"; | ||
669 | } | ||
670 | |||
671 | @Override | ||
672 | public List<String> getParameterNames() { | ||
673 | return Arrays.asList("t","e"); | ||
674 | } | ||
675 | |||
676 | @Override | ||
677 | public List<PParameter> getParameters() { | ||
678 | return parameters; | ||
679 | } | ||
680 | |||
681 | @Override | ||
682 | public Set<PBody> doGetContainedBodies() { | ||
683 | setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); | ||
684 | Set<PBody> bodies = new LinkedHashSet<>(); | ||
685 | { | ||
686 | PBody body = new PBody(this); | ||
687 | PVariable var_t = body.getOrCreateVariableByName("t"); | ||
688 | PVariable var_e = body.getOrCreateVariableByName("e"); | ||
689 | new TypeConstraint(body, Tuples.flatTupleOf(var_t), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); | ||
690 | new TypeConstraint(body, Tuples.flatTupleOf(var_e), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Exit"))); | ||
691 | body.setSymbolicParameters(Arrays.<ExportedParameter>asList( | ||
692 | new ExportedParameter(body, var_t, parameter_t), | ||
693 | new ExportedParameter(body, var_e, parameter_e) | ||
694 | )); | ||
695 | // Exit.outgoingTransitions(e,t) | ||
696 | new TypeConstraint(body, Tuples.flatTupleOf(var_e), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Exit"))); | ||
697 | PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); | ||
698 | new TypeConstraint(body, Tuples.flatTupleOf(var_e, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Vertex", "outgoingTransitions"))); | ||
699 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); | ||
700 | new Equality(body, var__virtual_0_, var_t); | ||
701 | bodies.add(body); | ||
702 | } | ||
703 | { | ||
704 | PAnnotation annotation = new PAnnotation("Constraint"); | ||
705 | annotation.addAttribute("severity", "error"); | ||
706 | annotation.addAttribute("message", "error"); | ||
707 | annotation.addAttribute("key", Arrays.asList(new Object[] { | ||
708 | new ParameterReference("e") | ||
709 | })); | ||
710 | addAnnotation(annotation); | ||
711 | } | ||
712 | return bodies; | ||
713 | } | ||
714 | } | ||
715 | } | ||
diff --git a/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/OutgoingFromFinal.java b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/OutgoingFromFinal.java new file mode 100644 index 00000000..fbac352b --- /dev/null +++ b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/OutgoingFromFinal.java | |||
@@ -0,0 +1,715 @@ | |||
1 | /** | ||
2 | * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql | ||
3 | */ | ||
4 | package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; | ||
5 | |||
6 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.FinalState; | ||
7 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition; | ||
8 | import java.util.Arrays; | ||
9 | import java.util.Collection; | ||
10 | import java.util.LinkedHashSet; | ||
11 | import java.util.List; | ||
12 | import java.util.Objects; | ||
13 | import java.util.Optional; | ||
14 | import java.util.Set; | ||
15 | import java.util.function.Consumer; | ||
16 | import java.util.stream.Collectors; | ||
17 | import java.util.stream.Stream; | ||
18 | import org.apache.log4j.Logger; | ||
19 | import org.eclipse.emf.ecore.EClass; | ||
20 | import org.eclipse.viatra.query.runtime.api.IPatternMatch; | ||
21 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification; | ||
22 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; | ||
23 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; | ||
24 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; | ||
25 | import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; | ||
26 | import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; | ||
27 | import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; | ||
28 | import org.eclipse.viatra.query.runtime.emf.types.EStructuralFeatureInstancesKey; | ||
29 | import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; | ||
30 | import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; | ||
31 | import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; | ||
32 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; | ||
33 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; | ||
34 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality; | ||
35 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; | ||
36 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; | ||
37 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; | ||
38 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; | ||
39 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; | ||
40 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; | ||
41 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | ||
42 | import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; | ||
43 | |||
44 | /** | ||
45 | * A pattern-specific query specification that can instantiate Matcher in a type-safe way. | ||
46 | * | ||
47 | * <p>Original source: | ||
48 | * <code><pre> | ||
49 | * ///////// | ||
50 | * // Final | ||
51 | * ///////// | ||
52 | * | ||
53 | * {@literal @}Constraint(severity="error", message="error", key = {f}) | ||
54 | * pattern outgoingFromFinal(t : Transition, f : FinalState) { | ||
55 | * FinalState.outgoingTransitions(f,t); | ||
56 | * } | ||
57 | * </pre></code> | ||
58 | * | ||
59 | * @see Matcher | ||
60 | * @see Match | ||
61 | * | ||
62 | */ | ||
63 | @SuppressWarnings("all") | ||
64 | public final class OutgoingFromFinal extends BaseGeneratedEMFQuerySpecification<OutgoingFromFinal.Matcher> { | ||
65 | /** | ||
66 | * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.outgoingFromFinal pattern, | ||
67 | * to be used in conjunction with {@link Matcher}. | ||
68 | * | ||
69 | * <p>Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. | ||
70 | * Each instance is a (possibly partial) substitution of pattern parameters, | ||
71 | * usable to represent a match of the pattern in the result of a query, | ||
72 | * or to specify the bound (fixed) input parameters when issuing a query. | ||
73 | * | ||
74 | * @see Matcher | ||
75 | * | ||
76 | */ | ||
77 | public static abstract class Match extends BasePatternMatch { | ||
78 | private Transition fT; | ||
79 | |||
80 | private FinalState fF; | ||
81 | |||
82 | private static List<String> parameterNames = makeImmutableList("t", "f"); | ||
83 | |||
84 | private Match(final Transition pT, final FinalState pF) { | ||
85 | this.fT = pT; | ||
86 | this.fF = pF; | ||
87 | } | ||
88 | |||
89 | @Override | ||
90 | public Object get(final String parameterName) { | ||
91 | if ("t".equals(parameterName)) return this.fT; | ||
92 | if ("f".equals(parameterName)) return this.fF; | ||
93 | return null; | ||
94 | } | ||
95 | |||
96 | public Transition getT() { | ||
97 | return this.fT; | ||
98 | } | ||
99 | |||
100 | public FinalState getF() { | ||
101 | return this.fF; | ||
102 | } | ||
103 | |||
104 | @Override | ||
105 | public boolean set(final String parameterName, final Object newValue) { | ||
106 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
107 | if ("t".equals(parameterName) ) { | ||
108 | this.fT = (Transition) newValue; | ||
109 | return true; | ||
110 | } | ||
111 | if ("f".equals(parameterName) ) { | ||
112 | this.fF = (FinalState) newValue; | ||
113 | return true; | ||
114 | } | ||
115 | return false; | ||
116 | } | ||
117 | |||
118 | public void setT(final Transition pT) { | ||
119 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
120 | this.fT = pT; | ||
121 | } | ||
122 | |||
123 | public void setF(final FinalState pF) { | ||
124 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
125 | this.fF = pF; | ||
126 | } | ||
127 | |||
128 | @Override | ||
129 | public String patternName() { | ||
130 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.outgoingFromFinal"; | ||
131 | } | ||
132 | |||
133 | @Override | ||
134 | public List<String> parameterNames() { | ||
135 | return OutgoingFromFinal.Match.parameterNames; | ||
136 | } | ||
137 | |||
138 | @Override | ||
139 | public Object[] toArray() { | ||
140 | return new Object[]{fT, fF}; | ||
141 | } | ||
142 | |||
143 | @Override | ||
144 | public OutgoingFromFinal.Match toImmutable() { | ||
145 | return isMutable() ? newMatch(fT, fF) : this; | ||
146 | } | ||
147 | |||
148 | @Override | ||
149 | public String prettyPrint() { | ||
150 | StringBuilder result = new StringBuilder(); | ||
151 | result.append("\"t\"=" + prettyPrintValue(fT) + ", "); | ||
152 | result.append("\"f\"=" + prettyPrintValue(fF)); | ||
153 | return result.toString(); | ||
154 | } | ||
155 | |||
156 | @Override | ||
157 | public int hashCode() { | ||
158 | return Objects.hash(fT, fF); | ||
159 | } | ||
160 | |||
161 | @Override | ||
162 | public boolean equals(final Object obj) { | ||
163 | if (this == obj) | ||
164 | return true; | ||
165 | if (obj == null) { | ||
166 | return false; | ||
167 | } | ||
168 | if ((obj instanceof OutgoingFromFinal.Match)) { | ||
169 | OutgoingFromFinal.Match other = (OutgoingFromFinal.Match) obj; | ||
170 | return Objects.equals(fT, other.fT) && Objects.equals(fF, other.fF); | ||
171 | } else { | ||
172 | // this should be infrequent | ||
173 | if (!(obj instanceof IPatternMatch)) { | ||
174 | return false; | ||
175 | } | ||
176 | IPatternMatch otherSig = (IPatternMatch) obj; | ||
177 | return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); | ||
178 | } | ||
179 | } | ||
180 | |||
181 | @Override | ||
182 | public OutgoingFromFinal specification() { | ||
183 | return OutgoingFromFinal.instance(); | ||
184 | } | ||
185 | |||
186 | /** | ||
187 | * Returns an empty, mutable match. | ||
188 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
189 | * | ||
190 | * @return the empty match. | ||
191 | * | ||
192 | */ | ||
193 | public static OutgoingFromFinal.Match newEmptyMatch() { | ||
194 | return new Mutable(null, null); | ||
195 | } | ||
196 | |||
197 | /** | ||
198 | * Returns a mutable (partial) match. | ||
199 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
200 | * | ||
201 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
202 | * @param pF the fixed value of pattern parameter f, or null if not bound. | ||
203 | * @return the new, mutable (partial) match object. | ||
204 | * | ||
205 | */ | ||
206 | public static OutgoingFromFinal.Match newMutableMatch(final Transition pT, final FinalState pF) { | ||
207 | return new Mutable(pT, pF); | ||
208 | } | ||
209 | |||
210 | /** | ||
211 | * Returns a new (partial) match. | ||
212 | * This can be used e.g. to call the matcher with a partial match. | ||
213 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
214 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
215 | * @param pF the fixed value of pattern parameter f, or null if not bound. | ||
216 | * @return the (partial) match object. | ||
217 | * | ||
218 | */ | ||
219 | public static OutgoingFromFinal.Match newMatch(final Transition pT, final FinalState pF) { | ||
220 | return new Immutable(pT, pF); | ||
221 | } | ||
222 | |||
223 | private static final class Mutable extends OutgoingFromFinal.Match { | ||
224 | Mutable(final Transition pT, final FinalState pF) { | ||
225 | super(pT, pF); | ||
226 | } | ||
227 | |||
228 | @Override | ||
229 | public boolean isMutable() { | ||
230 | return true; | ||
231 | } | ||
232 | } | ||
233 | |||
234 | private static final class Immutable extends OutgoingFromFinal.Match { | ||
235 | Immutable(final Transition pT, final FinalState pF) { | ||
236 | super(pT, pF); | ||
237 | } | ||
238 | |||
239 | @Override | ||
240 | public boolean isMutable() { | ||
241 | return false; | ||
242 | } | ||
243 | } | ||
244 | } | ||
245 | |||
246 | /** | ||
247 | * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.outgoingFromFinal pattern, | ||
248 | * providing pattern-specific query methods. | ||
249 | * | ||
250 | * <p>Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, | ||
251 | * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. | ||
252 | * | ||
253 | * <p>Matches of the pattern will be represented as {@link Match}. | ||
254 | * | ||
255 | * <p>Original source: | ||
256 | * <code><pre> | ||
257 | * ///////// | ||
258 | * // Final | ||
259 | * ///////// | ||
260 | * | ||
261 | * {@literal @}Constraint(severity="error", message="error", key = {f}) | ||
262 | * pattern outgoingFromFinal(t : Transition, f : FinalState) { | ||
263 | * FinalState.outgoingTransitions(f,t); | ||
264 | * } | ||
265 | * </pre></code> | ||
266 | * | ||
267 | * @see Match | ||
268 | * @see OutgoingFromFinal | ||
269 | * | ||
270 | */ | ||
271 | public static class Matcher extends BaseMatcher<OutgoingFromFinal.Match> { | ||
272 | /** | ||
273 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
274 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
275 | * | ||
276 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
277 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
278 | * | ||
279 | */ | ||
280 | public static OutgoingFromFinal.Matcher on(final ViatraQueryEngine engine) { | ||
281 | // check if matcher already exists | ||
282 | Matcher matcher = engine.getExistingMatcher(querySpecification()); | ||
283 | if (matcher == null) { | ||
284 | matcher = (Matcher)engine.getMatcher(querySpecification()); | ||
285 | } | ||
286 | return matcher; | ||
287 | } | ||
288 | |||
289 | /** | ||
290 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
291 | * @return an initialized matcher | ||
292 | * @noreference This method is for internal matcher initialization by the framework, do not call it manually. | ||
293 | * | ||
294 | */ | ||
295 | public static OutgoingFromFinal.Matcher create() { | ||
296 | return new Matcher(); | ||
297 | } | ||
298 | |||
299 | private final static int POSITION_T = 0; | ||
300 | |||
301 | private final static int POSITION_F = 1; | ||
302 | |||
303 | private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(OutgoingFromFinal.Matcher.class); | ||
304 | |||
305 | /** | ||
306 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
307 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
308 | * | ||
309 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
310 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
311 | * | ||
312 | */ | ||
313 | private Matcher() { | ||
314 | super(querySpecification()); | ||
315 | } | ||
316 | |||
317 | /** | ||
318 | * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. | ||
319 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
320 | * @param pF the fixed value of pattern parameter f, or null if not bound. | ||
321 | * @return matches represented as a Match object. | ||
322 | * | ||
323 | */ | ||
324 | public Collection<OutgoingFromFinal.Match> getAllMatches(final Transition pT, final FinalState pF) { | ||
325 | return rawStreamAllMatches(new Object[]{pT, pF}).collect(Collectors.toSet()); | ||
326 | } | ||
327 | |||
328 | /** | ||
329 | * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. | ||
330 | * </p> | ||
331 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
332 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
333 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
334 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
335 | * @param pF the fixed value of pattern parameter f, or null if not bound. | ||
336 | * @return a stream of matches represented as a Match object. | ||
337 | * | ||
338 | */ | ||
339 | public Stream<OutgoingFromFinal.Match> streamAllMatches(final Transition pT, final FinalState pF) { | ||
340 | return rawStreamAllMatches(new Object[]{pT, pF}); | ||
341 | } | ||
342 | |||
343 | /** | ||
344 | * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
345 | * Neither determinism nor randomness of selection is guaranteed. | ||
346 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
347 | * @param pF the fixed value of pattern parameter f, or null if not bound. | ||
348 | * @return a match represented as a Match object, or null if no match is found. | ||
349 | * | ||
350 | */ | ||
351 | public Optional<OutgoingFromFinal.Match> getOneArbitraryMatch(final Transition pT, final FinalState pF) { | ||
352 | return rawGetOneArbitraryMatch(new Object[]{pT, pF}); | ||
353 | } | ||
354 | |||
355 | /** | ||
356 | * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, | ||
357 | * under any possible substitution of the unspecified parameters (if any). | ||
358 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
359 | * @param pF the fixed value of pattern parameter f, or null if not bound. | ||
360 | * @return true if the input is a valid (partial) match of the pattern. | ||
361 | * | ||
362 | */ | ||
363 | public boolean hasMatch(final Transition pT, final FinalState pF) { | ||
364 | return rawHasMatch(new Object[]{pT, pF}); | ||
365 | } | ||
366 | |||
367 | /** | ||
368 | * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. | ||
369 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
370 | * @param pF the fixed value of pattern parameter f, or null if not bound. | ||
371 | * @return the number of pattern matches found. | ||
372 | * | ||
373 | */ | ||
374 | public int countMatches(final Transition pT, final FinalState pF) { | ||
375 | return rawCountMatches(new Object[]{pT, pF}); | ||
376 | } | ||
377 | |||
378 | /** | ||
379 | * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
380 | * Neither determinism nor randomness of selection is guaranteed. | ||
381 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
382 | * @param pF the fixed value of pattern parameter f, or null if not bound. | ||
383 | * @param processor the action that will process the selected match. | ||
384 | * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked | ||
385 | * | ||
386 | */ | ||
387 | public boolean forOneArbitraryMatch(final Transition pT, final FinalState pF, final Consumer<? super OutgoingFromFinal.Match> processor) { | ||
388 | return rawForOneArbitraryMatch(new Object[]{pT, pF}, processor); | ||
389 | } | ||
390 | |||
391 | /** | ||
392 | * Returns a new (partial) match. | ||
393 | * This can be used e.g. to call the matcher with a partial match. | ||
394 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
395 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
396 | * @param pF the fixed value of pattern parameter f, or null if not bound. | ||
397 | * @return the (partial) match object. | ||
398 | * | ||
399 | */ | ||
400 | public OutgoingFromFinal.Match newMatch(final Transition pT, final FinalState pF) { | ||
401 | return OutgoingFromFinal.Match.newMatch(pT, pF); | ||
402 | } | ||
403 | |||
404 | /** | ||
405 | * Retrieve the set of values that occur in matches for t. | ||
406 | * @return the Set of all values or empty set if there are no matches | ||
407 | * | ||
408 | */ | ||
409 | protected Stream<Transition> rawStreamAllValuesOft(final Object[] parameters) { | ||
410 | return rawStreamAllValues(POSITION_T, parameters).map(Transition.class::cast); | ||
411 | } | ||
412 | |||
413 | /** | ||
414 | * Retrieve the set of values that occur in matches for t. | ||
415 | * @return the Set of all values or empty set if there are no matches | ||
416 | * | ||
417 | */ | ||
418 | public Set<Transition> getAllValuesOft() { | ||
419 | return rawStreamAllValuesOft(emptyArray()).collect(Collectors.toSet()); | ||
420 | } | ||
421 | |||
422 | /** | ||
423 | * Retrieve the set of values that occur in matches for t. | ||
424 | * @return the Set of all values or empty set if there are no matches | ||
425 | * | ||
426 | */ | ||
427 | public Stream<Transition> streamAllValuesOft() { | ||
428 | return rawStreamAllValuesOft(emptyArray()); | ||
429 | } | ||
430 | |||
431 | /** | ||
432 | * Retrieve the set of values that occur in matches for t. | ||
433 | * </p> | ||
434 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
435 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
436 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
437 | * | ||
438 | * @return the Stream of all values or empty set if there are no matches | ||
439 | * | ||
440 | */ | ||
441 | public Stream<Transition> streamAllValuesOft(final OutgoingFromFinal.Match partialMatch) { | ||
442 | return rawStreamAllValuesOft(partialMatch.toArray()); | ||
443 | } | ||
444 | |||
445 | /** | ||
446 | * Retrieve the set of values that occur in matches for t. | ||
447 | * </p> | ||
448 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
449 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
450 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
451 | * | ||
452 | * @return the Stream of all values or empty set if there are no matches | ||
453 | * | ||
454 | */ | ||
455 | public Stream<Transition> streamAllValuesOft(final FinalState pF) { | ||
456 | return rawStreamAllValuesOft(new Object[]{null, pF}); | ||
457 | } | ||
458 | |||
459 | /** | ||
460 | * Retrieve the set of values that occur in matches for t. | ||
461 | * @return the Set of all values or empty set if there are no matches | ||
462 | * | ||
463 | */ | ||
464 | public Set<Transition> getAllValuesOft(final OutgoingFromFinal.Match partialMatch) { | ||
465 | return rawStreamAllValuesOft(partialMatch.toArray()).collect(Collectors.toSet()); | ||
466 | } | ||
467 | |||
468 | /** | ||
469 | * Retrieve the set of values that occur in matches for t. | ||
470 | * @return the Set of all values or empty set if there are no matches | ||
471 | * | ||
472 | */ | ||
473 | public Set<Transition> getAllValuesOft(final FinalState pF) { | ||
474 | return rawStreamAllValuesOft(new Object[]{null, pF}).collect(Collectors.toSet()); | ||
475 | } | ||
476 | |||
477 | /** | ||
478 | * Retrieve the set of values that occur in matches for f. | ||
479 | * @return the Set of all values or empty set if there are no matches | ||
480 | * | ||
481 | */ | ||
482 | protected Stream<FinalState> rawStreamAllValuesOff(final Object[] parameters) { | ||
483 | return rawStreamAllValues(POSITION_F, parameters).map(FinalState.class::cast); | ||
484 | } | ||
485 | |||
486 | /** | ||
487 | * Retrieve the set of values that occur in matches for f. | ||
488 | * @return the Set of all values or empty set if there are no matches | ||
489 | * | ||
490 | */ | ||
491 | public Set<FinalState> getAllValuesOff() { | ||
492 | return rawStreamAllValuesOff(emptyArray()).collect(Collectors.toSet()); | ||
493 | } | ||
494 | |||
495 | /** | ||
496 | * Retrieve the set of values that occur in matches for f. | ||
497 | * @return the Set of all values or empty set if there are no matches | ||
498 | * | ||
499 | */ | ||
500 | public Stream<FinalState> streamAllValuesOff() { | ||
501 | return rawStreamAllValuesOff(emptyArray()); | ||
502 | } | ||
503 | |||
504 | /** | ||
505 | * Retrieve the set of values that occur in matches for f. | ||
506 | * </p> | ||
507 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
508 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
509 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
510 | * | ||
511 | * @return the Stream of all values or empty set if there are no matches | ||
512 | * | ||
513 | */ | ||
514 | public Stream<FinalState> streamAllValuesOff(final OutgoingFromFinal.Match partialMatch) { | ||
515 | return rawStreamAllValuesOff(partialMatch.toArray()); | ||
516 | } | ||
517 | |||
518 | /** | ||
519 | * Retrieve the set of values that occur in matches for f. | ||
520 | * </p> | ||
521 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
522 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
523 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
524 | * | ||
525 | * @return the Stream of all values or empty set if there are no matches | ||
526 | * | ||
527 | */ | ||
528 | public Stream<FinalState> streamAllValuesOff(final Transition pT) { | ||
529 | return rawStreamAllValuesOff(new Object[]{pT, null}); | ||
530 | } | ||
531 | |||
532 | /** | ||
533 | * Retrieve the set of values that occur in matches for f. | ||
534 | * @return the Set of all values or empty set if there are no matches | ||
535 | * | ||
536 | */ | ||
537 | public Set<FinalState> getAllValuesOff(final OutgoingFromFinal.Match partialMatch) { | ||
538 | return rawStreamAllValuesOff(partialMatch.toArray()).collect(Collectors.toSet()); | ||
539 | } | ||
540 | |||
541 | /** | ||
542 | * Retrieve the set of values that occur in matches for f. | ||
543 | * @return the Set of all values or empty set if there are no matches | ||
544 | * | ||
545 | */ | ||
546 | public Set<FinalState> getAllValuesOff(final Transition pT) { | ||
547 | return rawStreamAllValuesOff(new Object[]{pT, null}).collect(Collectors.toSet()); | ||
548 | } | ||
549 | |||
550 | @Override | ||
551 | protected OutgoingFromFinal.Match tupleToMatch(final Tuple t) { | ||
552 | try { | ||
553 | return OutgoingFromFinal.Match.newMatch((Transition) t.get(POSITION_T), (FinalState) t.get(POSITION_F)); | ||
554 | } catch(ClassCastException e) { | ||
555 | LOGGER.error("Element(s) in tuple not properly typed!",e); | ||
556 | return null; | ||
557 | } | ||
558 | } | ||
559 | |||
560 | @Override | ||
561 | protected OutgoingFromFinal.Match arrayToMatch(final Object[] match) { | ||
562 | try { | ||
563 | return OutgoingFromFinal.Match.newMatch((Transition) match[POSITION_T], (FinalState) match[POSITION_F]); | ||
564 | } catch(ClassCastException e) { | ||
565 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
566 | return null; | ||
567 | } | ||
568 | } | ||
569 | |||
570 | @Override | ||
571 | protected OutgoingFromFinal.Match arrayToMatchMutable(final Object[] match) { | ||
572 | try { | ||
573 | return OutgoingFromFinal.Match.newMutableMatch((Transition) match[POSITION_T], (FinalState) match[POSITION_F]); | ||
574 | } catch(ClassCastException e) { | ||
575 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
576 | return null; | ||
577 | } | ||
578 | } | ||
579 | |||
580 | /** | ||
581 | * @return the singleton instance of the query specification of this pattern | ||
582 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
583 | * | ||
584 | */ | ||
585 | public static IQuerySpecification<OutgoingFromFinal.Matcher> querySpecification() { | ||
586 | return OutgoingFromFinal.instance(); | ||
587 | } | ||
588 | } | ||
589 | |||
590 | private OutgoingFromFinal() { | ||
591 | super(GeneratedPQuery.INSTANCE); | ||
592 | } | ||
593 | |||
594 | /** | ||
595 | * @return the singleton instance of the query specification | ||
596 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
597 | * | ||
598 | */ | ||
599 | public static OutgoingFromFinal instance() { | ||
600 | try{ | ||
601 | return LazyHolder.INSTANCE; | ||
602 | } catch (ExceptionInInitializerError err) { | ||
603 | throw processInitializerError(err); | ||
604 | } | ||
605 | } | ||
606 | |||
607 | @Override | ||
608 | protected OutgoingFromFinal.Matcher instantiate(final ViatraQueryEngine engine) { | ||
609 | return OutgoingFromFinal.Matcher.on(engine); | ||
610 | } | ||
611 | |||
612 | @Override | ||
613 | public OutgoingFromFinal.Matcher instantiate() { | ||
614 | return OutgoingFromFinal.Matcher.create(); | ||
615 | } | ||
616 | |||
617 | @Override | ||
618 | public OutgoingFromFinal.Match newEmptyMatch() { | ||
619 | return OutgoingFromFinal.Match.newEmptyMatch(); | ||
620 | } | ||
621 | |||
622 | @Override | ||
623 | public OutgoingFromFinal.Match newMatch(final Object... parameters) { | ||
624 | return OutgoingFromFinal.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition) parameters[0], (ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.FinalState) parameters[1]); | ||
625 | } | ||
626 | |||
627 | /** | ||
628 | * Inner class allowing the singleton instance of {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.OutgoingFromFinal (visibility: PUBLIC, simpleName: OutgoingFromFinal, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.OutgoingFromFinal, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created | ||
629 | * <b>not</b> at the class load time of the outer class, | ||
630 | * but rather at the first call to {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.OutgoingFromFinal (visibility: PUBLIC, simpleName: OutgoingFromFinal, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.OutgoingFromFinal, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. | ||
631 | * | ||
632 | * <p> This workaround is required e.g. to support recursion. | ||
633 | * | ||
634 | */ | ||
635 | private static class LazyHolder { | ||
636 | private final static OutgoingFromFinal INSTANCE = new OutgoingFromFinal(); | ||
637 | |||
638 | /** | ||
639 | * Statically initializes the query specification <b>after</b> the field {@link #INSTANCE} is assigned. | ||
640 | * This initialization order is required to support indirect recursion. | ||
641 | * | ||
642 | * <p> The static initializer is defined using a helper field to work around limitations of the code generator. | ||
643 | * | ||
644 | */ | ||
645 | private final static Object STATIC_INITIALIZER = ensureInitialized(); | ||
646 | |||
647 | public static Object ensureInitialized() { | ||
648 | INSTANCE.ensureInitializedInternal(); | ||
649 | return null; | ||
650 | } | ||
651 | } | ||
652 | |||
653 | private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { | ||
654 | private final static OutgoingFromFinal.GeneratedPQuery INSTANCE = new GeneratedPQuery(); | ||
655 | |||
656 | private final PParameter parameter_t = new PParameter("t", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Transition")), PParameterDirection.INOUT); | ||
657 | |||
658 | private final PParameter parameter_f = new PParameter("f", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.FinalState", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "FinalState")), PParameterDirection.INOUT); | ||
659 | |||
660 | private final List<PParameter> parameters = Arrays.asList(parameter_t, parameter_f); | ||
661 | |||
662 | private GeneratedPQuery() { | ||
663 | super(PVisibility.PUBLIC); | ||
664 | } | ||
665 | |||
666 | @Override | ||
667 | public String getFullyQualifiedName() { | ||
668 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.outgoingFromFinal"; | ||
669 | } | ||
670 | |||
671 | @Override | ||
672 | public List<String> getParameterNames() { | ||
673 | return Arrays.asList("t","f"); | ||
674 | } | ||
675 | |||
676 | @Override | ||
677 | public List<PParameter> getParameters() { | ||
678 | return parameters; | ||
679 | } | ||
680 | |||
681 | @Override | ||
682 | public Set<PBody> doGetContainedBodies() { | ||
683 | setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); | ||
684 | Set<PBody> bodies = new LinkedHashSet<>(); | ||
685 | { | ||
686 | PBody body = new PBody(this); | ||
687 | PVariable var_t = body.getOrCreateVariableByName("t"); | ||
688 | PVariable var_f = body.getOrCreateVariableByName("f"); | ||
689 | new TypeConstraint(body, Tuples.flatTupleOf(var_t), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); | ||
690 | new TypeConstraint(body, Tuples.flatTupleOf(var_f), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "FinalState"))); | ||
691 | body.setSymbolicParameters(Arrays.<ExportedParameter>asList( | ||
692 | new ExportedParameter(body, var_t, parameter_t), | ||
693 | new ExportedParameter(body, var_f, parameter_f) | ||
694 | )); | ||
695 | // FinalState.outgoingTransitions(f,t) | ||
696 | new TypeConstraint(body, Tuples.flatTupleOf(var_f), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "FinalState"))); | ||
697 | PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); | ||
698 | new TypeConstraint(body, Tuples.flatTupleOf(var_f, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Vertex", "outgoingTransitions"))); | ||
699 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); | ||
700 | new Equality(body, var__virtual_0_, var_t); | ||
701 | bodies.add(body); | ||
702 | } | ||
703 | { | ||
704 | PAnnotation annotation = new PAnnotation("Constraint"); | ||
705 | annotation.addAttribute("severity", "error"); | ||
706 | annotation.addAttribute("message", "error"); | ||
707 | annotation.addAttribute("key", Arrays.asList(new Object[] { | ||
708 | new ParameterReference("f") | ||
709 | })); | ||
710 | addAnnotation(annotation); | ||
711 | } | ||
712 | return bodies; | ||
713 | } | ||
714 | } | ||
715 | } | ||
diff --git a/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/StateInRegion.java b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/StateInRegion.java new file mode 100644 index 00000000..0d1fd0e6 --- /dev/null +++ b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/StateInRegion.java | |||
@@ -0,0 +1,694 @@ | |||
1 | /** | ||
2 | * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql | ||
3 | */ | ||
4 | package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; | ||
5 | |||
6 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Region; | ||
7 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.State; | ||
8 | import java.util.Arrays; | ||
9 | import java.util.Collection; | ||
10 | import java.util.LinkedHashSet; | ||
11 | import java.util.List; | ||
12 | import java.util.Objects; | ||
13 | import java.util.Optional; | ||
14 | import java.util.Set; | ||
15 | import java.util.function.Consumer; | ||
16 | import java.util.stream.Collectors; | ||
17 | import java.util.stream.Stream; | ||
18 | import org.apache.log4j.Logger; | ||
19 | import org.eclipse.emf.ecore.EClass; | ||
20 | import org.eclipse.viatra.query.runtime.api.IPatternMatch; | ||
21 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification; | ||
22 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; | ||
23 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; | ||
24 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; | ||
25 | import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; | ||
26 | import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; | ||
27 | import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; | ||
28 | import org.eclipse.viatra.query.runtime.emf.types.EStructuralFeatureInstancesKey; | ||
29 | import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; | ||
30 | import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; | ||
31 | import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; | ||
32 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality; | ||
33 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; | ||
34 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; | ||
35 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; | ||
36 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; | ||
37 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; | ||
38 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; | ||
39 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | ||
40 | import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; | ||
41 | |||
42 | /** | ||
43 | * A pattern-specific query specification that can instantiate Matcher in a type-safe way. | ||
44 | * | ||
45 | * <p>Original source: | ||
46 | * <code><pre> | ||
47 | * pattern StateInRegion(region: Region, state: State) { | ||
48 | * Region.vertices(region,state); | ||
49 | * } | ||
50 | * </pre></code> | ||
51 | * | ||
52 | * @see Matcher | ||
53 | * @see Match | ||
54 | * | ||
55 | */ | ||
56 | @SuppressWarnings("all") | ||
57 | public final class StateInRegion extends BaseGeneratedEMFQuerySpecification<StateInRegion.Matcher> { | ||
58 | /** | ||
59 | * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.StateInRegion pattern, | ||
60 | * to be used in conjunction with {@link Matcher}. | ||
61 | * | ||
62 | * <p>Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. | ||
63 | * Each instance is a (possibly partial) substitution of pattern parameters, | ||
64 | * usable to represent a match of the pattern in the result of a query, | ||
65 | * or to specify the bound (fixed) input parameters when issuing a query. | ||
66 | * | ||
67 | * @see Matcher | ||
68 | * | ||
69 | */ | ||
70 | public static abstract class Match extends BasePatternMatch { | ||
71 | private Region fRegion; | ||
72 | |||
73 | private State fState; | ||
74 | |||
75 | private static List<String> parameterNames = makeImmutableList("region", "state"); | ||
76 | |||
77 | private Match(final Region pRegion, final State pState) { | ||
78 | this.fRegion = pRegion; | ||
79 | this.fState = pState; | ||
80 | } | ||
81 | |||
82 | @Override | ||
83 | public Object get(final String parameterName) { | ||
84 | if ("region".equals(parameterName)) return this.fRegion; | ||
85 | if ("state".equals(parameterName)) return this.fState; | ||
86 | return null; | ||
87 | } | ||
88 | |||
89 | public Region getRegion() { | ||
90 | return this.fRegion; | ||
91 | } | ||
92 | |||
93 | public State getState() { | ||
94 | return this.fState; | ||
95 | } | ||
96 | |||
97 | @Override | ||
98 | public boolean set(final String parameterName, final Object newValue) { | ||
99 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
100 | if ("region".equals(parameterName) ) { | ||
101 | this.fRegion = (Region) newValue; | ||
102 | return true; | ||
103 | } | ||
104 | if ("state".equals(parameterName) ) { | ||
105 | this.fState = (State) newValue; | ||
106 | return true; | ||
107 | } | ||
108 | return false; | ||
109 | } | ||
110 | |||
111 | public void setRegion(final Region pRegion) { | ||
112 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
113 | this.fRegion = pRegion; | ||
114 | } | ||
115 | |||
116 | public void setState(final State pState) { | ||
117 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
118 | this.fState = pState; | ||
119 | } | ||
120 | |||
121 | @Override | ||
122 | public String patternName() { | ||
123 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.StateInRegion"; | ||
124 | } | ||
125 | |||
126 | @Override | ||
127 | public List<String> parameterNames() { | ||
128 | return StateInRegion.Match.parameterNames; | ||
129 | } | ||
130 | |||
131 | @Override | ||
132 | public Object[] toArray() { | ||
133 | return new Object[]{fRegion, fState}; | ||
134 | } | ||
135 | |||
136 | @Override | ||
137 | public StateInRegion.Match toImmutable() { | ||
138 | return isMutable() ? newMatch(fRegion, fState) : this; | ||
139 | } | ||
140 | |||
141 | @Override | ||
142 | public String prettyPrint() { | ||
143 | StringBuilder result = new StringBuilder(); | ||
144 | result.append("\"region\"=" + prettyPrintValue(fRegion) + ", "); | ||
145 | result.append("\"state\"=" + prettyPrintValue(fState)); | ||
146 | return result.toString(); | ||
147 | } | ||
148 | |||
149 | @Override | ||
150 | public int hashCode() { | ||
151 | return Objects.hash(fRegion, fState); | ||
152 | } | ||
153 | |||
154 | @Override | ||
155 | public boolean equals(final Object obj) { | ||
156 | if (this == obj) | ||
157 | return true; | ||
158 | if (obj == null) { | ||
159 | return false; | ||
160 | } | ||
161 | if ((obj instanceof StateInRegion.Match)) { | ||
162 | StateInRegion.Match other = (StateInRegion.Match) obj; | ||
163 | return Objects.equals(fRegion, other.fRegion) && Objects.equals(fState, other.fState); | ||
164 | } else { | ||
165 | // this should be infrequent | ||
166 | if (!(obj instanceof IPatternMatch)) { | ||
167 | return false; | ||
168 | } | ||
169 | IPatternMatch otherSig = (IPatternMatch) obj; | ||
170 | return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); | ||
171 | } | ||
172 | } | ||
173 | |||
174 | @Override | ||
175 | public StateInRegion specification() { | ||
176 | return StateInRegion.instance(); | ||
177 | } | ||
178 | |||
179 | /** | ||
180 | * Returns an empty, mutable match. | ||
181 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
182 | * | ||
183 | * @return the empty match. | ||
184 | * | ||
185 | */ | ||
186 | public static StateInRegion.Match newEmptyMatch() { | ||
187 | return new Mutable(null, null); | ||
188 | } | ||
189 | |||
190 | /** | ||
191 | * Returns a mutable (partial) match. | ||
192 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
193 | * | ||
194 | * @param pRegion the fixed value of pattern parameter region, or null if not bound. | ||
195 | * @param pState the fixed value of pattern parameter state, or null if not bound. | ||
196 | * @return the new, mutable (partial) match object. | ||
197 | * | ||
198 | */ | ||
199 | public static StateInRegion.Match newMutableMatch(final Region pRegion, final State pState) { | ||
200 | return new Mutable(pRegion, pState); | ||
201 | } | ||
202 | |||
203 | /** | ||
204 | * Returns a new (partial) match. | ||
205 | * This can be used e.g. to call the matcher with a partial match. | ||
206 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
207 | * @param pRegion the fixed value of pattern parameter region, or null if not bound. | ||
208 | * @param pState the fixed value of pattern parameter state, or null if not bound. | ||
209 | * @return the (partial) match object. | ||
210 | * | ||
211 | */ | ||
212 | public static StateInRegion.Match newMatch(final Region pRegion, final State pState) { | ||
213 | return new Immutable(pRegion, pState); | ||
214 | } | ||
215 | |||
216 | private static final class Mutable extends StateInRegion.Match { | ||
217 | Mutable(final Region pRegion, final State pState) { | ||
218 | super(pRegion, pState); | ||
219 | } | ||
220 | |||
221 | @Override | ||
222 | public boolean isMutable() { | ||
223 | return true; | ||
224 | } | ||
225 | } | ||
226 | |||
227 | private static final class Immutable extends StateInRegion.Match { | ||
228 | Immutable(final Region pRegion, final State pState) { | ||
229 | super(pRegion, pState); | ||
230 | } | ||
231 | |||
232 | @Override | ||
233 | public boolean isMutable() { | ||
234 | return false; | ||
235 | } | ||
236 | } | ||
237 | } | ||
238 | |||
239 | /** | ||
240 | * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.StateInRegion pattern, | ||
241 | * providing pattern-specific query methods. | ||
242 | * | ||
243 | * <p>Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, | ||
244 | * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. | ||
245 | * | ||
246 | * <p>Matches of the pattern will be represented as {@link Match}. | ||
247 | * | ||
248 | * <p>Original source: | ||
249 | * <code><pre> | ||
250 | * pattern StateInRegion(region: Region, state: State) { | ||
251 | * Region.vertices(region,state); | ||
252 | * } | ||
253 | * </pre></code> | ||
254 | * | ||
255 | * @see Match | ||
256 | * @see StateInRegion | ||
257 | * | ||
258 | */ | ||
259 | public static class Matcher extends BaseMatcher<StateInRegion.Match> { | ||
260 | /** | ||
261 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
262 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
263 | * | ||
264 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
265 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
266 | * | ||
267 | */ | ||
268 | public static StateInRegion.Matcher on(final ViatraQueryEngine engine) { | ||
269 | // check if matcher already exists | ||
270 | Matcher matcher = engine.getExistingMatcher(querySpecification()); | ||
271 | if (matcher == null) { | ||
272 | matcher = (Matcher)engine.getMatcher(querySpecification()); | ||
273 | } | ||
274 | return matcher; | ||
275 | } | ||
276 | |||
277 | /** | ||
278 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
279 | * @return an initialized matcher | ||
280 | * @noreference This method is for internal matcher initialization by the framework, do not call it manually. | ||
281 | * | ||
282 | */ | ||
283 | public static StateInRegion.Matcher create() { | ||
284 | return new Matcher(); | ||
285 | } | ||
286 | |||
287 | private final static int POSITION_REGION = 0; | ||
288 | |||
289 | private final static int POSITION_STATE = 1; | ||
290 | |||
291 | private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(StateInRegion.Matcher.class); | ||
292 | |||
293 | /** | ||
294 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
295 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
296 | * | ||
297 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
298 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
299 | * | ||
300 | */ | ||
301 | private Matcher() { | ||
302 | super(querySpecification()); | ||
303 | } | ||
304 | |||
305 | /** | ||
306 | * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. | ||
307 | * @param pRegion the fixed value of pattern parameter region, or null if not bound. | ||
308 | * @param pState the fixed value of pattern parameter state, or null if not bound. | ||
309 | * @return matches represented as a Match object. | ||
310 | * | ||
311 | */ | ||
312 | public Collection<StateInRegion.Match> getAllMatches(final Region pRegion, final State pState) { | ||
313 | return rawStreamAllMatches(new Object[]{pRegion, pState}).collect(Collectors.toSet()); | ||
314 | } | ||
315 | |||
316 | /** | ||
317 | * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. | ||
318 | * </p> | ||
319 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
320 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
321 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
322 | * @param pRegion the fixed value of pattern parameter region, or null if not bound. | ||
323 | * @param pState the fixed value of pattern parameter state, or null if not bound. | ||
324 | * @return a stream of matches represented as a Match object. | ||
325 | * | ||
326 | */ | ||
327 | public Stream<StateInRegion.Match> streamAllMatches(final Region pRegion, final State pState) { | ||
328 | return rawStreamAllMatches(new Object[]{pRegion, pState}); | ||
329 | } | ||
330 | |||
331 | /** | ||
332 | * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
333 | * Neither determinism nor randomness of selection is guaranteed. | ||
334 | * @param pRegion the fixed value of pattern parameter region, or null if not bound. | ||
335 | * @param pState the fixed value of pattern parameter state, or null if not bound. | ||
336 | * @return a match represented as a Match object, or null if no match is found. | ||
337 | * | ||
338 | */ | ||
339 | public Optional<StateInRegion.Match> getOneArbitraryMatch(final Region pRegion, final State pState) { | ||
340 | return rawGetOneArbitraryMatch(new Object[]{pRegion, pState}); | ||
341 | } | ||
342 | |||
343 | /** | ||
344 | * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, | ||
345 | * under any possible substitution of the unspecified parameters (if any). | ||
346 | * @param pRegion the fixed value of pattern parameter region, or null if not bound. | ||
347 | * @param pState the fixed value of pattern parameter state, or null if not bound. | ||
348 | * @return true if the input is a valid (partial) match of the pattern. | ||
349 | * | ||
350 | */ | ||
351 | public boolean hasMatch(final Region pRegion, final State pState) { | ||
352 | return rawHasMatch(new Object[]{pRegion, pState}); | ||
353 | } | ||
354 | |||
355 | /** | ||
356 | * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. | ||
357 | * @param pRegion the fixed value of pattern parameter region, or null if not bound. | ||
358 | * @param pState the fixed value of pattern parameter state, or null if not bound. | ||
359 | * @return the number of pattern matches found. | ||
360 | * | ||
361 | */ | ||
362 | public int countMatches(final Region pRegion, final State pState) { | ||
363 | return rawCountMatches(new Object[]{pRegion, pState}); | ||
364 | } | ||
365 | |||
366 | /** | ||
367 | * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
368 | * Neither determinism nor randomness of selection is guaranteed. | ||
369 | * @param pRegion the fixed value of pattern parameter region, or null if not bound. | ||
370 | * @param pState the fixed value of pattern parameter state, or null if not bound. | ||
371 | * @param processor the action that will process the selected match. | ||
372 | * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked | ||
373 | * | ||
374 | */ | ||
375 | public boolean forOneArbitraryMatch(final Region pRegion, final State pState, final Consumer<? super StateInRegion.Match> processor) { | ||
376 | return rawForOneArbitraryMatch(new Object[]{pRegion, pState}, processor); | ||
377 | } | ||
378 | |||
379 | /** | ||
380 | * Returns a new (partial) match. | ||
381 | * This can be used e.g. to call the matcher with a partial match. | ||
382 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
383 | * @param pRegion the fixed value of pattern parameter region, or null if not bound. | ||
384 | * @param pState the fixed value of pattern parameter state, or null if not bound. | ||
385 | * @return the (partial) match object. | ||
386 | * | ||
387 | */ | ||
388 | public StateInRegion.Match newMatch(final Region pRegion, final State pState) { | ||
389 | return StateInRegion.Match.newMatch(pRegion, pState); | ||
390 | } | ||
391 | |||
392 | /** | ||
393 | * Retrieve the set of values that occur in matches for region. | ||
394 | * @return the Set of all values or empty set if there are no matches | ||
395 | * | ||
396 | */ | ||
397 | protected Stream<Region> rawStreamAllValuesOfregion(final Object[] parameters) { | ||
398 | return rawStreamAllValues(POSITION_REGION, parameters).map(Region.class::cast); | ||
399 | } | ||
400 | |||
401 | /** | ||
402 | * Retrieve the set of values that occur in matches for region. | ||
403 | * @return the Set of all values or empty set if there are no matches | ||
404 | * | ||
405 | */ | ||
406 | public Set<Region> getAllValuesOfregion() { | ||
407 | return rawStreamAllValuesOfregion(emptyArray()).collect(Collectors.toSet()); | ||
408 | } | ||
409 | |||
410 | /** | ||
411 | * Retrieve the set of values that occur in matches for region. | ||
412 | * @return the Set of all values or empty set if there are no matches | ||
413 | * | ||
414 | */ | ||
415 | public Stream<Region> streamAllValuesOfregion() { | ||
416 | return rawStreamAllValuesOfregion(emptyArray()); | ||
417 | } | ||
418 | |||
419 | /** | ||
420 | * Retrieve the set of values that occur in matches for region. | ||
421 | * </p> | ||
422 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
423 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
424 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
425 | * | ||
426 | * @return the Stream of all values or empty set if there are no matches | ||
427 | * | ||
428 | */ | ||
429 | public Stream<Region> streamAllValuesOfregion(final StateInRegion.Match partialMatch) { | ||
430 | return rawStreamAllValuesOfregion(partialMatch.toArray()); | ||
431 | } | ||
432 | |||
433 | /** | ||
434 | * Retrieve the set of values that occur in matches for region. | ||
435 | * </p> | ||
436 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
437 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
438 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
439 | * | ||
440 | * @return the Stream of all values or empty set if there are no matches | ||
441 | * | ||
442 | */ | ||
443 | public Stream<Region> streamAllValuesOfregion(final State pState) { | ||
444 | return rawStreamAllValuesOfregion(new Object[]{null, pState}); | ||
445 | } | ||
446 | |||
447 | /** | ||
448 | * Retrieve the set of values that occur in matches for region. | ||
449 | * @return the Set of all values or empty set if there are no matches | ||
450 | * | ||
451 | */ | ||
452 | public Set<Region> getAllValuesOfregion(final StateInRegion.Match partialMatch) { | ||
453 | return rawStreamAllValuesOfregion(partialMatch.toArray()).collect(Collectors.toSet()); | ||
454 | } | ||
455 | |||
456 | /** | ||
457 | * Retrieve the set of values that occur in matches for region. | ||
458 | * @return the Set of all values or empty set if there are no matches | ||
459 | * | ||
460 | */ | ||
461 | public Set<Region> getAllValuesOfregion(final State pState) { | ||
462 | return rawStreamAllValuesOfregion(new Object[]{null, pState}).collect(Collectors.toSet()); | ||
463 | } | ||
464 | |||
465 | /** | ||
466 | * Retrieve the set of values that occur in matches for state. | ||
467 | * @return the Set of all values or empty set if there are no matches | ||
468 | * | ||
469 | */ | ||
470 | protected Stream<State> rawStreamAllValuesOfstate(final Object[] parameters) { | ||
471 | return rawStreamAllValues(POSITION_STATE, parameters).map(State.class::cast); | ||
472 | } | ||
473 | |||
474 | /** | ||
475 | * Retrieve the set of values that occur in matches for state. | ||
476 | * @return the Set of all values or empty set if there are no matches | ||
477 | * | ||
478 | */ | ||
479 | public Set<State> getAllValuesOfstate() { | ||
480 | return rawStreamAllValuesOfstate(emptyArray()).collect(Collectors.toSet()); | ||
481 | } | ||
482 | |||
483 | /** | ||
484 | * Retrieve the set of values that occur in matches for state. | ||
485 | * @return the Set of all values or empty set if there are no matches | ||
486 | * | ||
487 | */ | ||
488 | public Stream<State> streamAllValuesOfstate() { | ||
489 | return rawStreamAllValuesOfstate(emptyArray()); | ||
490 | } | ||
491 | |||
492 | /** | ||
493 | * Retrieve the set of values that occur in matches for state. | ||
494 | * </p> | ||
495 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
496 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
497 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
498 | * | ||
499 | * @return the Stream of all values or empty set if there are no matches | ||
500 | * | ||
501 | */ | ||
502 | public Stream<State> streamAllValuesOfstate(final StateInRegion.Match partialMatch) { | ||
503 | return rawStreamAllValuesOfstate(partialMatch.toArray()); | ||
504 | } | ||
505 | |||
506 | /** | ||
507 | * Retrieve the set of values that occur in matches for state. | ||
508 | * </p> | ||
509 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
510 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
511 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
512 | * | ||
513 | * @return the Stream of all values or empty set if there are no matches | ||
514 | * | ||
515 | */ | ||
516 | public Stream<State> streamAllValuesOfstate(final Region pRegion) { | ||
517 | return rawStreamAllValuesOfstate(new Object[]{pRegion, null}); | ||
518 | } | ||
519 | |||
520 | /** | ||
521 | * Retrieve the set of values that occur in matches for state. | ||
522 | * @return the Set of all values or empty set if there are no matches | ||
523 | * | ||
524 | */ | ||
525 | public Set<State> getAllValuesOfstate(final StateInRegion.Match partialMatch) { | ||
526 | return rawStreamAllValuesOfstate(partialMatch.toArray()).collect(Collectors.toSet()); | ||
527 | } | ||
528 | |||
529 | /** | ||
530 | * Retrieve the set of values that occur in matches for state. | ||
531 | * @return the Set of all values or empty set if there are no matches | ||
532 | * | ||
533 | */ | ||
534 | public Set<State> getAllValuesOfstate(final Region pRegion) { | ||
535 | return rawStreamAllValuesOfstate(new Object[]{pRegion, null}).collect(Collectors.toSet()); | ||
536 | } | ||
537 | |||
538 | @Override | ||
539 | protected StateInRegion.Match tupleToMatch(final Tuple t) { | ||
540 | try { | ||
541 | return StateInRegion.Match.newMatch((Region) t.get(POSITION_REGION), (State) t.get(POSITION_STATE)); | ||
542 | } catch(ClassCastException e) { | ||
543 | LOGGER.error("Element(s) in tuple not properly typed!",e); | ||
544 | return null; | ||
545 | } | ||
546 | } | ||
547 | |||
548 | @Override | ||
549 | protected StateInRegion.Match arrayToMatch(final Object[] match) { | ||
550 | try { | ||
551 | return StateInRegion.Match.newMatch((Region) match[POSITION_REGION], (State) match[POSITION_STATE]); | ||
552 | } catch(ClassCastException e) { | ||
553 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
554 | return null; | ||
555 | } | ||
556 | } | ||
557 | |||
558 | @Override | ||
559 | protected StateInRegion.Match arrayToMatchMutable(final Object[] match) { | ||
560 | try { | ||
561 | return StateInRegion.Match.newMutableMatch((Region) match[POSITION_REGION], (State) match[POSITION_STATE]); | ||
562 | } catch(ClassCastException e) { | ||
563 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
564 | return null; | ||
565 | } | ||
566 | } | ||
567 | |||
568 | /** | ||
569 | * @return the singleton instance of the query specification of this pattern | ||
570 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
571 | * | ||
572 | */ | ||
573 | public static IQuerySpecification<StateInRegion.Matcher> querySpecification() { | ||
574 | return StateInRegion.instance(); | ||
575 | } | ||
576 | } | ||
577 | |||
578 | private StateInRegion() { | ||
579 | super(GeneratedPQuery.INSTANCE); | ||
580 | } | ||
581 | |||
582 | /** | ||
583 | * @return the singleton instance of the query specification | ||
584 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
585 | * | ||
586 | */ | ||
587 | public static StateInRegion instance() { | ||
588 | try{ | ||
589 | return LazyHolder.INSTANCE; | ||
590 | } catch (ExceptionInInitializerError err) { | ||
591 | throw processInitializerError(err); | ||
592 | } | ||
593 | } | ||
594 | |||
595 | @Override | ||
596 | protected StateInRegion.Matcher instantiate(final ViatraQueryEngine engine) { | ||
597 | return StateInRegion.Matcher.on(engine); | ||
598 | } | ||
599 | |||
600 | @Override | ||
601 | public StateInRegion.Matcher instantiate() { | ||
602 | return StateInRegion.Matcher.create(); | ||
603 | } | ||
604 | |||
605 | @Override | ||
606 | public StateInRegion.Match newEmptyMatch() { | ||
607 | return StateInRegion.Match.newEmptyMatch(); | ||
608 | } | ||
609 | |||
610 | @Override | ||
611 | public StateInRegion.Match newMatch(final Object... parameters) { | ||
612 | return StateInRegion.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Region) parameters[0], (ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.State) parameters[1]); | ||
613 | } | ||
614 | |||
615 | /** | ||
616 | * Inner class allowing the singleton instance of {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.StateInRegion (visibility: PUBLIC, simpleName: StateInRegion, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.StateInRegion, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created | ||
617 | * <b>not</b> at the class load time of the outer class, | ||
618 | * but rather at the first call to {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.StateInRegion (visibility: PUBLIC, simpleName: StateInRegion, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.StateInRegion, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. | ||
619 | * | ||
620 | * <p> This workaround is required e.g. to support recursion. | ||
621 | * | ||
622 | */ | ||
623 | private static class LazyHolder { | ||
624 | private final static StateInRegion INSTANCE = new StateInRegion(); | ||
625 | |||
626 | /** | ||
627 | * Statically initializes the query specification <b>after</b> the field {@link #INSTANCE} is assigned. | ||
628 | * This initialization order is required to support indirect recursion. | ||
629 | * | ||
630 | * <p> The static initializer is defined using a helper field to work around limitations of the code generator. | ||
631 | * | ||
632 | */ | ||
633 | private final static Object STATIC_INITIALIZER = ensureInitialized(); | ||
634 | |||
635 | public static Object ensureInitialized() { | ||
636 | INSTANCE.ensureInitializedInternal(); | ||
637 | return null; | ||
638 | } | ||
639 | } | ||
640 | |||
641 | private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { | ||
642 | private final static StateInRegion.GeneratedPQuery INSTANCE = new GeneratedPQuery(); | ||
643 | |||
644 | private final PParameter parameter_region = new PParameter("region", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Region", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Region")), PParameterDirection.INOUT); | ||
645 | |||
646 | private final PParameter parameter_state = new PParameter("state", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.State", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "State")), PParameterDirection.INOUT); | ||
647 | |||
648 | private final List<PParameter> parameters = Arrays.asList(parameter_region, parameter_state); | ||
649 | |||
650 | private GeneratedPQuery() { | ||
651 | super(PVisibility.PUBLIC); | ||
652 | } | ||
653 | |||
654 | @Override | ||
655 | public String getFullyQualifiedName() { | ||
656 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.StateInRegion"; | ||
657 | } | ||
658 | |||
659 | @Override | ||
660 | public List<String> getParameterNames() { | ||
661 | return Arrays.asList("region","state"); | ||
662 | } | ||
663 | |||
664 | @Override | ||
665 | public List<PParameter> getParameters() { | ||
666 | return parameters; | ||
667 | } | ||
668 | |||
669 | @Override | ||
670 | public Set<PBody> doGetContainedBodies() { | ||
671 | setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); | ||
672 | Set<PBody> bodies = new LinkedHashSet<>(); | ||
673 | { | ||
674 | PBody body = new PBody(this); | ||
675 | PVariable var_region = body.getOrCreateVariableByName("region"); | ||
676 | PVariable var_state = body.getOrCreateVariableByName("state"); | ||
677 | new TypeConstraint(body, Tuples.flatTupleOf(var_region), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Region"))); | ||
678 | new TypeConstraint(body, Tuples.flatTupleOf(var_state), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "State"))); | ||
679 | body.setSymbolicParameters(Arrays.<ExportedParameter>asList( | ||
680 | new ExportedParameter(body, var_region, parameter_region), | ||
681 | new ExportedParameter(body, var_state, parameter_state) | ||
682 | )); | ||
683 | // Region.vertices(region,state) | ||
684 | new TypeConstraint(body, Tuples.flatTupleOf(var_region), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Region"))); | ||
685 | PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); | ||
686 | new TypeConstraint(body, Tuples.flatTupleOf(var_region, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Region", "vertices"))); | ||
687 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); | ||
688 | new Equality(body, var__virtual_0_, var_state); | ||
689 | bodies.add(body); | ||
690 | } | ||
691 | return bodies; | ||
692 | } | ||
693 | } | ||
694 | } | ||
diff --git a/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/SynchHasNoIncoming.java b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/SynchHasNoIncoming.java new file mode 100644 index 00000000..d59ab2d9 --- /dev/null +++ b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/SynchHasNoIncoming.java | |||
@@ -0,0 +1,551 @@ | |||
1 | /** | ||
2 | * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql | ||
3 | */ | ||
4 | package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; | ||
5 | |||
6 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization; | ||
7 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.Transition; | ||
8 | import java.util.Arrays; | ||
9 | import java.util.Collection; | ||
10 | import java.util.LinkedHashSet; | ||
11 | import java.util.List; | ||
12 | import java.util.Objects; | ||
13 | import java.util.Optional; | ||
14 | import java.util.Set; | ||
15 | import java.util.function.Consumer; | ||
16 | import java.util.stream.Collectors; | ||
17 | import java.util.stream.Stream; | ||
18 | import org.apache.log4j.Logger; | ||
19 | import org.eclipse.emf.ecore.EClass; | ||
20 | import org.eclipse.viatra.query.runtime.api.IPatternMatch; | ||
21 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification; | ||
22 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; | ||
23 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; | ||
24 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; | ||
25 | import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; | ||
26 | import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; | ||
27 | import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; | ||
28 | import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; | ||
29 | import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; | ||
30 | import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; | ||
31 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; | ||
32 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; | ||
33 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; | ||
34 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.NegativePatternCall; | ||
35 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; | ||
36 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; | ||
37 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; | ||
38 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; | ||
39 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; | ||
40 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | ||
41 | import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; | ||
42 | |||
43 | /** | ||
44 | * A pattern-specific query specification that can instantiate Matcher in a type-safe way. | ||
45 | * | ||
46 | * <p>Original source: | ||
47 | * <code><pre> | ||
48 | * {@literal @}Constraint(severity="error", message="error", key = {s}) | ||
49 | * pattern synchHasNoIncoming(s : Synchronization) { | ||
50 | * neg find transition(_, _, s); | ||
51 | * } | ||
52 | * </pre></code> | ||
53 | * | ||
54 | * @see Matcher | ||
55 | * @see Match | ||
56 | * | ||
57 | */ | ||
58 | @SuppressWarnings("all") | ||
59 | public final class SynchHasNoIncoming extends BaseGeneratedEMFQuerySpecification<SynchHasNoIncoming.Matcher> { | ||
60 | /** | ||
61 | * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.synchHasNoIncoming pattern, | ||
62 | * to be used in conjunction with {@link Matcher}. | ||
63 | * | ||
64 | * <p>Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. | ||
65 | * Each instance is a (possibly partial) substitution of pattern parameters, | ||
66 | * usable to represent a match of the pattern in the result of a query, | ||
67 | * or to specify the bound (fixed) input parameters when issuing a query. | ||
68 | * | ||
69 | * @see Matcher | ||
70 | * | ||
71 | */ | ||
72 | public static abstract class Match extends BasePatternMatch { | ||
73 | private Synchronization fS; | ||
74 | |||
75 | private static List<String> parameterNames = makeImmutableList("s"); | ||
76 | |||
77 | private Match(final Synchronization pS) { | ||
78 | this.fS = pS; | ||
79 | } | ||
80 | |||
81 | @Override | ||
82 | public Object get(final String parameterName) { | ||
83 | if ("s".equals(parameterName)) return this.fS; | ||
84 | return null; | ||
85 | } | ||
86 | |||
87 | public Synchronization getS() { | ||
88 | return this.fS; | ||
89 | } | ||
90 | |||
91 | @Override | ||
92 | public boolean set(final String parameterName, final Object newValue) { | ||
93 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
94 | if ("s".equals(parameterName) ) { | ||
95 | this.fS = (Synchronization) newValue; | ||
96 | return true; | ||
97 | } | ||
98 | return false; | ||
99 | } | ||
100 | |||
101 | public void setS(final Synchronization pS) { | ||
102 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
103 | this.fS = pS; | ||
104 | } | ||
105 | |||
106 | @Override | ||
107 | public String patternName() { | ||
108 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.synchHasNoIncoming"; | ||
109 | } | ||
110 | |||
111 | @Override | ||
112 | public List<String> parameterNames() { | ||
113 | return SynchHasNoIncoming.Match.parameterNames; | ||
114 | } | ||
115 | |||
116 | @Override | ||
117 | public Object[] toArray() { | ||
118 | return new Object[]{fS}; | ||
119 | } | ||
120 | |||
121 | @Override | ||
122 | public SynchHasNoIncoming.Match toImmutable() { | ||
123 | return isMutable() ? newMatch(fS) : this; | ||
124 | } | ||
125 | |||
126 | @Override | ||
127 | public String prettyPrint() { | ||
128 | StringBuilder result = new StringBuilder(); | ||
129 | result.append("\"s\"=" + prettyPrintValue(fS)); | ||
130 | return result.toString(); | ||
131 | } | ||
132 | |||
133 | @Override | ||
134 | public int hashCode() { | ||
135 | return Objects.hash(fS); | ||
136 | } | ||
137 | |||
138 | @Override | ||
139 | public boolean equals(final Object obj) { | ||
140 | if (this == obj) | ||
141 | return true; | ||
142 | if (obj == null) { | ||
143 | return false; | ||
144 | } | ||
145 | if ((obj instanceof SynchHasNoIncoming.Match)) { | ||
146 | SynchHasNoIncoming.Match other = (SynchHasNoIncoming.Match) obj; | ||
147 | return Objects.equals(fS, other.fS); | ||
148 | } else { | ||
149 | // this should be infrequent | ||
150 | if (!(obj instanceof IPatternMatch)) { | ||
151 | return false; | ||
152 | } | ||
153 | IPatternMatch otherSig = (IPatternMatch) obj; | ||
154 | return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); | ||
155 | } | ||
156 | } | ||
157 | |||
158 | @Override | ||
159 | public SynchHasNoIncoming specification() { | ||
160 | return SynchHasNoIncoming.instance(); | ||
161 | } | ||
162 | |||
163 | /** | ||
164 | * Returns an empty, mutable match. | ||
165 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
166 | * | ||
167 | * @return the empty match. | ||
168 | * | ||
169 | */ | ||
170 | public static SynchHasNoIncoming.Match newEmptyMatch() { | ||
171 | return new Mutable(null); | ||
172 | } | ||
173 | |||
174 | /** | ||
175 | * Returns a mutable (partial) match. | ||
176 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
177 | * | ||
178 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
179 | * @return the new, mutable (partial) match object. | ||
180 | * | ||
181 | */ | ||
182 | public static SynchHasNoIncoming.Match newMutableMatch(final Synchronization pS) { | ||
183 | return new Mutable(pS); | ||
184 | } | ||
185 | |||
186 | /** | ||
187 | * Returns a new (partial) match. | ||
188 | * This can be used e.g. to call the matcher with a partial match. | ||
189 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
190 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
191 | * @return the (partial) match object. | ||
192 | * | ||
193 | */ | ||
194 | public static SynchHasNoIncoming.Match newMatch(final Synchronization pS) { | ||
195 | return new Immutable(pS); | ||
196 | } | ||
197 | |||
198 | private static final class Mutable extends SynchHasNoIncoming.Match { | ||
199 | Mutable(final Synchronization pS) { | ||
200 | super(pS); | ||
201 | } | ||
202 | |||
203 | @Override | ||
204 | public boolean isMutable() { | ||
205 | return true; | ||
206 | } | ||
207 | } | ||
208 | |||
209 | private static final class Immutable extends SynchHasNoIncoming.Match { | ||
210 | Immutable(final Synchronization pS) { | ||
211 | super(pS); | ||
212 | } | ||
213 | |||
214 | @Override | ||
215 | public boolean isMutable() { | ||
216 | return false; | ||
217 | } | ||
218 | } | ||
219 | } | ||
220 | |||
221 | /** | ||
222 | * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.synchHasNoIncoming pattern, | ||
223 | * providing pattern-specific query methods. | ||
224 | * | ||
225 | * <p>Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, | ||
226 | * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. | ||
227 | * | ||
228 | * <p>Matches of the pattern will be represented as {@link Match}. | ||
229 | * | ||
230 | * <p>Original source: | ||
231 | * <code><pre> | ||
232 | * {@literal @}Constraint(severity="error", message="error", key = {s}) | ||
233 | * pattern synchHasNoIncoming(s : Synchronization) { | ||
234 | * neg find transition(_, _, s); | ||
235 | * } | ||
236 | * </pre></code> | ||
237 | * | ||
238 | * @see Match | ||
239 | * @see SynchHasNoIncoming | ||
240 | * | ||
241 | */ | ||
242 | public static class Matcher extends BaseMatcher<SynchHasNoIncoming.Match> { | ||
243 | /** | ||
244 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
245 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
246 | * | ||
247 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
248 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
249 | * | ||
250 | */ | ||
251 | public static SynchHasNoIncoming.Matcher on(final ViatraQueryEngine engine) { | ||
252 | // check if matcher already exists | ||
253 | Matcher matcher = engine.getExistingMatcher(querySpecification()); | ||
254 | if (matcher == null) { | ||
255 | matcher = (Matcher)engine.getMatcher(querySpecification()); | ||
256 | } | ||
257 | return matcher; | ||
258 | } | ||
259 | |||
260 | /** | ||
261 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
262 | * @return an initialized matcher | ||
263 | * @noreference This method is for internal matcher initialization by the framework, do not call it manually. | ||
264 | * | ||
265 | */ | ||
266 | public static SynchHasNoIncoming.Matcher create() { | ||
267 | return new Matcher(); | ||
268 | } | ||
269 | |||
270 | private final static int POSITION_S = 0; | ||
271 | |||
272 | private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(SynchHasNoIncoming.Matcher.class); | ||
273 | |||
274 | /** | ||
275 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
276 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
277 | * | ||
278 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
279 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
280 | * | ||
281 | */ | ||
282 | private Matcher() { | ||
283 | super(querySpecification()); | ||
284 | } | ||
285 | |||
286 | /** | ||
287 | * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. | ||
288 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
289 | * @return matches represented as a Match object. | ||
290 | * | ||
291 | */ | ||
292 | public Collection<SynchHasNoIncoming.Match> getAllMatches(final Synchronization pS) { | ||
293 | return rawStreamAllMatches(new Object[]{pS}).collect(Collectors.toSet()); | ||
294 | } | ||
295 | |||
296 | /** | ||
297 | * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. | ||
298 | * </p> | ||
299 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
300 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
301 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
302 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
303 | * @return a stream of matches represented as a Match object. | ||
304 | * | ||
305 | */ | ||
306 | public Stream<SynchHasNoIncoming.Match> streamAllMatches(final Synchronization pS) { | ||
307 | return rawStreamAllMatches(new Object[]{pS}); | ||
308 | } | ||
309 | |||
310 | /** | ||
311 | * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
312 | * Neither determinism nor randomness of selection is guaranteed. | ||
313 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
314 | * @return a match represented as a Match object, or null if no match is found. | ||
315 | * | ||
316 | */ | ||
317 | public Optional<SynchHasNoIncoming.Match> getOneArbitraryMatch(final Synchronization pS) { | ||
318 | return rawGetOneArbitraryMatch(new Object[]{pS}); | ||
319 | } | ||
320 | |||
321 | /** | ||
322 | * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, | ||
323 | * under any possible substitution of the unspecified parameters (if any). | ||
324 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
325 | * @return true if the input is a valid (partial) match of the pattern. | ||
326 | * | ||
327 | */ | ||
328 | public boolean hasMatch(final Synchronization pS) { | ||
329 | return rawHasMatch(new Object[]{pS}); | ||
330 | } | ||
331 | |||
332 | /** | ||
333 | * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. | ||
334 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
335 | * @return the number of pattern matches found. | ||
336 | * | ||
337 | */ | ||
338 | public int countMatches(final Synchronization pS) { | ||
339 | return rawCountMatches(new Object[]{pS}); | ||
340 | } | ||
341 | |||
342 | /** | ||
343 | * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
344 | * Neither determinism nor randomness of selection is guaranteed. | ||
345 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
346 | * @param processor the action that will process the selected match. | ||
347 | * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked | ||
348 | * | ||
349 | */ | ||
350 | public boolean forOneArbitraryMatch(final Synchronization pS, final Consumer<? super SynchHasNoIncoming.Match> processor) { | ||
351 | return rawForOneArbitraryMatch(new Object[]{pS}, processor); | ||
352 | } | ||
353 | |||
354 | /** | ||
355 | * Returns a new (partial) match. | ||
356 | * This can be used e.g. to call the matcher with a partial match. | ||
357 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
358 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
359 | * @return the (partial) match object. | ||
360 | * | ||
361 | */ | ||
362 | public SynchHasNoIncoming.Match newMatch(final Synchronization pS) { | ||
363 | return SynchHasNoIncoming.Match.newMatch(pS); | ||
364 | } | ||
365 | |||
366 | /** | ||
367 | * Retrieve the set of values that occur in matches for s. | ||
368 | * @return the Set of all values or empty set if there are no matches | ||
369 | * | ||
370 | */ | ||
371 | protected Stream<Synchronization> rawStreamAllValuesOfs(final Object[] parameters) { | ||
372 | return rawStreamAllValues(POSITION_S, parameters).map(Synchronization.class::cast); | ||
373 | } | ||
374 | |||
375 | /** | ||
376 | * Retrieve the set of values that occur in matches for s. | ||
377 | * @return the Set of all values or empty set if there are no matches | ||
378 | * | ||
379 | */ | ||
380 | public Set<Synchronization> getAllValuesOfs() { | ||
381 | return rawStreamAllValuesOfs(emptyArray()).collect(Collectors.toSet()); | ||
382 | } | ||
383 | |||
384 | /** | ||
385 | * Retrieve the set of values that occur in matches for s. | ||
386 | * @return the Set of all values or empty set if there are no matches | ||
387 | * | ||
388 | */ | ||
389 | public Stream<Synchronization> streamAllValuesOfs() { | ||
390 | return rawStreamAllValuesOfs(emptyArray()); | ||
391 | } | ||
392 | |||
393 | @Override | ||
394 | protected SynchHasNoIncoming.Match tupleToMatch(final Tuple t) { | ||
395 | try { | ||
396 | return SynchHasNoIncoming.Match.newMatch((Synchronization) t.get(POSITION_S)); | ||
397 | } catch(ClassCastException e) { | ||
398 | LOGGER.error("Element(s) in tuple not properly typed!",e); | ||
399 | return null; | ||
400 | } | ||
401 | } | ||
402 | |||
403 | @Override | ||
404 | protected SynchHasNoIncoming.Match arrayToMatch(final Object[] match) { | ||
405 | try { | ||
406 | return SynchHasNoIncoming.Match.newMatch((Synchronization) match[POSITION_S]); | ||
407 | } catch(ClassCastException e) { | ||
408 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
409 | return null; | ||
410 | } | ||
411 | } | ||
412 | |||
413 | @Override | ||
414 | protected SynchHasNoIncoming.Match arrayToMatchMutable(final Object[] match) { | ||
415 | try { | ||
416 | return SynchHasNoIncoming.Match.newMutableMatch((Synchronization) match[POSITION_S]); | ||
417 | } catch(ClassCastException e) { | ||
418 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
419 | return null; | ||
420 | } | ||
421 | } | ||
422 | |||
423 | /** | ||
424 | * @return the singleton instance of the query specification of this pattern | ||
425 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
426 | * | ||
427 | */ | ||
428 | public static IQuerySpecification<SynchHasNoIncoming.Matcher> querySpecification() { | ||
429 | return SynchHasNoIncoming.instance(); | ||
430 | } | ||
431 | } | ||
432 | |||
433 | private SynchHasNoIncoming() { | ||
434 | super(GeneratedPQuery.INSTANCE); | ||
435 | } | ||
436 | |||
437 | /** | ||
438 | * @return the singleton instance of the query specification | ||
439 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
440 | * | ||
441 | */ | ||
442 | public static SynchHasNoIncoming instance() { | ||
443 | try{ | ||
444 | return LazyHolder.INSTANCE; | ||
445 | } catch (ExceptionInInitializerError err) { | ||
446 | throw processInitializerError(err); | ||
447 | } | ||
448 | } | ||
449 | |||
450 | @Override | ||
451 | protected SynchHasNoIncoming.Matcher instantiate(final ViatraQueryEngine engine) { | ||
452 | return SynchHasNoIncoming.Matcher.on(engine); | ||
453 | } | ||
454 | |||
455 | @Override | ||
456 | public SynchHasNoIncoming.Matcher instantiate() { | ||
457 | return SynchHasNoIncoming.Matcher.create(); | ||
458 | } | ||
459 | |||
460 | @Override | ||
461 | public SynchHasNoIncoming.Match newEmptyMatch() { | ||
462 | return SynchHasNoIncoming.Match.newEmptyMatch(); | ||
463 | } | ||
464 | |||
465 | @Override | ||
466 | public SynchHasNoIncoming.Match newMatch(final Object... parameters) { | ||
467 | return SynchHasNoIncoming.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization) parameters[0]); | ||
468 | } | ||
469 | |||
470 | /** | ||
471 | * Inner class allowing the singleton instance of {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchHasNoIncoming (visibility: PUBLIC, simpleName: SynchHasNoIncoming, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchHasNoIncoming, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created | ||
472 | * <b>not</b> at the class load time of the outer class, | ||
473 | * but rather at the first call to {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchHasNoIncoming (visibility: PUBLIC, simpleName: SynchHasNoIncoming, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchHasNoIncoming, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. | ||
474 | * | ||
475 | * <p> This workaround is required e.g. to support recursion. | ||
476 | * | ||
477 | */ | ||
478 | private static class LazyHolder { | ||
479 | private final static SynchHasNoIncoming INSTANCE = new SynchHasNoIncoming(); | ||
480 | |||
481 | /** | ||
482 | * Statically initializes the query specification <b>after</b> the field {@link #INSTANCE} is assigned. | ||
483 | * This initialization order is required to support indirect recursion. | ||
484 | * | ||
485 | * <p> The static initializer is defined using a helper field to work around limitations of the code generator. | ||
486 | * | ||
487 | */ | ||
488 | private final static Object STATIC_INITIALIZER = ensureInitialized(); | ||
489 | |||
490 | public static Object ensureInitialized() { | ||
491 | INSTANCE.ensureInitializedInternal(); | ||
492 | return null; | ||
493 | } | ||
494 | } | ||
495 | |||
496 | private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { | ||
497 | private final static SynchHasNoIncoming.GeneratedPQuery INSTANCE = new GeneratedPQuery(); | ||
498 | |||
499 | private final PParameter parameter_s = new PParameter("s", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Synchronization")), PParameterDirection.INOUT); | ||
500 | |||
501 | private final List<PParameter> parameters = Arrays.asList(parameter_s); | ||
502 | |||
503 | private GeneratedPQuery() { | ||
504 | super(PVisibility.PUBLIC); | ||
505 | } | ||
506 | |||
507 | @Override | ||
508 | public String getFullyQualifiedName() { | ||
509 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.synchHasNoIncoming"; | ||
510 | } | ||
511 | |||
512 | @Override | ||
513 | public List<String> getParameterNames() { | ||
514 | return Arrays.asList("s"); | ||
515 | } | ||
516 | |||
517 | @Override | ||
518 | public List<PParameter> getParameters() { | ||
519 | return parameters; | ||
520 | } | ||
521 | |||
522 | @Override | ||
523 | public Set<PBody> doGetContainedBodies() { | ||
524 | setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); | ||
525 | Set<PBody> bodies = new LinkedHashSet<>(); | ||
526 | { | ||
527 | PBody body = new PBody(this); | ||
528 | PVariable var_s = body.getOrCreateVariableByName("s"); | ||
529 | PVariable var___0_ = body.getOrCreateVariableByName("_<0>"); | ||
530 | PVariable var___1_ = body.getOrCreateVariableByName("_<1>"); | ||
531 | new TypeConstraint(body, Tuples.flatTupleOf(var_s), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Synchronization"))); | ||
532 | body.setSymbolicParameters(Arrays.<ExportedParameter>asList( | ||
533 | new ExportedParameter(body, var_s, parameter_s) | ||
534 | )); | ||
535 | // neg find transition(_, _, s) | ||
536 | new NegativePatternCall(body, Tuples.flatTupleOf(var___0_, var___1_, var_s), Transition.instance().getInternalQueryRepresentation()); | ||
537 | bodies.add(body); | ||
538 | } | ||
539 | { | ||
540 | PAnnotation annotation = new PAnnotation("Constraint"); | ||
541 | annotation.addAttribute("severity", "error"); | ||
542 | annotation.addAttribute("message", "error"); | ||
543 | annotation.addAttribute("key", Arrays.asList(new Object[] { | ||
544 | new ParameterReference("s") | ||
545 | })); | ||
546 | addAnnotation(annotation); | ||
547 | } | ||
548 | return bodies; | ||
549 | } | ||
550 | } | ||
551 | } | ||
diff --git a/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/SynchHasNoOutgoing.java b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/SynchHasNoOutgoing.java new file mode 100644 index 00000000..e3ff69bd --- /dev/null +++ b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/SynchHasNoOutgoing.java | |||
@@ -0,0 +1,559 @@ | |||
1 | /** | ||
2 | * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql | ||
3 | */ | ||
4 | package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; | ||
5 | |||
6 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization; | ||
7 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.Transition; | ||
8 | import java.util.Arrays; | ||
9 | import java.util.Collection; | ||
10 | import java.util.LinkedHashSet; | ||
11 | import java.util.List; | ||
12 | import java.util.Objects; | ||
13 | import java.util.Optional; | ||
14 | import java.util.Set; | ||
15 | import java.util.function.Consumer; | ||
16 | import java.util.stream.Collectors; | ||
17 | import java.util.stream.Stream; | ||
18 | import org.apache.log4j.Logger; | ||
19 | import org.eclipse.emf.ecore.EClass; | ||
20 | import org.eclipse.viatra.query.runtime.api.IPatternMatch; | ||
21 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification; | ||
22 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; | ||
23 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; | ||
24 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; | ||
25 | import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; | ||
26 | import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; | ||
27 | import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; | ||
28 | import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; | ||
29 | import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; | ||
30 | import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; | ||
31 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; | ||
32 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; | ||
33 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; | ||
34 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.NegativePatternCall; | ||
35 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; | ||
36 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; | ||
37 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; | ||
38 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; | ||
39 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; | ||
40 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | ||
41 | import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; | ||
42 | |||
43 | /** | ||
44 | * A pattern-specific query specification that can instantiate Matcher in a type-safe way. | ||
45 | * | ||
46 | * <p>Original source: | ||
47 | * <code><pre> | ||
48 | * ///////// | ||
49 | * // Synchronization | ||
50 | * ///////// | ||
51 | * | ||
52 | * {@literal @}Constraint(severity="error", message="error", key = {s}) | ||
53 | * pattern synchHasNoOutgoing(s : Synchronization) { | ||
54 | * neg find transition(_, s, _); | ||
55 | * } | ||
56 | * </pre></code> | ||
57 | * | ||
58 | * @see Matcher | ||
59 | * @see Match | ||
60 | * | ||
61 | */ | ||
62 | @SuppressWarnings("all") | ||
63 | public final class SynchHasNoOutgoing extends BaseGeneratedEMFQuerySpecification<SynchHasNoOutgoing.Matcher> { | ||
64 | /** | ||
65 | * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.synchHasNoOutgoing pattern, | ||
66 | * to be used in conjunction with {@link Matcher}. | ||
67 | * | ||
68 | * <p>Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. | ||
69 | * Each instance is a (possibly partial) substitution of pattern parameters, | ||
70 | * usable to represent a match of the pattern in the result of a query, | ||
71 | * or to specify the bound (fixed) input parameters when issuing a query. | ||
72 | * | ||
73 | * @see Matcher | ||
74 | * | ||
75 | */ | ||
76 | public static abstract class Match extends BasePatternMatch { | ||
77 | private Synchronization fS; | ||
78 | |||
79 | private static List<String> parameterNames = makeImmutableList("s"); | ||
80 | |||
81 | private Match(final Synchronization pS) { | ||
82 | this.fS = pS; | ||
83 | } | ||
84 | |||
85 | @Override | ||
86 | public Object get(final String parameterName) { | ||
87 | if ("s".equals(parameterName)) return this.fS; | ||
88 | return null; | ||
89 | } | ||
90 | |||
91 | public Synchronization getS() { | ||
92 | return this.fS; | ||
93 | } | ||
94 | |||
95 | @Override | ||
96 | public boolean set(final String parameterName, final Object newValue) { | ||
97 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
98 | if ("s".equals(parameterName) ) { | ||
99 | this.fS = (Synchronization) newValue; | ||
100 | return true; | ||
101 | } | ||
102 | return false; | ||
103 | } | ||
104 | |||
105 | public void setS(final Synchronization pS) { | ||
106 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
107 | this.fS = pS; | ||
108 | } | ||
109 | |||
110 | @Override | ||
111 | public String patternName() { | ||
112 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.synchHasNoOutgoing"; | ||
113 | } | ||
114 | |||
115 | @Override | ||
116 | public List<String> parameterNames() { | ||
117 | return SynchHasNoOutgoing.Match.parameterNames; | ||
118 | } | ||
119 | |||
120 | @Override | ||
121 | public Object[] toArray() { | ||
122 | return new Object[]{fS}; | ||
123 | } | ||
124 | |||
125 | @Override | ||
126 | public SynchHasNoOutgoing.Match toImmutable() { | ||
127 | return isMutable() ? newMatch(fS) : this; | ||
128 | } | ||
129 | |||
130 | @Override | ||
131 | public String prettyPrint() { | ||
132 | StringBuilder result = new StringBuilder(); | ||
133 | result.append("\"s\"=" + prettyPrintValue(fS)); | ||
134 | return result.toString(); | ||
135 | } | ||
136 | |||
137 | @Override | ||
138 | public int hashCode() { | ||
139 | return Objects.hash(fS); | ||
140 | } | ||
141 | |||
142 | @Override | ||
143 | public boolean equals(final Object obj) { | ||
144 | if (this == obj) | ||
145 | return true; | ||
146 | if (obj == null) { | ||
147 | return false; | ||
148 | } | ||
149 | if ((obj instanceof SynchHasNoOutgoing.Match)) { | ||
150 | SynchHasNoOutgoing.Match other = (SynchHasNoOutgoing.Match) obj; | ||
151 | return Objects.equals(fS, other.fS); | ||
152 | } else { | ||
153 | // this should be infrequent | ||
154 | if (!(obj instanceof IPatternMatch)) { | ||
155 | return false; | ||
156 | } | ||
157 | IPatternMatch otherSig = (IPatternMatch) obj; | ||
158 | return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); | ||
159 | } | ||
160 | } | ||
161 | |||
162 | @Override | ||
163 | public SynchHasNoOutgoing specification() { | ||
164 | return SynchHasNoOutgoing.instance(); | ||
165 | } | ||
166 | |||
167 | /** | ||
168 | * Returns an empty, mutable match. | ||
169 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
170 | * | ||
171 | * @return the empty match. | ||
172 | * | ||
173 | */ | ||
174 | public static SynchHasNoOutgoing.Match newEmptyMatch() { | ||
175 | return new Mutable(null); | ||
176 | } | ||
177 | |||
178 | /** | ||
179 | * Returns a mutable (partial) match. | ||
180 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
181 | * | ||
182 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
183 | * @return the new, mutable (partial) match object. | ||
184 | * | ||
185 | */ | ||
186 | public static SynchHasNoOutgoing.Match newMutableMatch(final Synchronization pS) { | ||
187 | return new Mutable(pS); | ||
188 | } | ||
189 | |||
190 | /** | ||
191 | * Returns a new (partial) match. | ||
192 | * This can be used e.g. to call the matcher with a partial match. | ||
193 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
194 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
195 | * @return the (partial) match object. | ||
196 | * | ||
197 | */ | ||
198 | public static SynchHasNoOutgoing.Match newMatch(final Synchronization pS) { | ||
199 | return new Immutable(pS); | ||
200 | } | ||
201 | |||
202 | private static final class Mutable extends SynchHasNoOutgoing.Match { | ||
203 | Mutable(final Synchronization pS) { | ||
204 | super(pS); | ||
205 | } | ||
206 | |||
207 | @Override | ||
208 | public boolean isMutable() { | ||
209 | return true; | ||
210 | } | ||
211 | } | ||
212 | |||
213 | private static final class Immutable extends SynchHasNoOutgoing.Match { | ||
214 | Immutable(final Synchronization pS) { | ||
215 | super(pS); | ||
216 | } | ||
217 | |||
218 | @Override | ||
219 | public boolean isMutable() { | ||
220 | return false; | ||
221 | } | ||
222 | } | ||
223 | } | ||
224 | |||
225 | /** | ||
226 | * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.synchHasNoOutgoing pattern, | ||
227 | * providing pattern-specific query methods. | ||
228 | * | ||
229 | * <p>Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, | ||
230 | * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. | ||
231 | * | ||
232 | * <p>Matches of the pattern will be represented as {@link Match}. | ||
233 | * | ||
234 | * <p>Original source: | ||
235 | * <code><pre> | ||
236 | * ///////// | ||
237 | * // Synchronization | ||
238 | * ///////// | ||
239 | * | ||
240 | * {@literal @}Constraint(severity="error", message="error", key = {s}) | ||
241 | * pattern synchHasNoOutgoing(s : Synchronization) { | ||
242 | * neg find transition(_, s, _); | ||
243 | * } | ||
244 | * </pre></code> | ||
245 | * | ||
246 | * @see Match | ||
247 | * @see SynchHasNoOutgoing | ||
248 | * | ||
249 | */ | ||
250 | public static class Matcher extends BaseMatcher<SynchHasNoOutgoing.Match> { | ||
251 | /** | ||
252 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
253 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
254 | * | ||
255 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
256 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
257 | * | ||
258 | */ | ||
259 | public static SynchHasNoOutgoing.Matcher on(final ViatraQueryEngine engine) { | ||
260 | // check if matcher already exists | ||
261 | Matcher matcher = engine.getExistingMatcher(querySpecification()); | ||
262 | if (matcher == null) { | ||
263 | matcher = (Matcher)engine.getMatcher(querySpecification()); | ||
264 | } | ||
265 | return matcher; | ||
266 | } | ||
267 | |||
268 | /** | ||
269 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
270 | * @return an initialized matcher | ||
271 | * @noreference This method is for internal matcher initialization by the framework, do not call it manually. | ||
272 | * | ||
273 | */ | ||
274 | public static SynchHasNoOutgoing.Matcher create() { | ||
275 | return new Matcher(); | ||
276 | } | ||
277 | |||
278 | private final static int POSITION_S = 0; | ||
279 | |||
280 | private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(SynchHasNoOutgoing.Matcher.class); | ||
281 | |||
282 | /** | ||
283 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
284 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
285 | * | ||
286 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
287 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
288 | * | ||
289 | */ | ||
290 | private Matcher() { | ||
291 | super(querySpecification()); | ||
292 | } | ||
293 | |||
294 | /** | ||
295 | * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. | ||
296 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
297 | * @return matches represented as a Match object. | ||
298 | * | ||
299 | */ | ||
300 | public Collection<SynchHasNoOutgoing.Match> getAllMatches(final Synchronization pS) { | ||
301 | return rawStreamAllMatches(new Object[]{pS}).collect(Collectors.toSet()); | ||
302 | } | ||
303 | |||
304 | /** | ||
305 | * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. | ||
306 | * </p> | ||
307 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
308 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
309 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
310 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
311 | * @return a stream of matches represented as a Match object. | ||
312 | * | ||
313 | */ | ||
314 | public Stream<SynchHasNoOutgoing.Match> streamAllMatches(final Synchronization pS) { | ||
315 | return rawStreamAllMatches(new Object[]{pS}); | ||
316 | } | ||
317 | |||
318 | /** | ||
319 | * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
320 | * Neither determinism nor randomness of selection is guaranteed. | ||
321 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
322 | * @return a match represented as a Match object, or null if no match is found. | ||
323 | * | ||
324 | */ | ||
325 | public Optional<SynchHasNoOutgoing.Match> getOneArbitraryMatch(final Synchronization pS) { | ||
326 | return rawGetOneArbitraryMatch(new Object[]{pS}); | ||
327 | } | ||
328 | |||
329 | /** | ||
330 | * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, | ||
331 | * under any possible substitution of the unspecified parameters (if any). | ||
332 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
333 | * @return true if the input is a valid (partial) match of the pattern. | ||
334 | * | ||
335 | */ | ||
336 | public boolean hasMatch(final Synchronization pS) { | ||
337 | return rawHasMatch(new Object[]{pS}); | ||
338 | } | ||
339 | |||
340 | /** | ||
341 | * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. | ||
342 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
343 | * @return the number of pattern matches found. | ||
344 | * | ||
345 | */ | ||
346 | public int countMatches(final Synchronization pS) { | ||
347 | return rawCountMatches(new Object[]{pS}); | ||
348 | } | ||
349 | |||
350 | /** | ||
351 | * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
352 | * Neither determinism nor randomness of selection is guaranteed. | ||
353 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
354 | * @param processor the action that will process the selected match. | ||
355 | * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked | ||
356 | * | ||
357 | */ | ||
358 | public boolean forOneArbitraryMatch(final Synchronization pS, final Consumer<? super SynchHasNoOutgoing.Match> processor) { | ||
359 | return rawForOneArbitraryMatch(new Object[]{pS}, processor); | ||
360 | } | ||
361 | |||
362 | /** | ||
363 | * Returns a new (partial) match. | ||
364 | * This can be used e.g. to call the matcher with a partial match. | ||
365 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
366 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
367 | * @return the (partial) match object. | ||
368 | * | ||
369 | */ | ||
370 | public SynchHasNoOutgoing.Match newMatch(final Synchronization pS) { | ||
371 | return SynchHasNoOutgoing.Match.newMatch(pS); | ||
372 | } | ||
373 | |||
374 | /** | ||
375 | * Retrieve the set of values that occur in matches for s. | ||
376 | * @return the Set of all values or empty set if there are no matches | ||
377 | * | ||
378 | */ | ||
379 | protected Stream<Synchronization> rawStreamAllValuesOfs(final Object[] parameters) { | ||
380 | return rawStreamAllValues(POSITION_S, parameters).map(Synchronization.class::cast); | ||
381 | } | ||
382 | |||
383 | /** | ||
384 | * Retrieve the set of values that occur in matches for s. | ||
385 | * @return the Set of all values or empty set if there are no matches | ||
386 | * | ||
387 | */ | ||
388 | public Set<Synchronization> getAllValuesOfs() { | ||
389 | return rawStreamAllValuesOfs(emptyArray()).collect(Collectors.toSet()); | ||
390 | } | ||
391 | |||
392 | /** | ||
393 | * Retrieve the set of values that occur in matches for s. | ||
394 | * @return the Set of all values or empty set if there are no matches | ||
395 | * | ||
396 | */ | ||
397 | public Stream<Synchronization> streamAllValuesOfs() { | ||
398 | return rawStreamAllValuesOfs(emptyArray()); | ||
399 | } | ||
400 | |||
401 | @Override | ||
402 | protected SynchHasNoOutgoing.Match tupleToMatch(final Tuple t) { | ||
403 | try { | ||
404 | return SynchHasNoOutgoing.Match.newMatch((Synchronization) t.get(POSITION_S)); | ||
405 | } catch(ClassCastException e) { | ||
406 | LOGGER.error("Element(s) in tuple not properly typed!",e); | ||
407 | return null; | ||
408 | } | ||
409 | } | ||
410 | |||
411 | @Override | ||
412 | protected SynchHasNoOutgoing.Match arrayToMatch(final Object[] match) { | ||
413 | try { | ||
414 | return SynchHasNoOutgoing.Match.newMatch((Synchronization) match[POSITION_S]); | ||
415 | } catch(ClassCastException e) { | ||
416 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
417 | return null; | ||
418 | } | ||
419 | } | ||
420 | |||
421 | @Override | ||
422 | protected SynchHasNoOutgoing.Match arrayToMatchMutable(final Object[] match) { | ||
423 | try { | ||
424 | return SynchHasNoOutgoing.Match.newMutableMatch((Synchronization) match[POSITION_S]); | ||
425 | } catch(ClassCastException e) { | ||
426 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
427 | return null; | ||
428 | } | ||
429 | } | ||
430 | |||
431 | /** | ||
432 | * @return the singleton instance of the query specification of this pattern | ||
433 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
434 | * | ||
435 | */ | ||
436 | public static IQuerySpecification<SynchHasNoOutgoing.Matcher> querySpecification() { | ||
437 | return SynchHasNoOutgoing.instance(); | ||
438 | } | ||
439 | } | ||
440 | |||
441 | private SynchHasNoOutgoing() { | ||
442 | super(GeneratedPQuery.INSTANCE); | ||
443 | } | ||
444 | |||
445 | /** | ||
446 | * @return the singleton instance of the query specification | ||
447 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
448 | * | ||
449 | */ | ||
450 | public static SynchHasNoOutgoing instance() { | ||
451 | try{ | ||
452 | return LazyHolder.INSTANCE; | ||
453 | } catch (ExceptionInInitializerError err) { | ||
454 | throw processInitializerError(err); | ||
455 | } | ||
456 | } | ||
457 | |||
458 | @Override | ||
459 | protected SynchHasNoOutgoing.Matcher instantiate(final ViatraQueryEngine engine) { | ||
460 | return SynchHasNoOutgoing.Matcher.on(engine); | ||
461 | } | ||
462 | |||
463 | @Override | ||
464 | public SynchHasNoOutgoing.Matcher instantiate() { | ||
465 | return SynchHasNoOutgoing.Matcher.create(); | ||
466 | } | ||
467 | |||
468 | @Override | ||
469 | public SynchHasNoOutgoing.Match newEmptyMatch() { | ||
470 | return SynchHasNoOutgoing.Match.newEmptyMatch(); | ||
471 | } | ||
472 | |||
473 | @Override | ||
474 | public SynchHasNoOutgoing.Match newMatch(final Object... parameters) { | ||
475 | return SynchHasNoOutgoing.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization) parameters[0]); | ||
476 | } | ||
477 | |||
478 | /** | ||
479 | * Inner class allowing the singleton instance of {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchHasNoOutgoing (visibility: PUBLIC, simpleName: SynchHasNoOutgoing, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchHasNoOutgoing, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created | ||
480 | * <b>not</b> at the class load time of the outer class, | ||
481 | * but rather at the first call to {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchHasNoOutgoing (visibility: PUBLIC, simpleName: SynchHasNoOutgoing, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchHasNoOutgoing, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. | ||
482 | * | ||
483 | * <p> This workaround is required e.g. to support recursion. | ||
484 | * | ||
485 | */ | ||
486 | private static class LazyHolder { | ||
487 | private final static SynchHasNoOutgoing INSTANCE = new SynchHasNoOutgoing(); | ||
488 | |||
489 | /** | ||
490 | * Statically initializes the query specification <b>after</b> the field {@link #INSTANCE} is assigned. | ||
491 | * This initialization order is required to support indirect recursion. | ||
492 | * | ||
493 | * <p> The static initializer is defined using a helper field to work around limitations of the code generator. | ||
494 | * | ||
495 | */ | ||
496 | private final static Object STATIC_INITIALIZER = ensureInitialized(); | ||
497 | |||
498 | public static Object ensureInitialized() { | ||
499 | INSTANCE.ensureInitializedInternal(); | ||
500 | return null; | ||
501 | } | ||
502 | } | ||
503 | |||
504 | private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { | ||
505 | private final static SynchHasNoOutgoing.GeneratedPQuery INSTANCE = new GeneratedPQuery(); | ||
506 | |||
507 | private final PParameter parameter_s = new PParameter("s", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Synchronization")), PParameterDirection.INOUT); | ||
508 | |||
509 | private final List<PParameter> parameters = Arrays.asList(parameter_s); | ||
510 | |||
511 | private GeneratedPQuery() { | ||
512 | super(PVisibility.PUBLIC); | ||
513 | } | ||
514 | |||
515 | @Override | ||
516 | public String getFullyQualifiedName() { | ||
517 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.synchHasNoOutgoing"; | ||
518 | } | ||
519 | |||
520 | @Override | ||
521 | public List<String> getParameterNames() { | ||
522 | return Arrays.asList("s"); | ||
523 | } | ||
524 | |||
525 | @Override | ||
526 | public List<PParameter> getParameters() { | ||
527 | return parameters; | ||
528 | } | ||
529 | |||
530 | @Override | ||
531 | public Set<PBody> doGetContainedBodies() { | ||
532 | setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); | ||
533 | Set<PBody> bodies = new LinkedHashSet<>(); | ||
534 | { | ||
535 | PBody body = new PBody(this); | ||
536 | PVariable var_s = body.getOrCreateVariableByName("s"); | ||
537 | PVariable var___0_ = body.getOrCreateVariableByName("_<0>"); | ||
538 | PVariable var___1_ = body.getOrCreateVariableByName("_<1>"); | ||
539 | new TypeConstraint(body, Tuples.flatTupleOf(var_s), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Synchronization"))); | ||
540 | body.setSymbolicParameters(Arrays.<ExportedParameter>asList( | ||
541 | new ExportedParameter(body, var_s, parameter_s) | ||
542 | )); | ||
543 | // neg find transition(_, s, _) | ||
544 | new NegativePatternCall(body, Tuples.flatTupleOf(var___0_, var_s, var___1_), Transition.instance().getInternalQueryRepresentation()); | ||
545 | bodies.add(body); | ||
546 | } | ||
547 | { | ||
548 | PAnnotation annotation = new PAnnotation("Constraint"); | ||
549 | annotation.addAttribute("severity", "error"); | ||
550 | annotation.addAttribute("message", "error"); | ||
551 | annotation.addAttribute("key", Arrays.asList(new Object[] { | ||
552 | new ParameterReference("s") | ||
553 | })); | ||
554 | addAnnotation(annotation); | ||
555 | } | ||
556 | return bodies; | ||
557 | } | ||
558 | } | ||
559 | } | ||
diff --git a/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/SynchThree.java b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/SynchThree.java new file mode 100644 index 00000000..228db3a0 --- /dev/null +++ b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/SynchThree.java | |||
@@ -0,0 +1,639 @@ | |||
1 | /** | ||
2 | * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql | ||
3 | */ | ||
4 | package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; | ||
5 | |||
6 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization; | ||
7 | import java.util.Arrays; | ||
8 | import java.util.Collection; | ||
9 | import java.util.LinkedHashSet; | ||
10 | import java.util.List; | ||
11 | import java.util.Objects; | ||
12 | import java.util.Optional; | ||
13 | import java.util.Set; | ||
14 | import java.util.function.Consumer; | ||
15 | import java.util.stream.Collectors; | ||
16 | import java.util.stream.Stream; | ||
17 | import org.apache.log4j.Logger; | ||
18 | import org.eclipse.emf.ecore.EClass; | ||
19 | import org.eclipse.viatra.query.runtime.api.IPatternMatch; | ||
20 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification; | ||
21 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; | ||
22 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; | ||
23 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; | ||
24 | import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; | ||
25 | import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; | ||
26 | import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; | ||
27 | import org.eclipse.viatra.query.runtime.emf.types.EStructuralFeatureInstancesKey; | ||
28 | import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; | ||
29 | import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; | ||
30 | import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; | ||
31 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; | ||
32 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; | ||
33 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality; | ||
34 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; | ||
35 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Inequality; | ||
36 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; | ||
37 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; | ||
38 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; | ||
39 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; | ||
40 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; | ||
41 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | ||
42 | import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; | ||
43 | |||
44 | /** | ||
45 | * A pattern-specific query specification that can instantiate Matcher in a type-safe way. | ||
46 | * | ||
47 | * <p>Original source: | ||
48 | * <code><pre> | ||
49 | * Simplifying model generation | ||
50 | * | ||
51 | * {@literal @}Constraint(severity="error", message="error", key = {s}) | ||
52 | * pattern synchThree(s: Synchronization) { | ||
53 | * Transition.target(t1,s); | ||
54 | * Transition.target(t2,s); | ||
55 | * Transition.target(t3,s); | ||
56 | * t1!=t2; | ||
57 | * t2!=t3; | ||
58 | * t1!=t3; | ||
59 | * } or { | ||
60 | * Transition.source(t1,s); | ||
61 | * Transition.source(t2,s); | ||
62 | * Transition.source(t3,s); | ||
63 | * t1!=t2; | ||
64 | * t2!=t3; | ||
65 | * t1!=t3; | ||
66 | * } | ||
67 | * </pre></code> | ||
68 | * | ||
69 | * @see Matcher | ||
70 | * @see Match | ||
71 | * | ||
72 | */ | ||
73 | @SuppressWarnings("all") | ||
74 | public final class SynchThree extends BaseGeneratedEMFQuerySpecification<SynchThree.Matcher> { | ||
75 | /** | ||
76 | * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.synchThree pattern, | ||
77 | * to be used in conjunction with {@link Matcher}. | ||
78 | * | ||
79 | * <p>Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. | ||
80 | * Each instance is a (possibly partial) substitution of pattern parameters, | ||
81 | * usable to represent a match of the pattern in the result of a query, | ||
82 | * or to specify the bound (fixed) input parameters when issuing a query. | ||
83 | * | ||
84 | * @see Matcher | ||
85 | * | ||
86 | */ | ||
87 | public static abstract class Match extends BasePatternMatch { | ||
88 | private Synchronization fS; | ||
89 | |||
90 | private static List<String> parameterNames = makeImmutableList("s"); | ||
91 | |||
92 | private Match(final Synchronization pS) { | ||
93 | this.fS = pS; | ||
94 | } | ||
95 | |||
96 | @Override | ||
97 | public Object get(final String parameterName) { | ||
98 | if ("s".equals(parameterName)) return this.fS; | ||
99 | return null; | ||
100 | } | ||
101 | |||
102 | public Synchronization getS() { | ||
103 | return this.fS; | ||
104 | } | ||
105 | |||
106 | @Override | ||
107 | public boolean set(final String parameterName, final Object newValue) { | ||
108 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
109 | if ("s".equals(parameterName) ) { | ||
110 | this.fS = (Synchronization) newValue; | ||
111 | return true; | ||
112 | } | ||
113 | return false; | ||
114 | } | ||
115 | |||
116 | public void setS(final Synchronization pS) { | ||
117 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
118 | this.fS = pS; | ||
119 | } | ||
120 | |||
121 | @Override | ||
122 | public String patternName() { | ||
123 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.synchThree"; | ||
124 | } | ||
125 | |||
126 | @Override | ||
127 | public List<String> parameterNames() { | ||
128 | return SynchThree.Match.parameterNames; | ||
129 | } | ||
130 | |||
131 | @Override | ||
132 | public Object[] toArray() { | ||
133 | return new Object[]{fS}; | ||
134 | } | ||
135 | |||
136 | @Override | ||
137 | public SynchThree.Match toImmutable() { | ||
138 | return isMutable() ? newMatch(fS) : this; | ||
139 | } | ||
140 | |||
141 | @Override | ||
142 | public String prettyPrint() { | ||
143 | StringBuilder result = new StringBuilder(); | ||
144 | result.append("\"s\"=" + prettyPrintValue(fS)); | ||
145 | return result.toString(); | ||
146 | } | ||
147 | |||
148 | @Override | ||
149 | public int hashCode() { | ||
150 | return Objects.hash(fS); | ||
151 | } | ||
152 | |||
153 | @Override | ||
154 | public boolean equals(final Object obj) { | ||
155 | if (this == obj) | ||
156 | return true; | ||
157 | if (obj == null) { | ||
158 | return false; | ||
159 | } | ||
160 | if ((obj instanceof SynchThree.Match)) { | ||
161 | SynchThree.Match other = (SynchThree.Match) obj; | ||
162 | return Objects.equals(fS, other.fS); | ||
163 | } else { | ||
164 | // this should be infrequent | ||
165 | if (!(obj instanceof IPatternMatch)) { | ||
166 | return false; | ||
167 | } | ||
168 | IPatternMatch otherSig = (IPatternMatch) obj; | ||
169 | return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); | ||
170 | } | ||
171 | } | ||
172 | |||
173 | @Override | ||
174 | public SynchThree specification() { | ||
175 | return SynchThree.instance(); | ||
176 | } | ||
177 | |||
178 | /** | ||
179 | * Returns an empty, mutable match. | ||
180 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
181 | * | ||
182 | * @return the empty match. | ||
183 | * | ||
184 | */ | ||
185 | public static SynchThree.Match newEmptyMatch() { | ||
186 | return new Mutable(null); | ||
187 | } | ||
188 | |||
189 | /** | ||
190 | * Returns a mutable (partial) match. | ||
191 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
192 | * | ||
193 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
194 | * @return the new, mutable (partial) match object. | ||
195 | * | ||
196 | */ | ||
197 | public static SynchThree.Match newMutableMatch(final Synchronization pS) { | ||
198 | return new Mutable(pS); | ||
199 | } | ||
200 | |||
201 | /** | ||
202 | * Returns a new (partial) match. | ||
203 | * This can be used e.g. to call the matcher with a partial match. | ||
204 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
205 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
206 | * @return the (partial) match object. | ||
207 | * | ||
208 | */ | ||
209 | public static SynchThree.Match newMatch(final Synchronization pS) { | ||
210 | return new Immutable(pS); | ||
211 | } | ||
212 | |||
213 | private static final class Mutable extends SynchThree.Match { | ||
214 | Mutable(final Synchronization pS) { | ||
215 | super(pS); | ||
216 | } | ||
217 | |||
218 | @Override | ||
219 | public boolean isMutable() { | ||
220 | return true; | ||
221 | } | ||
222 | } | ||
223 | |||
224 | private static final class Immutable extends SynchThree.Match { | ||
225 | Immutable(final Synchronization pS) { | ||
226 | super(pS); | ||
227 | } | ||
228 | |||
229 | @Override | ||
230 | public boolean isMutable() { | ||
231 | return false; | ||
232 | } | ||
233 | } | ||
234 | } | ||
235 | |||
236 | /** | ||
237 | * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.synchThree pattern, | ||
238 | * providing pattern-specific query methods. | ||
239 | * | ||
240 | * <p>Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, | ||
241 | * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. | ||
242 | * | ||
243 | * <p>Matches of the pattern will be represented as {@link Match}. | ||
244 | * | ||
245 | * <p>Original source: | ||
246 | * <code><pre> | ||
247 | * Simplifying model generation | ||
248 | * | ||
249 | * {@literal @}Constraint(severity="error", message="error", key = {s}) | ||
250 | * pattern synchThree(s: Synchronization) { | ||
251 | * Transition.target(t1,s); | ||
252 | * Transition.target(t2,s); | ||
253 | * Transition.target(t3,s); | ||
254 | * t1!=t2; | ||
255 | * t2!=t3; | ||
256 | * t1!=t3; | ||
257 | * } or { | ||
258 | * Transition.source(t1,s); | ||
259 | * Transition.source(t2,s); | ||
260 | * Transition.source(t3,s); | ||
261 | * t1!=t2; | ||
262 | * t2!=t3; | ||
263 | * t1!=t3; | ||
264 | * } | ||
265 | * </pre></code> | ||
266 | * | ||
267 | * @see Match | ||
268 | * @see SynchThree | ||
269 | * | ||
270 | */ | ||
271 | public static class Matcher extends BaseMatcher<SynchThree.Match> { | ||
272 | /** | ||
273 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
274 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
275 | * | ||
276 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
277 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
278 | * | ||
279 | */ | ||
280 | public static SynchThree.Matcher on(final ViatraQueryEngine engine) { | ||
281 | // check if matcher already exists | ||
282 | Matcher matcher = engine.getExistingMatcher(querySpecification()); | ||
283 | if (matcher == null) { | ||
284 | matcher = (Matcher)engine.getMatcher(querySpecification()); | ||
285 | } | ||
286 | return matcher; | ||
287 | } | ||
288 | |||
289 | /** | ||
290 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
291 | * @return an initialized matcher | ||
292 | * @noreference This method is for internal matcher initialization by the framework, do not call it manually. | ||
293 | * | ||
294 | */ | ||
295 | public static SynchThree.Matcher create() { | ||
296 | return new Matcher(); | ||
297 | } | ||
298 | |||
299 | private final static int POSITION_S = 0; | ||
300 | |||
301 | private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(SynchThree.Matcher.class); | ||
302 | |||
303 | /** | ||
304 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
305 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
306 | * | ||
307 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
308 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
309 | * | ||
310 | */ | ||
311 | private Matcher() { | ||
312 | super(querySpecification()); | ||
313 | } | ||
314 | |||
315 | /** | ||
316 | * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. | ||
317 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
318 | * @return matches represented as a Match object. | ||
319 | * | ||
320 | */ | ||
321 | public Collection<SynchThree.Match> getAllMatches(final Synchronization pS) { | ||
322 | return rawStreamAllMatches(new Object[]{pS}).collect(Collectors.toSet()); | ||
323 | } | ||
324 | |||
325 | /** | ||
326 | * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. | ||
327 | * </p> | ||
328 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
329 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
330 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
331 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
332 | * @return a stream of matches represented as a Match object. | ||
333 | * | ||
334 | */ | ||
335 | public Stream<SynchThree.Match> streamAllMatches(final Synchronization pS) { | ||
336 | return rawStreamAllMatches(new Object[]{pS}); | ||
337 | } | ||
338 | |||
339 | /** | ||
340 | * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
341 | * Neither determinism nor randomness of selection is guaranteed. | ||
342 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
343 | * @return a match represented as a Match object, or null if no match is found. | ||
344 | * | ||
345 | */ | ||
346 | public Optional<SynchThree.Match> getOneArbitraryMatch(final Synchronization pS) { | ||
347 | return rawGetOneArbitraryMatch(new Object[]{pS}); | ||
348 | } | ||
349 | |||
350 | /** | ||
351 | * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, | ||
352 | * under any possible substitution of the unspecified parameters (if any). | ||
353 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
354 | * @return true if the input is a valid (partial) match of the pattern. | ||
355 | * | ||
356 | */ | ||
357 | public boolean hasMatch(final Synchronization pS) { | ||
358 | return rawHasMatch(new Object[]{pS}); | ||
359 | } | ||
360 | |||
361 | /** | ||
362 | * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. | ||
363 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
364 | * @return the number of pattern matches found. | ||
365 | * | ||
366 | */ | ||
367 | public int countMatches(final Synchronization pS) { | ||
368 | return rawCountMatches(new Object[]{pS}); | ||
369 | } | ||
370 | |||
371 | /** | ||
372 | * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
373 | * Neither determinism nor randomness of selection is guaranteed. | ||
374 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
375 | * @param processor the action that will process the selected match. | ||
376 | * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked | ||
377 | * | ||
378 | */ | ||
379 | public boolean forOneArbitraryMatch(final Synchronization pS, final Consumer<? super SynchThree.Match> processor) { | ||
380 | return rawForOneArbitraryMatch(new Object[]{pS}, processor); | ||
381 | } | ||
382 | |||
383 | /** | ||
384 | * Returns a new (partial) match. | ||
385 | * This can be used e.g. to call the matcher with a partial match. | ||
386 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
387 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
388 | * @return the (partial) match object. | ||
389 | * | ||
390 | */ | ||
391 | public SynchThree.Match newMatch(final Synchronization pS) { | ||
392 | return SynchThree.Match.newMatch(pS); | ||
393 | } | ||
394 | |||
395 | /** | ||
396 | * Retrieve the set of values that occur in matches for s. | ||
397 | * @return the Set of all values or empty set if there are no matches | ||
398 | * | ||
399 | */ | ||
400 | protected Stream<Synchronization> rawStreamAllValuesOfs(final Object[] parameters) { | ||
401 | return rawStreamAllValues(POSITION_S, parameters).map(Synchronization.class::cast); | ||
402 | } | ||
403 | |||
404 | /** | ||
405 | * Retrieve the set of values that occur in matches for s. | ||
406 | * @return the Set of all values or empty set if there are no matches | ||
407 | * | ||
408 | */ | ||
409 | public Set<Synchronization> getAllValuesOfs() { | ||
410 | return rawStreamAllValuesOfs(emptyArray()).collect(Collectors.toSet()); | ||
411 | } | ||
412 | |||
413 | /** | ||
414 | * Retrieve the set of values that occur in matches for s. | ||
415 | * @return the Set of all values or empty set if there are no matches | ||
416 | * | ||
417 | */ | ||
418 | public Stream<Synchronization> streamAllValuesOfs() { | ||
419 | return rawStreamAllValuesOfs(emptyArray()); | ||
420 | } | ||
421 | |||
422 | @Override | ||
423 | protected SynchThree.Match tupleToMatch(final Tuple t) { | ||
424 | try { | ||
425 | return SynchThree.Match.newMatch((Synchronization) t.get(POSITION_S)); | ||
426 | } catch(ClassCastException e) { | ||
427 | LOGGER.error("Element(s) in tuple not properly typed!",e); | ||
428 | return null; | ||
429 | } | ||
430 | } | ||
431 | |||
432 | @Override | ||
433 | protected SynchThree.Match arrayToMatch(final Object[] match) { | ||
434 | try { | ||
435 | return SynchThree.Match.newMatch((Synchronization) match[POSITION_S]); | ||
436 | } catch(ClassCastException e) { | ||
437 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
438 | return null; | ||
439 | } | ||
440 | } | ||
441 | |||
442 | @Override | ||
443 | protected SynchThree.Match arrayToMatchMutable(final Object[] match) { | ||
444 | try { | ||
445 | return SynchThree.Match.newMutableMatch((Synchronization) match[POSITION_S]); | ||
446 | } catch(ClassCastException e) { | ||
447 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
448 | return null; | ||
449 | } | ||
450 | } | ||
451 | |||
452 | /** | ||
453 | * @return the singleton instance of the query specification of this pattern | ||
454 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
455 | * | ||
456 | */ | ||
457 | public static IQuerySpecification<SynchThree.Matcher> querySpecification() { | ||
458 | return SynchThree.instance(); | ||
459 | } | ||
460 | } | ||
461 | |||
462 | private SynchThree() { | ||
463 | super(GeneratedPQuery.INSTANCE); | ||
464 | } | ||
465 | |||
466 | /** | ||
467 | * @return the singleton instance of the query specification | ||
468 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
469 | * | ||
470 | */ | ||
471 | public static SynchThree instance() { | ||
472 | try{ | ||
473 | return LazyHolder.INSTANCE; | ||
474 | } catch (ExceptionInInitializerError err) { | ||
475 | throw processInitializerError(err); | ||
476 | } | ||
477 | } | ||
478 | |||
479 | @Override | ||
480 | protected SynchThree.Matcher instantiate(final ViatraQueryEngine engine) { | ||
481 | return SynchThree.Matcher.on(engine); | ||
482 | } | ||
483 | |||
484 | @Override | ||
485 | public SynchThree.Matcher instantiate() { | ||
486 | return SynchThree.Matcher.create(); | ||
487 | } | ||
488 | |||
489 | @Override | ||
490 | public SynchThree.Match newEmptyMatch() { | ||
491 | return SynchThree.Match.newEmptyMatch(); | ||
492 | } | ||
493 | |||
494 | @Override | ||
495 | public SynchThree.Match newMatch(final Object... parameters) { | ||
496 | return SynchThree.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization) parameters[0]); | ||
497 | } | ||
498 | |||
499 | /** | ||
500 | * Inner class allowing the singleton instance of {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchThree (visibility: PUBLIC, simpleName: SynchThree, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchThree, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created | ||
501 | * <b>not</b> at the class load time of the outer class, | ||
502 | * but rather at the first call to {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchThree (visibility: PUBLIC, simpleName: SynchThree, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchThree, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. | ||
503 | * | ||
504 | * <p> This workaround is required e.g. to support recursion. | ||
505 | * | ||
506 | */ | ||
507 | private static class LazyHolder { | ||
508 | private final static SynchThree INSTANCE = new SynchThree(); | ||
509 | |||
510 | /** | ||
511 | * Statically initializes the query specification <b>after</b> the field {@link #INSTANCE} is assigned. | ||
512 | * This initialization order is required to support indirect recursion. | ||
513 | * | ||
514 | * <p> The static initializer is defined using a helper field to work around limitations of the code generator. | ||
515 | * | ||
516 | */ | ||
517 | private final static Object STATIC_INITIALIZER = ensureInitialized(); | ||
518 | |||
519 | public static Object ensureInitialized() { | ||
520 | INSTANCE.ensureInitializedInternal(); | ||
521 | return null; | ||
522 | } | ||
523 | } | ||
524 | |||
525 | private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { | ||
526 | private final static SynchThree.GeneratedPQuery INSTANCE = new GeneratedPQuery(); | ||
527 | |||
528 | private final PParameter parameter_s = new PParameter("s", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Synchronization")), PParameterDirection.INOUT); | ||
529 | |||
530 | private final List<PParameter> parameters = Arrays.asList(parameter_s); | ||
531 | |||
532 | private GeneratedPQuery() { | ||
533 | super(PVisibility.PUBLIC); | ||
534 | } | ||
535 | |||
536 | @Override | ||
537 | public String getFullyQualifiedName() { | ||
538 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.synchThree"; | ||
539 | } | ||
540 | |||
541 | @Override | ||
542 | public List<String> getParameterNames() { | ||
543 | return Arrays.asList("s"); | ||
544 | } | ||
545 | |||
546 | @Override | ||
547 | public List<PParameter> getParameters() { | ||
548 | return parameters; | ||
549 | } | ||
550 | |||
551 | @Override | ||
552 | public Set<PBody> doGetContainedBodies() { | ||
553 | setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); | ||
554 | Set<PBody> bodies = new LinkedHashSet<>(); | ||
555 | { | ||
556 | PBody body = new PBody(this); | ||
557 | PVariable var_s = body.getOrCreateVariableByName("s"); | ||
558 | PVariable var_t1 = body.getOrCreateVariableByName("t1"); | ||
559 | PVariable var_t2 = body.getOrCreateVariableByName("t2"); | ||
560 | PVariable var_t3 = body.getOrCreateVariableByName("t3"); | ||
561 | new TypeConstraint(body, Tuples.flatTupleOf(var_s), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Synchronization"))); | ||
562 | body.setSymbolicParameters(Arrays.<ExportedParameter>asList( | ||
563 | new ExportedParameter(body, var_s, parameter_s) | ||
564 | )); | ||
565 | // Transition.target(t1,s) | ||
566 | new TypeConstraint(body, Tuples.flatTupleOf(var_t1), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); | ||
567 | PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); | ||
568 | new TypeConstraint(body, Tuples.flatTupleOf(var_t1, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Transition", "target"))); | ||
569 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); | ||
570 | new Equality(body, var__virtual_0_, var_s); | ||
571 | // Transition.target(t2,s) | ||
572 | new TypeConstraint(body, Tuples.flatTupleOf(var_t2), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); | ||
573 | PVariable var__virtual_1_ = body.getOrCreateVariableByName(".virtual{1}"); | ||
574 | new TypeConstraint(body, Tuples.flatTupleOf(var_t2, var__virtual_1_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Transition", "target"))); | ||
575 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_1_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); | ||
576 | new Equality(body, var__virtual_1_, var_s); | ||
577 | // Transition.target(t3,s) | ||
578 | new TypeConstraint(body, Tuples.flatTupleOf(var_t3), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); | ||
579 | PVariable var__virtual_2_ = body.getOrCreateVariableByName(".virtual{2}"); | ||
580 | new TypeConstraint(body, Tuples.flatTupleOf(var_t3, var__virtual_2_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Transition", "target"))); | ||
581 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_2_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); | ||
582 | new Equality(body, var__virtual_2_, var_s); | ||
583 | // t1!=t2 | ||
584 | new Inequality(body, var_t1, var_t2); | ||
585 | // t2!=t3 | ||
586 | new Inequality(body, var_t2, var_t3); | ||
587 | // t1!=t3 | ||
588 | new Inequality(body, var_t1, var_t3); | ||
589 | bodies.add(body); | ||
590 | } | ||
591 | { | ||
592 | PBody body = new PBody(this); | ||
593 | PVariable var_s = body.getOrCreateVariableByName("s"); | ||
594 | PVariable var_t1 = body.getOrCreateVariableByName("t1"); | ||
595 | PVariable var_t2 = body.getOrCreateVariableByName("t2"); | ||
596 | PVariable var_t3 = body.getOrCreateVariableByName("t3"); | ||
597 | new TypeConstraint(body, Tuples.flatTupleOf(var_s), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Synchronization"))); | ||
598 | body.setSymbolicParameters(Arrays.<ExportedParameter>asList( | ||
599 | new ExportedParameter(body, var_s, parameter_s) | ||
600 | )); | ||
601 | // Transition.source(t1,s) | ||
602 | new TypeConstraint(body, Tuples.flatTupleOf(var_t1), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); | ||
603 | PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); | ||
604 | new TypeConstraint(body, Tuples.flatTupleOf(var_t1, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Transition", "source"))); | ||
605 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); | ||
606 | new Equality(body, var__virtual_0_, var_s); | ||
607 | // Transition.source(t2,s) | ||
608 | new TypeConstraint(body, Tuples.flatTupleOf(var_t2), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); | ||
609 | PVariable var__virtual_1_ = body.getOrCreateVariableByName(".virtual{1}"); | ||
610 | new TypeConstraint(body, Tuples.flatTupleOf(var_t2, var__virtual_1_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Transition", "source"))); | ||
611 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_1_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); | ||
612 | new Equality(body, var__virtual_1_, var_s); | ||
613 | // Transition.source(t3,s) | ||
614 | new TypeConstraint(body, Tuples.flatTupleOf(var_t3), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); | ||
615 | PVariable var__virtual_2_ = body.getOrCreateVariableByName(".virtual{2}"); | ||
616 | new TypeConstraint(body, Tuples.flatTupleOf(var_t3, var__virtual_2_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Transition", "source"))); | ||
617 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_2_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); | ||
618 | new Equality(body, var__virtual_2_, var_s); | ||
619 | // t1!=t2 | ||
620 | new Inequality(body, var_t1, var_t2); | ||
621 | // t2!=t3 | ||
622 | new Inequality(body, var_t2, var_t3); | ||
623 | // t1!=t3 | ||
624 | new Inequality(body, var_t1, var_t3); | ||
625 | bodies.add(body); | ||
626 | } | ||
627 | { | ||
628 | PAnnotation annotation = new PAnnotation("Constraint"); | ||
629 | annotation.addAttribute("severity", "error"); | ||
630 | annotation.addAttribute("message", "error"); | ||
631 | annotation.addAttribute("key", Arrays.asList(new Object[] { | ||
632 | new ParameterReference("s") | ||
633 | })); | ||
634 | addAnnotation(annotation); | ||
635 | } | ||
636 | return bodies; | ||
637 | } | ||
638 | } | ||
639 | } | ||
diff --git a/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/SynchronizedIncomingInSameRegion.java b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/SynchronizedIncomingInSameRegion.java new file mode 100644 index 00000000..dabbe8c5 --- /dev/null +++ b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/SynchronizedIncomingInSameRegion.java | |||
@@ -0,0 +1,888 @@ | |||
1 | /** | ||
2 | * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql | ||
3 | */ | ||
4 | package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; | ||
5 | |||
6 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization; | ||
7 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex; | ||
8 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.Transition; | ||
9 | import java.util.Arrays; | ||
10 | import java.util.Collection; | ||
11 | import java.util.LinkedHashSet; | ||
12 | import java.util.List; | ||
13 | import java.util.Objects; | ||
14 | import java.util.Optional; | ||
15 | import java.util.Set; | ||
16 | import java.util.function.Consumer; | ||
17 | import java.util.stream.Collectors; | ||
18 | import java.util.stream.Stream; | ||
19 | import org.apache.log4j.Logger; | ||
20 | import org.eclipse.emf.ecore.EClass; | ||
21 | import org.eclipse.viatra.query.runtime.api.IPatternMatch; | ||
22 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification; | ||
23 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; | ||
24 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; | ||
25 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; | ||
26 | import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; | ||
27 | import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; | ||
28 | import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; | ||
29 | import org.eclipse.viatra.query.runtime.emf.types.EStructuralFeatureInstancesKey; | ||
30 | import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; | ||
31 | import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; | ||
32 | import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; | ||
33 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; | ||
34 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; | ||
35 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality; | ||
36 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; | ||
37 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Inequality; | ||
38 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall; | ||
39 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; | ||
40 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; | ||
41 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; | ||
42 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; | ||
43 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; | ||
44 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | ||
45 | import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; | ||
46 | |||
47 | /** | ||
48 | * A pattern-specific query specification that can instantiate Matcher in a type-safe way. | ||
49 | * | ||
50 | * <p>Original source: | ||
51 | * <code><pre> | ||
52 | * {@literal @}Constraint(severity="error", message="error", key = {s}) | ||
53 | * pattern SynchronizedIncomingInSameRegion(s : Synchronization, v1 : Vertex, v2 : Vertex) { | ||
54 | * find transition(t1, v1, s); | ||
55 | * find transition(t2, v2, s); | ||
56 | * t1!=t2; | ||
57 | * Region.vertices(r, v1); | ||
58 | * Region.vertices(r, v2); | ||
59 | * } or { | ||
60 | * find transition(t1, s, v1); | ||
61 | * find transition(t2, s, v2); | ||
62 | * t1!=t2; | ||
63 | * Region.vertices(r, v1); | ||
64 | * Region.vertices(r, v2); | ||
65 | * } | ||
66 | * </pre></code> | ||
67 | * | ||
68 | * @see Matcher | ||
69 | * @see Match | ||
70 | * | ||
71 | */ | ||
72 | @SuppressWarnings("all") | ||
73 | public final class SynchronizedIncomingInSameRegion extends BaseGeneratedEMFQuerySpecification<SynchronizedIncomingInSameRegion.Matcher> { | ||
74 | /** | ||
75 | * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedIncomingInSameRegion pattern, | ||
76 | * to be used in conjunction with {@link Matcher}. | ||
77 | * | ||
78 | * <p>Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. | ||
79 | * Each instance is a (possibly partial) substitution of pattern parameters, | ||
80 | * usable to represent a match of the pattern in the result of a query, | ||
81 | * or to specify the bound (fixed) input parameters when issuing a query. | ||
82 | * | ||
83 | * @see Matcher | ||
84 | * | ||
85 | */ | ||
86 | public static abstract class Match extends BasePatternMatch { | ||
87 | private Synchronization fS; | ||
88 | |||
89 | private Vertex fV1; | ||
90 | |||
91 | private Vertex fV2; | ||
92 | |||
93 | private static List<String> parameterNames = makeImmutableList("s", "v1", "v2"); | ||
94 | |||
95 | private Match(final Synchronization pS, final Vertex pV1, final Vertex pV2) { | ||
96 | this.fS = pS; | ||
97 | this.fV1 = pV1; | ||
98 | this.fV2 = pV2; | ||
99 | } | ||
100 | |||
101 | @Override | ||
102 | public Object get(final String parameterName) { | ||
103 | if ("s".equals(parameterName)) return this.fS; | ||
104 | if ("v1".equals(parameterName)) return this.fV1; | ||
105 | if ("v2".equals(parameterName)) return this.fV2; | ||
106 | return null; | ||
107 | } | ||
108 | |||
109 | public Synchronization getS() { | ||
110 | return this.fS; | ||
111 | } | ||
112 | |||
113 | public Vertex getV1() { | ||
114 | return this.fV1; | ||
115 | } | ||
116 | |||
117 | public Vertex getV2() { | ||
118 | return this.fV2; | ||
119 | } | ||
120 | |||
121 | @Override | ||
122 | public boolean set(final String parameterName, final Object newValue) { | ||
123 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
124 | if ("s".equals(parameterName) ) { | ||
125 | this.fS = (Synchronization) newValue; | ||
126 | return true; | ||
127 | } | ||
128 | if ("v1".equals(parameterName) ) { | ||
129 | this.fV1 = (Vertex) newValue; | ||
130 | return true; | ||
131 | } | ||
132 | if ("v2".equals(parameterName) ) { | ||
133 | this.fV2 = (Vertex) newValue; | ||
134 | return true; | ||
135 | } | ||
136 | return false; | ||
137 | } | ||
138 | |||
139 | public void setS(final Synchronization pS) { | ||
140 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
141 | this.fS = pS; | ||
142 | } | ||
143 | |||
144 | public void setV1(final Vertex pV1) { | ||
145 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
146 | this.fV1 = pV1; | ||
147 | } | ||
148 | |||
149 | public void setV2(final Vertex pV2) { | ||
150 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
151 | this.fV2 = pV2; | ||
152 | } | ||
153 | |||
154 | @Override | ||
155 | public String patternName() { | ||
156 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedIncomingInSameRegion"; | ||
157 | } | ||
158 | |||
159 | @Override | ||
160 | public List<String> parameterNames() { | ||
161 | return SynchronizedIncomingInSameRegion.Match.parameterNames; | ||
162 | } | ||
163 | |||
164 | @Override | ||
165 | public Object[] toArray() { | ||
166 | return new Object[]{fS, fV1, fV2}; | ||
167 | } | ||
168 | |||
169 | @Override | ||
170 | public SynchronizedIncomingInSameRegion.Match toImmutable() { | ||
171 | return isMutable() ? newMatch(fS, fV1, fV2) : this; | ||
172 | } | ||
173 | |||
174 | @Override | ||
175 | public String prettyPrint() { | ||
176 | StringBuilder result = new StringBuilder(); | ||
177 | result.append("\"s\"=" + prettyPrintValue(fS) + ", "); | ||
178 | result.append("\"v1\"=" + prettyPrintValue(fV1) + ", "); | ||
179 | result.append("\"v2\"=" + prettyPrintValue(fV2)); | ||
180 | return result.toString(); | ||
181 | } | ||
182 | |||
183 | @Override | ||
184 | public int hashCode() { | ||
185 | return Objects.hash(fS, fV1, fV2); | ||
186 | } | ||
187 | |||
188 | @Override | ||
189 | public boolean equals(final Object obj) { | ||
190 | if (this == obj) | ||
191 | return true; | ||
192 | if (obj == null) { | ||
193 | return false; | ||
194 | } | ||
195 | if ((obj instanceof SynchronizedIncomingInSameRegion.Match)) { | ||
196 | SynchronizedIncomingInSameRegion.Match other = (SynchronizedIncomingInSameRegion.Match) obj; | ||
197 | return Objects.equals(fS, other.fS) && Objects.equals(fV1, other.fV1) && Objects.equals(fV2, other.fV2); | ||
198 | } else { | ||
199 | // this should be infrequent | ||
200 | if (!(obj instanceof IPatternMatch)) { | ||
201 | return false; | ||
202 | } | ||
203 | IPatternMatch otherSig = (IPatternMatch) obj; | ||
204 | return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); | ||
205 | } | ||
206 | } | ||
207 | |||
208 | @Override | ||
209 | public SynchronizedIncomingInSameRegion specification() { | ||
210 | return SynchronizedIncomingInSameRegion.instance(); | ||
211 | } | ||
212 | |||
213 | /** | ||
214 | * Returns an empty, mutable match. | ||
215 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
216 | * | ||
217 | * @return the empty match. | ||
218 | * | ||
219 | */ | ||
220 | public static SynchronizedIncomingInSameRegion.Match newEmptyMatch() { | ||
221 | return new Mutable(null, null, null); | ||
222 | } | ||
223 | |||
224 | /** | ||
225 | * Returns a mutable (partial) match. | ||
226 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
227 | * | ||
228 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
229 | * @param pV1 the fixed value of pattern parameter v1, or null if not bound. | ||
230 | * @param pV2 the fixed value of pattern parameter v2, or null if not bound. | ||
231 | * @return the new, mutable (partial) match object. | ||
232 | * | ||
233 | */ | ||
234 | public static SynchronizedIncomingInSameRegion.Match newMutableMatch(final Synchronization pS, final Vertex pV1, final Vertex pV2) { | ||
235 | return new Mutable(pS, pV1, pV2); | ||
236 | } | ||
237 | |||
238 | /** | ||
239 | * Returns a new (partial) match. | ||
240 | * This can be used e.g. to call the matcher with a partial match. | ||
241 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
242 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
243 | * @param pV1 the fixed value of pattern parameter v1, or null if not bound. | ||
244 | * @param pV2 the fixed value of pattern parameter v2, or null if not bound. | ||
245 | * @return the (partial) match object. | ||
246 | * | ||
247 | */ | ||
248 | public static SynchronizedIncomingInSameRegion.Match newMatch(final Synchronization pS, final Vertex pV1, final Vertex pV2) { | ||
249 | return new Immutable(pS, pV1, pV2); | ||
250 | } | ||
251 | |||
252 | private static final class Mutable extends SynchronizedIncomingInSameRegion.Match { | ||
253 | Mutable(final Synchronization pS, final Vertex pV1, final Vertex pV2) { | ||
254 | super(pS, pV1, pV2); | ||
255 | } | ||
256 | |||
257 | @Override | ||
258 | public boolean isMutable() { | ||
259 | return true; | ||
260 | } | ||
261 | } | ||
262 | |||
263 | private static final class Immutable extends SynchronizedIncomingInSameRegion.Match { | ||
264 | Immutable(final Synchronization pS, final Vertex pV1, final Vertex pV2) { | ||
265 | super(pS, pV1, pV2); | ||
266 | } | ||
267 | |||
268 | @Override | ||
269 | public boolean isMutable() { | ||
270 | return false; | ||
271 | } | ||
272 | } | ||
273 | } | ||
274 | |||
275 | /** | ||
276 | * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedIncomingInSameRegion pattern, | ||
277 | * providing pattern-specific query methods. | ||
278 | * | ||
279 | * <p>Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, | ||
280 | * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. | ||
281 | * | ||
282 | * <p>Matches of the pattern will be represented as {@link Match}. | ||
283 | * | ||
284 | * <p>Original source: | ||
285 | * <code><pre> | ||
286 | * {@literal @}Constraint(severity="error", message="error", key = {s}) | ||
287 | * pattern SynchronizedIncomingInSameRegion(s : Synchronization, v1 : Vertex, v2 : Vertex) { | ||
288 | * find transition(t1, v1, s); | ||
289 | * find transition(t2, v2, s); | ||
290 | * t1!=t2; | ||
291 | * Region.vertices(r, v1); | ||
292 | * Region.vertices(r, v2); | ||
293 | * } or { | ||
294 | * find transition(t1, s, v1); | ||
295 | * find transition(t2, s, v2); | ||
296 | * t1!=t2; | ||
297 | * Region.vertices(r, v1); | ||
298 | * Region.vertices(r, v2); | ||
299 | * } | ||
300 | * </pre></code> | ||
301 | * | ||
302 | * @see Match | ||
303 | * @see SynchronizedIncomingInSameRegion | ||
304 | * | ||
305 | */ | ||
306 | public static class Matcher extends BaseMatcher<SynchronizedIncomingInSameRegion.Match> { | ||
307 | /** | ||
308 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
309 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
310 | * | ||
311 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
312 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
313 | * | ||
314 | */ | ||
315 | public static SynchronizedIncomingInSameRegion.Matcher on(final ViatraQueryEngine engine) { | ||
316 | // check if matcher already exists | ||
317 | Matcher matcher = engine.getExistingMatcher(querySpecification()); | ||
318 | if (matcher == null) { | ||
319 | matcher = (Matcher)engine.getMatcher(querySpecification()); | ||
320 | } | ||
321 | return matcher; | ||
322 | } | ||
323 | |||
324 | /** | ||
325 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
326 | * @return an initialized matcher | ||
327 | * @noreference This method is for internal matcher initialization by the framework, do not call it manually. | ||
328 | * | ||
329 | */ | ||
330 | public static SynchronizedIncomingInSameRegion.Matcher create() { | ||
331 | return new Matcher(); | ||
332 | } | ||
333 | |||
334 | private final static int POSITION_S = 0; | ||
335 | |||
336 | private final static int POSITION_V1 = 1; | ||
337 | |||
338 | private final static int POSITION_V2 = 2; | ||
339 | |||
340 | private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(SynchronizedIncomingInSameRegion.Matcher.class); | ||
341 | |||
342 | /** | ||
343 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
344 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
345 | * | ||
346 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
347 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
348 | * | ||
349 | */ | ||
350 | private Matcher() { | ||
351 | super(querySpecification()); | ||
352 | } | ||
353 | |||
354 | /** | ||
355 | * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. | ||
356 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
357 | * @param pV1 the fixed value of pattern parameter v1, or null if not bound. | ||
358 | * @param pV2 the fixed value of pattern parameter v2, or null if not bound. | ||
359 | * @return matches represented as a Match object. | ||
360 | * | ||
361 | */ | ||
362 | public Collection<SynchronizedIncomingInSameRegion.Match> getAllMatches(final Synchronization pS, final Vertex pV1, final Vertex pV2) { | ||
363 | return rawStreamAllMatches(new Object[]{pS, pV1, pV2}).collect(Collectors.toSet()); | ||
364 | } | ||
365 | |||
366 | /** | ||
367 | * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. | ||
368 | * </p> | ||
369 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
370 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
371 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
372 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
373 | * @param pV1 the fixed value of pattern parameter v1, or null if not bound. | ||
374 | * @param pV2 the fixed value of pattern parameter v2, or null if not bound. | ||
375 | * @return a stream of matches represented as a Match object. | ||
376 | * | ||
377 | */ | ||
378 | public Stream<SynchronizedIncomingInSameRegion.Match> streamAllMatches(final Synchronization pS, final Vertex pV1, final Vertex pV2) { | ||
379 | return rawStreamAllMatches(new Object[]{pS, pV1, pV2}); | ||
380 | } | ||
381 | |||
382 | /** | ||
383 | * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
384 | * Neither determinism nor randomness of selection is guaranteed. | ||
385 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
386 | * @param pV1 the fixed value of pattern parameter v1, or null if not bound. | ||
387 | * @param pV2 the fixed value of pattern parameter v2, or null if not bound. | ||
388 | * @return a match represented as a Match object, or null if no match is found. | ||
389 | * | ||
390 | */ | ||
391 | public Optional<SynchronizedIncomingInSameRegion.Match> getOneArbitraryMatch(final Synchronization pS, final Vertex pV1, final Vertex pV2) { | ||
392 | return rawGetOneArbitraryMatch(new Object[]{pS, pV1, pV2}); | ||
393 | } | ||
394 | |||
395 | /** | ||
396 | * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, | ||
397 | * under any possible substitution of the unspecified parameters (if any). | ||
398 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
399 | * @param pV1 the fixed value of pattern parameter v1, or null if not bound. | ||
400 | * @param pV2 the fixed value of pattern parameter v2, or null if not bound. | ||
401 | * @return true if the input is a valid (partial) match of the pattern. | ||
402 | * | ||
403 | */ | ||
404 | public boolean hasMatch(final Synchronization pS, final Vertex pV1, final Vertex pV2) { | ||
405 | return rawHasMatch(new Object[]{pS, pV1, pV2}); | ||
406 | } | ||
407 | |||
408 | /** | ||
409 | * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. | ||
410 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
411 | * @param pV1 the fixed value of pattern parameter v1, or null if not bound. | ||
412 | * @param pV2 the fixed value of pattern parameter v2, or null if not bound. | ||
413 | * @return the number of pattern matches found. | ||
414 | * | ||
415 | */ | ||
416 | public int countMatches(final Synchronization pS, final Vertex pV1, final Vertex pV2) { | ||
417 | return rawCountMatches(new Object[]{pS, pV1, pV2}); | ||
418 | } | ||
419 | |||
420 | /** | ||
421 | * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
422 | * Neither determinism nor randomness of selection is guaranteed. | ||
423 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
424 | * @param pV1 the fixed value of pattern parameter v1, or null if not bound. | ||
425 | * @param pV2 the fixed value of pattern parameter v2, or null if not bound. | ||
426 | * @param processor the action that will process the selected match. | ||
427 | * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked | ||
428 | * | ||
429 | */ | ||
430 | public boolean forOneArbitraryMatch(final Synchronization pS, final Vertex pV1, final Vertex pV2, final Consumer<? super SynchronizedIncomingInSameRegion.Match> processor) { | ||
431 | return rawForOneArbitraryMatch(new Object[]{pS, pV1, pV2}, processor); | ||
432 | } | ||
433 | |||
434 | /** | ||
435 | * Returns a new (partial) match. | ||
436 | * This can be used e.g. to call the matcher with a partial match. | ||
437 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
438 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
439 | * @param pV1 the fixed value of pattern parameter v1, or null if not bound. | ||
440 | * @param pV2 the fixed value of pattern parameter v2, or null if not bound. | ||
441 | * @return the (partial) match object. | ||
442 | * | ||
443 | */ | ||
444 | public SynchronizedIncomingInSameRegion.Match newMatch(final Synchronization pS, final Vertex pV1, final Vertex pV2) { | ||
445 | return SynchronizedIncomingInSameRegion.Match.newMatch(pS, pV1, pV2); | ||
446 | } | ||
447 | |||
448 | /** | ||
449 | * Retrieve the set of values that occur in matches for s. | ||
450 | * @return the Set of all values or empty set if there are no matches | ||
451 | * | ||
452 | */ | ||
453 | protected Stream<Synchronization> rawStreamAllValuesOfs(final Object[] parameters) { | ||
454 | return rawStreamAllValues(POSITION_S, parameters).map(Synchronization.class::cast); | ||
455 | } | ||
456 | |||
457 | /** | ||
458 | * Retrieve the set of values that occur in matches for s. | ||
459 | * @return the Set of all values or empty set if there are no matches | ||
460 | * | ||
461 | */ | ||
462 | public Set<Synchronization> getAllValuesOfs() { | ||
463 | return rawStreamAllValuesOfs(emptyArray()).collect(Collectors.toSet()); | ||
464 | } | ||
465 | |||
466 | /** | ||
467 | * Retrieve the set of values that occur in matches for s. | ||
468 | * @return the Set of all values or empty set if there are no matches | ||
469 | * | ||
470 | */ | ||
471 | public Stream<Synchronization> streamAllValuesOfs() { | ||
472 | return rawStreamAllValuesOfs(emptyArray()); | ||
473 | } | ||
474 | |||
475 | /** | ||
476 | * Retrieve the set of values that occur in matches for s. | ||
477 | * </p> | ||
478 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
479 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
480 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
481 | * | ||
482 | * @return the Stream of all values or empty set if there are no matches | ||
483 | * | ||
484 | */ | ||
485 | public Stream<Synchronization> streamAllValuesOfs(final SynchronizedIncomingInSameRegion.Match partialMatch) { | ||
486 | return rawStreamAllValuesOfs(partialMatch.toArray()); | ||
487 | } | ||
488 | |||
489 | /** | ||
490 | * Retrieve the set of values that occur in matches for s. | ||
491 | * </p> | ||
492 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
493 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
494 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
495 | * | ||
496 | * @return the Stream of all values or empty set if there are no matches | ||
497 | * | ||
498 | */ | ||
499 | public Stream<Synchronization> streamAllValuesOfs(final Vertex pV1, final Vertex pV2) { | ||
500 | return rawStreamAllValuesOfs(new Object[]{null, pV1, pV2}); | ||
501 | } | ||
502 | |||
503 | /** | ||
504 | * Retrieve the set of values that occur in matches for s. | ||
505 | * @return the Set of all values or empty set if there are no matches | ||
506 | * | ||
507 | */ | ||
508 | public Set<Synchronization> getAllValuesOfs(final SynchronizedIncomingInSameRegion.Match partialMatch) { | ||
509 | return rawStreamAllValuesOfs(partialMatch.toArray()).collect(Collectors.toSet()); | ||
510 | } | ||
511 | |||
512 | /** | ||
513 | * Retrieve the set of values that occur in matches for s. | ||
514 | * @return the Set of all values or empty set if there are no matches | ||
515 | * | ||
516 | */ | ||
517 | public Set<Synchronization> getAllValuesOfs(final Vertex pV1, final Vertex pV2) { | ||
518 | return rawStreamAllValuesOfs(new Object[]{null, pV1, pV2}).collect(Collectors.toSet()); | ||
519 | } | ||
520 | |||
521 | /** | ||
522 | * Retrieve the set of values that occur in matches for v1. | ||
523 | * @return the Set of all values or empty set if there are no matches | ||
524 | * | ||
525 | */ | ||
526 | protected Stream<Vertex> rawStreamAllValuesOfv1(final Object[] parameters) { | ||
527 | return rawStreamAllValues(POSITION_V1, parameters).map(Vertex.class::cast); | ||
528 | } | ||
529 | |||
530 | /** | ||
531 | * Retrieve the set of values that occur in matches for v1. | ||
532 | * @return the Set of all values or empty set if there are no matches | ||
533 | * | ||
534 | */ | ||
535 | public Set<Vertex> getAllValuesOfv1() { | ||
536 | return rawStreamAllValuesOfv1(emptyArray()).collect(Collectors.toSet()); | ||
537 | } | ||
538 | |||
539 | /** | ||
540 | * Retrieve the set of values that occur in matches for v1. | ||
541 | * @return the Set of all values or empty set if there are no matches | ||
542 | * | ||
543 | */ | ||
544 | public Stream<Vertex> streamAllValuesOfv1() { | ||
545 | return rawStreamAllValuesOfv1(emptyArray()); | ||
546 | } | ||
547 | |||
548 | /** | ||
549 | * Retrieve the set of values that occur in matches for v1. | ||
550 | * </p> | ||
551 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
552 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
553 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
554 | * | ||
555 | * @return the Stream of all values or empty set if there are no matches | ||
556 | * | ||
557 | */ | ||
558 | public Stream<Vertex> streamAllValuesOfv1(final SynchronizedIncomingInSameRegion.Match partialMatch) { | ||
559 | return rawStreamAllValuesOfv1(partialMatch.toArray()); | ||
560 | } | ||
561 | |||
562 | /** | ||
563 | * Retrieve the set of values that occur in matches for v1. | ||
564 | * </p> | ||
565 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
566 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
567 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
568 | * | ||
569 | * @return the Stream of all values or empty set if there are no matches | ||
570 | * | ||
571 | */ | ||
572 | public Stream<Vertex> streamAllValuesOfv1(final Synchronization pS, final Vertex pV2) { | ||
573 | return rawStreamAllValuesOfv1(new Object[]{pS, null, pV2}); | ||
574 | } | ||
575 | |||
576 | /** | ||
577 | * Retrieve the set of values that occur in matches for v1. | ||
578 | * @return the Set of all values or empty set if there are no matches | ||
579 | * | ||
580 | */ | ||
581 | public Set<Vertex> getAllValuesOfv1(final SynchronizedIncomingInSameRegion.Match partialMatch) { | ||
582 | return rawStreamAllValuesOfv1(partialMatch.toArray()).collect(Collectors.toSet()); | ||
583 | } | ||
584 | |||
585 | /** | ||
586 | * Retrieve the set of values that occur in matches for v1. | ||
587 | * @return the Set of all values or empty set if there are no matches | ||
588 | * | ||
589 | */ | ||
590 | public Set<Vertex> getAllValuesOfv1(final Synchronization pS, final Vertex pV2) { | ||
591 | return rawStreamAllValuesOfv1(new Object[]{pS, null, pV2}).collect(Collectors.toSet()); | ||
592 | } | ||
593 | |||
594 | /** | ||
595 | * Retrieve the set of values that occur in matches for v2. | ||
596 | * @return the Set of all values or empty set if there are no matches | ||
597 | * | ||
598 | */ | ||
599 | protected Stream<Vertex> rawStreamAllValuesOfv2(final Object[] parameters) { | ||
600 | return rawStreamAllValues(POSITION_V2, parameters).map(Vertex.class::cast); | ||
601 | } | ||
602 | |||
603 | /** | ||
604 | * Retrieve the set of values that occur in matches for v2. | ||
605 | * @return the Set of all values or empty set if there are no matches | ||
606 | * | ||
607 | */ | ||
608 | public Set<Vertex> getAllValuesOfv2() { | ||
609 | return rawStreamAllValuesOfv2(emptyArray()).collect(Collectors.toSet()); | ||
610 | } | ||
611 | |||
612 | /** | ||
613 | * Retrieve the set of values that occur in matches for v2. | ||
614 | * @return the Set of all values or empty set if there are no matches | ||
615 | * | ||
616 | */ | ||
617 | public Stream<Vertex> streamAllValuesOfv2() { | ||
618 | return rawStreamAllValuesOfv2(emptyArray()); | ||
619 | } | ||
620 | |||
621 | /** | ||
622 | * Retrieve the set of values that occur in matches for v2. | ||
623 | * </p> | ||
624 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
625 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
626 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
627 | * | ||
628 | * @return the Stream of all values or empty set if there are no matches | ||
629 | * | ||
630 | */ | ||
631 | public Stream<Vertex> streamAllValuesOfv2(final SynchronizedIncomingInSameRegion.Match partialMatch) { | ||
632 | return rawStreamAllValuesOfv2(partialMatch.toArray()); | ||
633 | } | ||
634 | |||
635 | /** | ||
636 | * Retrieve the set of values that occur in matches for v2. | ||
637 | * </p> | ||
638 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
639 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
640 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
641 | * | ||
642 | * @return the Stream of all values or empty set if there are no matches | ||
643 | * | ||
644 | */ | ||
645 | public Stream<Vertex> streamAllValuesOfv2(final Synchronization pS, final Vertex pV1) { | ||
646 | return rawStreamAllValuesOfv2(new Object[]{pS, pV1, null}); | ||
647 | } | ||
648 | |||
649 | /** | ||
650 | * Retrieve the set of values that occur in matches for v2. | ||
651 | * @return the Set of all values or empty set if there are no matches | ||
652 | * | ||
653 | */ | ||
654 | public Set<Vertex> getAllValuesOfv2(final SynchronizedIncomingInSameRegion.Match partialMatch) { | ||
655 | return rawStreamAllValuesOfv2(partialMatch.toArray()).collect(Collectors.toSet()); | ||
656 | } | ||
657 | |||
658 | /** | ||
659 | * Retrieve the set of values that occur in matches for v2. | ||
660 | * @return the Set of all values or empty set if there are no matches | ||
661 | * | ||
662 | */ | ||
663 | public Set<Vertex> getAllValuesOfv2(final Synchronization pS, final Vertex pV1) { | ||
664 | return rawStreamAllValuesOfv2(new Object[]{pS, pV1, null}).collect(Collectors.toSet()); | ||
665 | } | ||
666 | |||
667 | @Override | ||
668 | protected SynchronizedIncomingInSameRegion.Match tupleToMatch(final Tuple t) { | ||
669 | try { | ||
670 | return SynchronizedIncomingInSameRegion.Match.newMatch((Synchronization) t.get(POSITION_S), (Vertex) t.get(POSITION_V1), (Vertex) t.get(POSITION_V2)); | ||
671 | } catch(ClassCastException e) { | ||
672 | LOGGER.error("Element(s) in tuple not properly typed!",e); | ||
673 | return null; | ||
674 | } | ||
675 | } | ||
676 | |||
677 | @Override | ||
678 | protected SynchronizedIncomingInSameRegion.Match arrayToMatch(final Object[] match) { | ||
679 | try { | ||
680 | return SynchronizedIncomingInSameRegion.Match.newMatch((Synchronization) match[POSITION_S], (Vertex) match[POSITION_V1], (Vertex) match[POSITION_V2]); | ||
681 | } catch(ClassCastException e) { | ||
682 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
683 | return null; | ||
684 | } | ||
685 | } | ||
686 | |||
687 | @Override | ||
688 | protected SynchronizedIncomingInSameRegion.Match arrayToMatchMutable(final Object[] match) { | ||
689 | try { | ||
690 | return SynchronizedIncomingInSameRegion.Match.newMutableMatch((Synchronization) match[POSITION_S], (Vertex) match[POSITION_V1], (Vertex) match[POSITION_V2]); | ||
691 | } catch(ClassCastException e) { | ||
692 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
693 | return null; | ||
694 | } | ||
695 | } | ||
696 | |||
697 | /** | ||
698 | * @return the singleton instance of the query specification of this pattern | ||
699 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
700 | * | ||
701 | */ | ||
702 | public static IQuerySpecification<SynchronizedIncomingInSameRegion.Matcher> querySpecification() { | ||
703 | return SynchronizedIncomingInSameRegion.instance(); | ||
704 | } | ||
705 | } | ||
706 | |||
707 | private SynchronizedIncomingInSameRegion() { | ||
708 | super(GeneratedPQuery.INSTANCE); | ||
709 | } | ||
710 | |||
711 | /** | ||
712 | * @return the singleton instance of the query specification | ||
713 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
714 | * | ||
715 | */ | ||
716 | public static SynchronizedIncomingInSameRegion instance() { | ||
717 | try{ | ||
718 | return LazyHolder.INSTANCE; | ||
719 | } catch (ExceptionInInitializerError err) { | ||
720 | throw processInitializerError(err); | ||
721 | } | ||
722 | } | ||
723 | |||
724 | @Override | ||
725 | protected SynchronizedIncomingInSameRegion.Matcher instantiate(final ViatraQueryEngine engine) { | ||
726 | return SynchronizedIncomingInSameRegion.Matcher.on(engine); | ||
727 | } | ||
728 | |||
729 | @Override | ||
730 | public SynchronizedIncomingInSameRegion.Matcher instantiate() { | ||
731 | return SynchronizedIncomingInSameRegion.Matcher.create(); | ||
732 | } | ||
733 | |||
734 | @Override | ||
735 | public SynchronizedIncomingInSameRegion.Match newEmptyMatch() { | ||
736 | return SynchronizedIncomingInSameRegion.Match.newEmptyMatch(); | ||
737 | } | ||
738 | |||
739 | @Override | ||
740 | public SynchronizedIncomingInSameRegion.Match newMatch(final Object... parameters) { | ||
741 | return SynchronizedIncomingInSameRegion.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization) parameters[0], (ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex) parameters[1], (ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex) parameters[2]); | ||
742 | } | ||
743 | |||
744 | /** | ||
745 | * Inner class allowing the singleton instance of {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedIncomingInSameRegion (visibility: PUBLIC, simpleName: SynchronizedIncomingInSameRegion, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedIncomingInSameRegion, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created | ||
746 | * <b>not</b> at the class load time of the outer class, | ||
747 | * but rather at the first call to {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedIncomingInSameRegion (visibility: PUBLIC, simpleName: SynchronizedIncomingInSameRegion, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedIncomingInSameRegion, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. | ||
748 | * | ||
749 | * <p> This workaround is required e.g. to support recursion. | ||
750 | * | ||
751 | */ | ||
752 | private static class LazyHolder { | ||
753 | private final static SynchronizedIncomingInSameRegion INSTANCE = new SynchronizedIncomingInSameRegion(); | ||
754 | |||
755 | /** | ||
756 | * Statically initializes the query specification <b>after</b> the field {@link #INSTANCE} is assigned. | ||
757 | * This initialization order is required to support indirect recursion. | ||
758 | * | ||
759 | * <p> The static initializer is defined using a helper field to work around limitations of the code generator. | ||
760 | * | ||
761 | */ | ||
762 | private final static Object STATIC_INITIALIZER = ensureInitialized(); | ||
763 | |||
764 | public static Object ensureInitialized() { | ||
765 | INSTANCE.ensureInitializedInternal(); | ||
766 | return null; | ||
767 | } | ||
768 | } | ||
769 | |||
770 | private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { | ||
771 | private final static SynchronizedIncomingInSameRegion.GeneratedPQuery INSTANCE = new GeneratedPQuery(); | ||
772 | |||
773 | private final PParameter parameter_s = new PParameter("s", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Synchronization")), PParameterDirection.INOUT); | ||
774 | |||
775 | private final PParameter parameter_v1 = new PParameter("v1", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Vertex")), PParameterDirection.INOUT); | ||
776 | |||
777 | private final PParameter parameter_v2 = new PParameter("v2", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Vertex")), PParameterDirection.INOUT); | ||
778 | |||
779 | private final List<PParameter> parameters = Arrays.asList(parameter_s, parameter_v1, parameter_v2); | ||
780 | |||
781 | private GeneratedPQuery() { | ||
782 | super(PVisibility.PUBLIC); | ||
783 | } | ||
784 | |||
785 | @Override | ||
786 | public String getFullyQualifiedName() { | ||
787 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedIncomingInSameRegion"; | ||
788 | } | ||
789 | |||
790 | @Override | ||
791 | public List<String> getParameterNames() { | ||
792 | return Arrays.asList("s","v1","v2"); | ||
793 | } | ||
794 | |||
795 | @Override | ||
796 | public List<PParameter> getParameters() { | ||
797 | return parameters; | ||
798 | } | ||
799 | |||
800 | @Override | ||
801 | public Set<PBody> doGetContainedBodies() { | ||
802 | setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); | ||
803 | Set<PBody> bodies = new LinkedHashSet<>(); | ||
804 | { | ||
805 | PBody body = new PBody(this); | ||
806 | PVariable var_s = body.getOrCreateVariableByName("s"); | ||
807 | PVariable var_v1 = body.getOrCreateVariableByName("v1"); | ||
808 | PVariable var_v2 = body.getOrCreateVariableByName("v2"); | ||
809 | PVariable var_t1 = body.getOrCreateVariableByName("t1"); | ||
810 | PVariable var_t2 = body.getOrCreateVariableByName("t2"); | ||
811 | PVariable var_r = body.getOrCreateVariableByName("r"); | ||
812 | new TypeConstraint(body, Tuples.flatTupleOf(var_s), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Synchronization"))); | ||
813 | new TypeConstraint(body, Tuples.flatTupleOf(var_v1), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); | ||
814 | new TypeConstraint(body, Tuples.flatTupleOf(var_v2), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); | ||
815 | body.setSymbolicParameters(Arrays.<ExportedParameter>asList( | ||
816 | new ExportedParameter(body, var_s, parameter_s), | ||
817 | new ExportedParameter(body, var_v1, parameter_v1), | ||
818 | new ExportedParameter(body, var_v2, parameter_v2) | ||
819 | )); | ||
820 | // find transition(t1, v1, s) | ||
821 | new PositivePatternCall(body, Tuples.flatTupleOf(var_t1, var_v1, var_s), Transition.instance().getInternalQueryRepresentation()); | ||
822 | // find transition(t2, v2, s) | ||
823 | new PositivePatternCall(body, Tuples.flatTupleOf(var_t2, var_v2, var_s), Transition.instance().getInternalQueryRepresentation()); | ||
824 | // t1!=t2 | ||
825 | new Inequality(body, var_t1, var_t2); | ||
826 | // Region.vertices(r, v1) | ||
827 | new TypeConstraint(body, Tuples.flatTupleOf(var_r), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Region"))); | ||
828 | PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); | ||
829 | new TypeConstraint(body, Tuples.flatTupleOf(var_r, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Region", "vertices"))); | ||
830 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); | ||
831 | new Equality(body, var__virtual_0_, var_v1); | ||
832 | // Region.vertices(r, v2) | ||
833 | new TypeConstraint(body, Tuples.flatTupleOf(var_r), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Region"))); | ||
834 | PVariable var__virtual_1_ = body.getOrCreateVariableByName(".virtual{1}"); | ||
835 | new TypeConstraint(body, Tuples.flatTupleOf(var_r, var__virtual_1_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Region", "vertices"))); | ||
836 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_1_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); | ||
837 | new Equality(body, var__virtual_1_, var_v2); | ||
838 | bodies.add(body); | ||
839 | } | ||
840 | { | ||
841 | PBody body = new PBody(this); | ||
842 | PVariable var_s = body.getOrCreateVariableByName("s"); | ||
843 | PVariable var_v1 = body.getOrCreateVariableByName("v1"); | ||
844 | PVariable var_v2 = body.getOrCreateVariableByName("v2"); | ||
845 | PVariable var_t1 = body.getOrCreateVariableByName("t1"); | ||
846 | PVariable var_t2 = body.getOrCreateVariableByName("t2"); | ||
847 | PVariable var_r = body.getOrCreateVariableByName("r"); | ||
848 | new TypeConstraint(body, Tuples.flatTupleOf(var_s), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Synchronization"))); | ||
849 | new TypeConstraint(body, Tuples.flatTupleOf(var_v1), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); | ||
850 | new TypeConstraint(body, Tuples.flatTupleOf(var_v2), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); | ||
851 | body.setSymbolicParameters(Arrays.<ExportedParameter>asList( | ||
852 | new ExportedParameter(body, var_s, parameter_s), | ||
853 | new ExportedParameter(body, var_v1, parameter_v1), | ||
854 | new ExportedParameter(body, var_v2, parameter_v2) | ||
855 | )); | ||
856 | // find transition(t1, s, v1) | ||
857 | new PositivePatternCall(body, Tuples.flatTupleOf(var_t1, var_s, var_v1), Transition.instance().getInternalQueryRepresentation()); | ||
858 | // find transition(t2, s, v2) | ||
859 | new PositivePatternCall(body, Tuples.flatTupleOf(var_t2, var_s, var_v2), Transition.instance().getInternalQueryRepresentation()); | ||
860 | // t1!=t2 | ||
861 | new Inequality(body, var_t1, var_t2); | ||
862 | // Region.vertices(r, v1) | ||
863 | new TypeConstraint(body, Tuples.flatTupleOf(var_r), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Region"))); | ||
864 | PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); | ||
865 | new TypeConstraint(body, Tuples.flatTupleOf(var_r, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Region", "vertices"))); | ||
866 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); | ||
867 | new Equality(body, var__virtual_0_, var_v1); | ||
868 | // Region.vertices(r, v2) | ||
869 | new TypeConstraint(body, Tuples.flatTupleOf(var_r), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Region"))); | ||
870 | PVariable var__virtual_1_ = body.getOrCreateVariableByName(".virtual{1}"); | ||
871 | new TypeConstraint(body, Tuples.flatTupleOf(var_r, var__virtual_1_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Region", "vertices"))); | ||
872 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_1_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); | ||
873 | new Equality(body, var__virtual_1_, var_v2); | ||
874 | bodies.add(body); | ||
875 | } | ||
876 | { | ||
877 | PAnnotation annotation = new PAnnotation("Constraint"); | ||
878 | annotation.addAttribute("severity", "error"); | ||
879 | annotation.addAttribute("message", "error"); | ||
880 | annotation.addAttribute("key", Arrays.asList(new Object[] { | ||
881 | new ParameterReference("s") | ||
882 | })); | ||
883 | addAnnotation(annotation); | ||
884 | } | ||
885 | return bodies; | ||
886 | } | ||
887 | } | ||
888 | } | ||
diff --git a/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/SynchronizedRegionDoesNotHaveMultipleRegions.java b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/SynchronizedRegionDoesNotHaveMultipleRegions.java new file mode 100644 index 00000000..28eecf9c --- /dev/null +++ b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/SynchronizedRegionDoesNotHaveMultipleRegions.java | |||
@@ -0,0 +1,744 @@ | |||
1 | /** | ||
2 | * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql | ||
3 | */ | ||
4 | package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; | ||
5 | |||
6 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization; | ||
7 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex; | ||
8 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.Child; | ||
9 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.HasMultipleRegions; | ||
10 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.Transition; | ||
11 | import java.util.Arrays; | ||
12 | import java.util.Collection; | ||
13 | import java.util.LinkedHashSet; | ||
14 | import java.util.List; | ||
15 | import java.util.Objects; | ||
16 | import java.util.Optional; | ||
17 | import java.util.Set; | ||
18 | import java.util.function.Consumer; | ||
19 | import java.util.stream.Collectors; | ||
20 | import java.util.stream.Stream; | ||
21 | import org.apache.log4j.Logger; | ||
22 | import org.eclipse.emf.ecore.EClass; | ||
23 | import org.eclipse.viatra.query.runtime.api.IPatternMatch; | ||
24 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification; | ||
25 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; | ||
26 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; | ||
27 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; | ||
28 | import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; | ||
29 | import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; | ||
30 | import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; | ||
31 | import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; | ||
32 | import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; | ||
33 | import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; | ||
34 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; | ||
35 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; | ||
36 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; | ||
37 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.NegativePatternCall; | ||
38 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall; | ||
39 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; | ||
40 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; | ||
41 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; | ||
42 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; | ||
43 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; | ||
44 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | ||
45 | import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; | ||
46 | |||
47 | /** | ||
48 | * A pattern-specific query specification that can instantiate Matcher in a type-safe way. | ||
49 | * | ||
50 | * <p>Original source: | ||
51 | * <code><pre> | ||
52 | * {@literal @}Constraint(severity="error", message="error", key = {s}) | ||
53 | * pattern SynchronizedRegionDoesNotHaveMultipleRegions(s : Synchronization, v : Vertex) { | ||
54 | * find transition(_, v, s); | ||
55 | * find child(c,v); | ||
56 | * neg find hasMultipleRegions(c); | ||
57 | * } or { | ||
58 | * find transition(_, s, v); | ||
59 | * find child(c,v); | ||
60 | * neg find hasMultipleRegions(c); | ||
61 | * } | ||
62 | * </pre></code> | ||
63 | * | ||
64 | * @see Matcher | ||
65 | * @see Match | ||
66 | * | ||
67 | */ | ||
68 | @SuppressWarnings("all") | ||
69 | public final class SynchronizedRegionDoesNotHaveMultipleRegions extends BaseGeneratedEMFQuerySpecification<SynchronizedRegionDoesNotHaveMultipleRegions.Matcher> { | ||
70 | /** | ||
71 | * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedRegionDoesNotHaveMultipleRegions pattern, | ||
72 | * to be used in conjunction with {@link Matcher}. | ||
73 | * | ||
74 | * <p>Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. | ||
75 | * Each instance is a (possibly partial) substitution of pattern parameters, | ||
76 | * usable to represent a match of the pattern in the result of a query, | ||
77 | * or to specify the bound (fixed) input parameters when issuing a query. | ||
78 | * | ||
79 | * @see Matcher | ||
80 | * | ||
81 | */ | ||
82 | public static abstract class Match extends BasePatternMatch { | ||
83 | private Synchronization fS; | ||
84 | |||
85 | private Vertex fV; | ||
86 | |||
87 | private static List<String> parameterNames = makeImmutableList("s", "v"); | ||
88 | |||
89 | private Match(final Synchronization pS, final Vertex pV) { | ||
90 | this.fS = pS; | ||
91 | this.fV = pV; | ||
92 | } | ||
93 | |||
94 | @Override | ||
95 | public Object get(final String parameterName) { | ||
96 | if ("s".equals(parameterName)) return this.fS; | ||
97 | if ("v".equals(parameterName)) return this.fV; | ||
98 | return null; | ||
99 | } | ||
100 | |||
101 | public Synchronization getS() { | ||
102 | return this.fS; | ||
103 | } | ||
104 | |||
105 | public Vertex getV() { | ||
106 | return this.fV; | ||
107 | } | ||
108 | |||
109 | @Override | ||
110 | public boolean set(final String parameterName, final Object newValue) { | ||
111 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
112 | if ("s".equals(parameterName) ) { | ||
113 | this.fS = (Synchronization) newValue; | ||
114 | return true; | ||
115 | } | ||
116 | if ("v".equals(parameterName) ) { | ||
117 | this.fV = (Vertex) newValue; | ||
118 | return true; | ||
119 | } | ||
120 | return false; | ||
121 | } | ||
122 | |||
123 | public void setS(final Synchronization pS) { | ||
124 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
125 | this.fS = pS; | ||
126 | } | ||
127 | |||
128 | public void setV(final Vertex pV) { | ||
129 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
130 | this.fV = pV; | ||
131 | } | ||
132 | |||
133 | @Override | ||
134 | public String patternName() { | ||
135 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedRegionDoesNotHaveMultipleRegions"; | ||
136 | } | ||
137 | |||
138 | @Override | ||
139 | public List<String> parameterNames() { | ||
140 | return SynchronizedRegionDoesNotHaveMultipleRegions.Match.parameterNames; | ||
141 | } | ||
142 | |||
143 | @Override | ||
144 | public Object[] toArray() { | ||
145 | return new Object[]{fS, fV}; | ||
146 | } | ||
147 | |||
148 | @Override | ||
149 | public SynchronizedRegionDoesNotHaveMultipleRegions.Match toImmutable() { | ||
150 | return isMutable() ? newMatch(fS, fV) : this; | ||
151 | } | ||
152 | |||
153 | @Override | ||
154 | public String prettyPrint() { | ||
155 | StringBuilder result = new StringBuilder(); | ||
156 | result.append("\"s\"=" + prettyPrintValue(fS) + ", "); | ||
157 | result.append("\"v\"=" + prettyPrintValue(fV)); | ||
158 | return result.toString(); | ||
159 | } | ||
160 | |||
161 | @Override | ||
162 | public int hashCode() { | ||
163 | return Objects.hash(fS, fV); | ||
164 | } | ||
165 | |||
166 | @Override | ||
167 | public boolean equals(final Object obj) { | ||
168 | if (this == obj) | ||
169 | return true; | ||
170 | if (obj == null) { | ||
171 | return false; | ||
172 | } | ||
173 | if ((obj instanceof SynchronizedRegionDoesNotHaveMultipleRegions.Match)) { | ||
174 | SynchronizedRegionDoesNotHaveMultipleRegions.Match other = (SynchronizedRegionDoesNotHaveMultipleRegions.Match) obj; | ||
175 | return Objects.equals(fS, other.fS) && Objects.equals(fV, other.fV); | ||
176 | } else { | ||
177 | // this should be infrequent | ||
178 | if (!(obj instanceof IPatternMatch)) { | ||
179 | return false; | ||
180 | } | ||
181 | IPatternMatch otherSig = (IPatternMatch) obj; | ||
182 | return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); | ||
183 | } | ||
184 | } | ||
185 | |||
186 | @Override | ||
187 | public SynchronizedRegionDoesNotHaveMultipleRegions specification() { | ||
188 | return SynchronizedRegionDoesNotHaveMultipleRegions.instance(); | ||
189 | } | ||
190 | |||
191 | /** | ||
192 | * Returns an empty, mutable match. | ||
193 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
194 | * | ||
195 | * @return the empty match. | ||
196 | * | ||
197 | */ | ||
198 | public static SynchronizedRegionDoesNotHaveMultipleRegions.Match newEmptyMatch() { | ||
199 | return new Mutable(null, null); | ||
200 | } | ||
201 | |||
202 | /** | ||
203 | * Returns a mutable (partial) match. | ||
204 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
205 | * | ||
206 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
207 | * @param pV the fixed value of pattern parameter v, or null if not bound. | ||
208 | * @return the new, mutable (partial) match object. | ||
209 | * | ||
210 | */ | ||
211 | public static SynchronizedRegionDoesNotHaveMultipleRegions.Match newMutableMatch(final Synchronization pS, final Vertex pV) { | ||
212 | return new Mutable(pS, pV); | ||
213 | } | ||
214 | |||
215 | /** | ||
216 | * Returns a new (partial) match. | ||
217 | * This can be used e.g. to call the matcher with a partial match. | ||
218 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
219 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
220 | * @param pV the fixed value of pattern parameter v, or null if not bound. | ||
221 | * @return the (partial) match object. | ||
222 | * | ||
223 | */ | ||
224 | public static SynchronizedRegionDoesNotHaveMultipleRegions.Match newMatch(final Synchronization pS, final Vertex pV) { | ||
225 | return new Immutable(pS, pV); | ||
226 | } | ||
227 | |||
228 | private static final class Mutable extends SynchronizedRegionDoesNotHaveMultipleRegions.Match { | ||
229 | Mutable(final Synchronization pS, final Vertex pV) { | ||
230 | super(pS, pV); | ||
231 | } | ||
232 | |||
233 | @Override | ||
234 | public boolean isMutable() { | ||
235 | return true; | ||
236 | } | ||
237 | } | ||
238 | |||
239 | private static final class Immutable extends SynchronizedRegionDoesNotHaveMultipleRegions.Match { | ||
240 | Immutable(final Synchronization pS, final Vertex pV) { | ||
241 | super(pS, pV); | ||
242 | } | ||
243 | |||
244 | @Override | ||
245 | public boolean isMutable() { | ||
246 | return false; | ||
247 | } | ||
248 | } | ||
249 | } | ||
250 | |||
251 | /** | ||
252 | * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedRegionDoesNotHaveMultipleRegions pattern, | ||
253 | * providing pattern-specific query methods. | ||
254 | * | ||
255 | * <p>Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, | ||
256 | * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. | ||
257 | * | ||
258 | * <p>Matches of the pattern will be represented as {@link Match}. | ||
259 | * | ||
260 | * <p>Original source: | ||
261 | * <code><pre> | ||
262 | * {@literal @}Constraint(severity="error", message="error", key = {s}) | ||
263 | * pattern SynchronizedRegionDoesNotHaveMultipleRegions(s : Synchronization, v : Vertex) { | ||
264 | * find transition(_, v, s); | ||
265 | * find child(c,v); | ||
266 | * neg find hasMultipleRegions(c); | ||
267 | * } or { | ||
268 | * find transition(_, s, v); | ||
269 | * find child(c,v); | ||
270 | * neg find hasMultipleRegions(c); | ||
271 | * } | ||
272 | * </pre></code> | ||
273 | * | ||
274 | * @see Match | ||
275 | * @see SynchronizedRegionDoesNotHaveMultipleRegions | ||
276 | * | ||
277 | */ | ||
278 | public static class Matcher extends BaseMatcher<SynchronizedRegionDoesNotHaveMultipleRegions.Match> { | ||
279 | /** | ||
280 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
281 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
282 | * | ||
283 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
284 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
285 | * | ||
286 | */ | ||
287 | public static SynchronizedRegionDoesNotHaveMultipleRegions.Matcher on(final ViatraQueryEngine engine) { | ||
288 | // check if matcher already exists | ||
289 | Matcher matcher = engine.getExistingMatcher(querySpecification()); | ||
290 | if (matcher == null) { | ||
291 | matcher = (Matcher)engine.getMatcher(querySpecification()); | ||
292 | } | ||
293 | return matcher; | ||
294 | } | ||
295 | |||
296 | /** | ||
297 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
298 | * @return an initialized matcher | ||
299 | * @noreference This method is for internal matcher initialization by the framework, do not call it manually. | ||
300 | * | ||
301 | */ | ||
302 | public static SynchronizedRegionDoesNotHaveMultipleRegions.Matcher create() { | ||
303 | return new Matcher(); | ||
304 | } | ||
305 | |||
306 | private final static int POSITION_S = 0; | ||
307 | |||
308 | private final static int POSITION_V = 1; | ||
309 | |||
310 | private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(SynchronizedRegionDoesNotHaveMultipleRegions.Matcher.class); | ||
311 | |||
312 | /** | ||
313 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
314 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
315 | * | ||
316 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
317 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
318 | * | ||
319 | */ | ||
320 | private Matcher() { | ||
321 | super(querySpecification()); | ||
322 | } | ||
323 | |||
324 | /** | ||
325 | * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. | ||
326 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
327 | * @param pV the fixed value of pattern parameter v, or null if not bound. | ||
328 | * @return matches represented as a Match object. | ||
329 | * | ||
330 | */ | ||
331 | public Collection<SynchronizedRegionDoesNotHaveMultipleRegions.Match> getAllMatches(final Synchronization pS, final Vertex pV) { | ||
332 | return rawStreamAllMatches(new Object[]{pS, pV}).collect(Collectors.toSet()); | ||
333 | } | ||
334 | |||
335 | /** | ||
336 | * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. | ||
337 | * </p> | ||
338 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
339 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
340 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
341 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
342 | * @param pV the fixed value of pattern parameter v, or null if not bound. | ||
343 | * @return a stream of matches represented as a Match object. | ||
344 | * | ||
345 | */ | ||
346 | public Stream<SynchronizedRegionDoesNotHaveMultipleRegions.Match> streamAllMatches(final Synchronization pS, final Vertex pV) { | ||
347 | return rawStreamAllMatches(new Object[]{pS, pV}); | ||
348 | } | ||
349 | |||
350 | /** | ||
351 | * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
352 | * Neither determinism nor randomness of selection is guaranteed. | ||
353 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
354 | * @param pV the fixed value of pattern parameter v, or null if not bound. | ||
355 | * @return a match represented as a Match object, or null if no match is found. | ||
356 | * | ||
357 | */ | ||
358 | public Optional<SynchronizedRegionDoesNotHaveMultipleRegions.Match> getOneArbitraryMatch(final Synchronization pS, final Vertex pV) { | ||
359 | return rawGetOneArbitraryMatch(new Object[]{pS, pV}); | ||
360 | } | ||
361 | |||
362 | /** | ||
363 | * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, | ||
364 | * under any possible substitution of the unspecified parameters (if any). | ||
365 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
366 | * @param pV the fixed value of pattern parameter v, or null if not bound. | ||
367 | * @return true if the input is a valid (partial) match of the pattern. | ||
368 | * | ||
369 | */ | ||
370 | public boolean hasMatch(final Synchronization pS, final Vertex pV) { | ||
371 | return rawHasMatch(new Object[]{pS, pV}); | ||
372 | } | ||
373 | |||
374 | /** | ||
375 | * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. | ||
376 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
377 | * @param pV the fixed value of pattern parameter v, or null if not bound. | ||
378 | * @return the number of pattern matches found. | ||
379 | * | ||
380 | */ | ||
381 | public int countMatches(final Synchronization pS, final Vertex pV) { | ||
382 | return rawCountMatches(new Object[]{pS, pV}); | ||
383 | } | ||
384 | |||
385 | /** | ||
386 | * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
387 | * Neither determinism nor randomness of selection is guaranteed. | ||
388 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
389 | * @param pV the fixed value of pattern parameter v, or null if not bound. | ||
390 | * @param processor the action that will process the selected match. | ||
391 | * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked | ||
392 | * | ||
393 | */ | ||
394 | public boolean forOneArbitraryMatch(final Synchronization pS, final Vertex pV, final Consumer<? super SynchronizedRegionDoesNotHaveMultipleRegions.Match> processor) { | ||
395 | return rawForOneArbitraryMatch(new Object[]{pS, pV}, processor); | ||
396 | } | ||
397 | |||
398 | /** | ||
399 | * Returns a new (partial) match. | ||
400 | * This can be used e.g. to call the matcher with a partial match. | ||
401 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
402 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
403 | * @param pV the fixed value of pattern parameter v, or null if not bound. | ||
404 | * @return the (partial) match object. | ||
405 | * | ||
406 | */ | ||
407 | public SynchronizedRegionDoesNotHaveMultipleRegions.Match newMatch(final Synchronization pS, final Vertex pV) { | ||
408 | return SynchronizedRegionDoesNotHaveMultipleRegions.Match.newMatch(pS, pV); | ||
409 | } | ||
410 | |||
411 | /** | ||
412 | * Retrieve the set of values that occur in matches for s. | ||
413 | * @return the Set of all values or empty set if there are no matches | ||
414 | * | ||
415 | */ | ||
416 | protected Stream<Synchronization> rawStreamAllValuesOfs(final Object[] parameters) { | ||
417 | return rawStreamAllValues(POSITION_S, parameters).map(Synchronization.class::cast); | ||
418 | } | ||
419 | |||
420 | /** | ||
421 | * Retrieve the set of values that occur in matches for s. | ||
422 | * @return the Set of all values or empty set if there are no matches | ||
423 | * | ||
424 | */ | ||
425 | public Set<Synchronization> getAllValuesOfs() { | ||
426 | return rawStreamAllValuesOfs(emptyArray()).collect(Collectors.toSet()); | ||
427 | } | ||
428 | |||
429 | /** | ||
430 | * Retrieve the set of values that occur in matches for s. | ||
431 | * @return the Set of all values or empty set if there are no matches | ||
432 | * | ||
433 | */ | ||
434 | public Stream<Synchronization> streamAllValuesOfs() { | ||
435 | return rawStreamAllValuesOfs(emptyArray()); | ||
436 | } | ||
437 | |||
438 | /** | ||
439 | * Retrieve the set of values that occur in matches for s. | ||
440 | * </p> | ||
441 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
442 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
443 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
444 | * | ||
445 | * @return the Stream of all values or empty set if there are no matches | ||
446 | * | ||
447 | */ | ||
448 | public Stream<Synchronization> streamAllValuesOfs(final SynchronizedRegionDoesNotHaveMultipleRegions.Match partialMatch) { | ||
449 | return rawStreamAllValuesOfs(partialMatch.toArray()); | ||
450 | } | ||
451 | |||
452 | /** | ||
453 | * Retrieve the set of values that occur in matches for s. | ||
454 | * </p> | ||
455 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
456 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
457 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
458 | * | ||
459 | * @return the Stream of all values or empty set if there are no matches | ||
460 | * | ||
461 | */ | ||
462 | public Stream<Synchronization> streamAllValuesOfs(final Vertex pV) { | ||
463 | return rawStreamAllValuesOfs(new Object[]{null, pV}); | ||
464 | } | ||
465 | |||
466 | /** | ||
467 | * Retrieve the set of values that occur in matches for s. | ||
468 | * @return the Set of all values or empty set if there are no matches | ||
469 | * | ||
470 | */ | ||
471 | public Set<Synchronization> getAllValuesOfs(final SynchronizedRegionDoesNotHaveMultipleRegions.Match partialMatch) { | ||
472 | return rawStreamAllValuesOfs(partialMatch.toArray()).collect(Collectors.toSet()); | ||
473 | } | ||
474 | |||
475 | /** | ||
476 | * Retrieve the set of values that occur in matches for s. | ||
477 | * @return the Set of all values or empty set if there are no matches | ||
478 | * | ||
479 | */ | ||
480 | public Set<Synchronization> getAllValuesOfs(final Vertex pV) { | ||
481 | return rawStreamAllValuesOfs(new Object[]{null, pV}).collect(Collectors.toSet()); | ||
482 | } | ||
483 | |||
484 | /** | ||
485 | * Retrieve the set of values that occur in matches for v. | ||
486 | * @return the Set of all values or empty set if there are no matches | ||
487 | * | ||
488 | */ | ||
489 | protected Stream<Vertex> rawStreamAllValuesOfv(final Object[] parameters) { | ||
490 | return rawStreamAllValues(POSITION_V, parameters).map(Vertex.class::cast); | ||
491 | } | ||
492 | |||
493 | /** | ||
494 | * Retrieve the set of values that occur in matches for v. | ||
495 | * @return the Set of all values or empty set if there are no matches | ||
496 | * | ||
497 | */ | ||
498 | public Set<Vertex> getAllValuesOfv() { | ||
499 | return rawStreamAllValuesOfv(emptyArray()).collect(Collectors.toSet()); | ||
500 | } | ||
501 | |||
502 | /** | ||
503 | * Retrieve the set of values that occur in matches for v. | ||
504 | * @return the Set of all values or empty set if there are no matches | ||
505 | * | ||
506 | */ | ||
507 | public Stream<Vertex> streamAllValuesOfv() { | ||
508 | return rawStreamAllValuesOfv(emptyArray()); | ||
509 | } | ||
510 | |||
511 | /** | ||
512 | * Retrieve the set of values that occur in matches for v. | ||
513 | * </p> | ||
514 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
515 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
516 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
517 | * | ||
518 | * @return the Stream of all values or empty set if there are no matches | ||
519 | * | ||
520 | */ | ||
521 | public Stream<Vertex> streamAllValuesOfv(final SynchronizedRegionDoesNotHaveMultipleRegions.Match partialMatch) { | ||
522 | return rawStreamAllValuesOfv(partialMatch.toArray()); | ||
523 | } | ||
524 | |||
525 | /** | ||
526 | * Retrieve the set of values that occur in matches for v. | ||
527 | * </p> | ||
528 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
529 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
530 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
531 | * | ||
532 | * @return the Stream of all values or empty set if there are no matches | ||
533 | * | ||
534 | */ | ||
535 | public Stream<Vertex> streamAllValuesOfv(final Synchronization pS) { | ||
536 | return rawStreamAllValuesOfv(new Object[]{pS, null}); | ||
537 | } | ||
538 | |||
539 | /** | ||
540 | * Retrieve the set of values that occur in matches for v. | ||
541 | * @return the Set of all values or empty set if there are no matches | ||
542 | * | ||
543 | */ | ||
544 | public Set<Vertex> getAllValuesOfv(final SynchronizedRegionDoesNotHaveMultipleRegions.Match partialMatch) { | ||
545 | return rawStreamAllValuesOfv(partialMatch.toArray()).collect(Collectors.toSet()); | ||
546 | } | ||
547 | |||
548 | /** | ||
549 | * Retrieve the set of values that occur in matches for v. | ||
550 | * @return the Set of all values or empty set if there are no matches | ||
551 | * | ||
552 | */ | ||
553 | public Set<Vertex> getAllValuesOfv(final Synchronization pS) { | ||
554 | return rawStreamAllValuesOfv(new Object[]{pS, null}).collect(Collectors.toSet()); | ||
555 | } | ||
556 | |||
557 | @Override | ||
558 | protected SynchronizedRegionDoesNotHaveMultipleRegions.Match tupleToMatch(final Tuple t) { | ||
559 | try { | ||
560 | return SynchronizedRegionDoesNotHaveMultipleRegions.Match.newMatch((Synchronization) t.get(POSITION_S), (Vertex) t.get(POSITION_V)); | ||
561 | } catch(ClassCastException e) { | ||
562 | LOGGER.error("Element(s) in tuple not properly typed!",e); | ||
563 | return null; | ||
564 | } | ||
565 | } | ||
566 | |||
567 | @Override | ||
568 | protected SynchronizedRegionDoesNotHaveMultipleRegions.Match arrayToMatch(final Object[] match) { | ||
569 | try { | ||
570 | return SynchronizedRegionDoesNotHaveMultipleRegions.Match.newMatch((Synchronization) match[POSITION_S], (Vertex) match[POSITION_V]); | ||
571 | } catch(ClassCastException e) { | ||
572 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
573 | return null; | ||
574 | } | ||
575 | } | ||
576 | |||
577 | @Override | ||
578 | protected SynchronizedRegionDoesNotHaveMultipleRegions.Match arrayToMatchMutable(final Object[] match) { | ||
579 | try { | ||
580 | return SynchronizedRegionDoesNotHaveMultipleRegions.Match.newMutableMatch((Synchronization) match[POSITION_S], (Vertex) match[POSITION_V]); | ||
581 | } catch(ClassCastException e) { | ||
582 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
583 | return null; | ||
584 | } | ||
585 | } | ||
586 | |||
587 | /** | ||
588 | * @return the singleton instance of the query specification of this pattern | ||
589 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
590 | * | ||
591 | */ | ||
592 | public static IQuerySpecification<SynchronizedRegionDoesNotHaveMultipleRegions.Matcher> querySpecification() { | ||
593 | return SynchronizedRegionDoesNotHaveMultipleRegions.instance(); | ||
594 | } | ||
595 | } | ||
596 | |||
597 | private SynchronizedRegionDoesNotHaveMultipleRegions() { | ||
598 | super(GeneratedPQuery.INSTANCE); | ||
599 | } | ||
600 | |||
601 | /** | ||
602 | * @return the singleton instance of the query specification | ||
603 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
604 | * | ||
605 | */ | ||
606 | public static SynchronizedRegionDoesNotHaveMultipleRegions instance() { | ||
607 | try{ | ||
608 | return LazyHolder.INSTANCE; | ||
609 | } catch (ExceptionInInitializerError err) { | ||
610 | throw processInitializerError(err); | ||
611 | } | ||
612 | } | ||
613 | |||
614 | @Override | ||
615 | protected SynchronizedRegionDoesNotHaveMultipleRegions.Matcher instantiate(final ViatraQueryEngine engine) { | ||
616 | return SynchronizedRegionDoesNotHaveMultipleRegions.Matcher.on(engine); | ||
617 | } | ||
618 | |||
619 | @Override | ||
620 | public SynchronizedRegionDoesNotHaveMultipleRegions.Matcher instantiate() { | ||
621 | return SynchronizedRegionDoesNotHaveMultipleRegions.Matcher.create(); | ||
622 | } | ||
623 | |||
624 | @Override | ||
625 | public SynchronizedRegionDoesNotHaveMultipleRegions.Match newEmptyMatch() { | ||
626 | return SynchronizedRegionDoesNotHaveMultipleRegions.Match.newEmptyMatch(); | ||
627 | } | ||
628 | |||
629 | @Override | ||
630 | public SynchronizedRegionDoesNotHaveMultipleRegions.Match newMatch(final Object... parameters) { | ||
631 | return SynchronizedRegionDoesNotHaveMultipleRegions.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization) parameters[0], (ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex) parameters[1]); | ||
632 | } | ||
633 | |||
634 | /** | ||
635 | * Inner class allowing the singleton instance of {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedRegionDoesNotHaveMultipleRegions (visibility: PUBLIC, simpleName: SynchronizedRegionDoesNotHaveMultipleRegions, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedRegionDoesNotHaveMultipleRegions, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created | ||
636 | * <b>not</b> at the class load time of the outer class, | ||
637 | * but rather at the first call to {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedRegionDoesNotHaveMultipleRegions (visibility: PUBLIC, simpleName: SynchronizedRegionDoesNotHaveMultipleRegions, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedRegionDoesNotHaveMultipleRegions, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. | ||
638 | * | ||
639 | * <p> This workaround is required e.g. to support recursion. | ||
640 | * | ||
641 | */ | ||
642 | private static class LazyHolder { | ||
643 | private final static SynchronizedRegionDoesNotHaveMultipleRegions INSTANCE = new SynchronizedRegionDoesNotHaveMultipleRegions(); | ||
644 | |||
645 | /** | ||
646 | * Statically initializes the query specification <b>after</b> the field {@link #INSTANCE} is assigned. | ||
647 | * This initialization order is required to support indirect recursion. | ||
648 | * | ||
649 | * <p> The static initializer is defined using a helper field to work around limitations of the code generator. | ||
650 | * | ||
651 | */ | ||
652 | private final static Object STATIC_INITIALIZER = ensureInitialized(); | ||
653 | |||
654 | public static Object ensureInitialized() { | ||
655 | INSTANCE.ensureInitializedInternal(); | ||
656 | return null; | ||
657 | } | ||
658 | } | ||
659 | |||
660 | private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { | ||
661 | private final static SynchronizedRegionDoesNotHaveMultipleRegions.GeneratedPQuery INSTANCE = new GeneratedPQuery(); | ||
662 | |||
663 | private final PParameter parameter_s = new PParameter("s", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Synchronization")), PParameterDirection.INOUT); | ||
664 | |||
665 | private final PParameter parameter_v = new PParameter("v", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Vertex")), PParameterDirection.INOUT); | ||
666 | |||
667 | private final List<PParameter> parameters = Arrays.asList(parameter_s, parameter_v); | ||
668 | |||
669 | private GeneratedPQuery() { | ||
670 | super(PVisibility.PUBLIC); | ||
671 | } | ||
672 | |||
673 | @Override | ||
674 | public String getFullyQualifiedName() { | ||
675 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedRegionDoesNotHaveMultipleRegions"; | ||
676 | } | ||
677 | |||
678 | @Override | ||
679 | public List<String> getParameterNames() { | ||
680 | return Arrays.asList("s","v"); | ||
681 | } | ||
682 | |||
683 | @Override | ||
684 | public List<PParameter> getParameters() { | ||
685 | return parameters; | ||
686 | } | ||
687 | |||
688 | @Override | ||
689 | public Set<PBody> doGetContainedBodies() { | ||
690 | setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); | ||
691 | Set<PBody> bodies = new LinkedHashSet<>(); | ||
692 | { | ||
693 | PBody body = new PBody(this); | ||
694 | PVariable var_s = body.getOrCreateVariableByName("s"); | ||
695 | PVariable var_v = body.getOrCreateVariableByName("v"); | ||
696 | PVariable var___0_ = body.getOrCreateVariableByName("_<0>"); | ||
697 | PVariable var_c = body.getOrCreateVariableByName("c"); | ||
698 | new TypeConstraint(body, Tuples.flatTupleOf(var_s), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Synchronization"))); | ||
699 | new TypeConstraint(body, Tuples.flatTupleOf(var_v), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); | ||
700 | body.setSymbolicParameters(Arrays.<ExportedParameter>asList( | ||
701 | new ExportedParameter(body, var_s, parameter_s), | ||
702 | new ExportedParameter(body, var_v, parameter_v) | ||
703 | )); | ||
704 | // find transition(_, v, s) | ||
705 | new PositivePatternCall(body, Tuples.flatTupleOf(var___0_, var_v, var_s), Transition.instance().getInternalQueryRepresentation()); | ||
706 | // find child(c,v) | ||
707 | new PositivePatternCall(body, Tuples.flatTupleOf(var_c, var_v), Child.instance().getInternalQueryRepresentation()); | ||
708 | // neg find hasMultipleRegions(c) | ||
709 | new NegativePatternCall(body, Tuples.flatTupleOf(var_c), HasMultipleRegions.instance().getInternalQueryRepresentation()); | ||
710 | bodies.add(body); | ||
711 | } | ||
712 | { | ||
713 | PBody body = new PBody(this); | ||
714 | PVariable var_s = body.getOrCreateVariableByName("s"); | ||
715 | PVariable var_v = body.getOrCreateVariableByName("v"); | ||
716 | PVariable var___0_ = body.getOrCreateVariableByName("_<0>"); | ||
717 | PVariable var_c = body.getOrCreateVariableByName("c"); | ||
718 | new TypeConstraint(body, Tuples.flatTupleOf(var_s), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Synchronization"))); | ||
719 | new TypeConstraint(body, Tuples.flatTupleOf(var_v), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); | ||
720 | body.setSymbolicParameters(Arrays.<ExportedParameter>asList( | ||
721 | new ExportedParameter(body, var_s, parameter_s), | ||
722 | new ExportedParameter(body, var_v, parameter_v) | ||
723 | )); | ||
724 | // find transition(_, s, v) | ||
725 | new PositivePatternCall(body, Tuples.flatTupleOf(var___0_, var_s, var_v), Transition.instance().getInternalQueryRepresentation()); | ||
726 | // find child(c,v) | ||
727 | new PositivePatternCall(body, Tuples.flatTupleOf(var_c, var_v), Child.instance().getInternalQueryRepresentation()); | ||
728 | // neg find hasMultipleRegions(c) | ||
729 | new NegativePatternCall(body, Tuples.flatTupleOf(var_c), HasMultipleRegions.instance().getInternalQueryRepresentation()); | ||
730 | bodies.add(body); | ||
731 | } | ||
732 | { | ||
733 | PAnnotation annotation = new PAnnotation("Constraint"); | ||
734 | annotation.addAttribute("severity", "error"); | ||
735 | annotation.addAttribute("message", "error"); | ||
736 | annotation.addAttribute("key", Arrays.asList(new Object[] { | ||
737 | new ParameterReference("s") | ||
738 | })); | ||
739 | addAnnotation(annotation); | ||
740 | } | ||
741 | return bodies; | ||
742 | } | ||
743 | } | ||
744 | } | ||
diff --git a/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/SynchronizedRegionsAreNotSiblings.java b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/SynchronizedRegionsAreNotSiblings.java new file mode 100644 index 00000000..160c4aa0 --- /dev/null +++ b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/SynchronizedRegionsAreNotSiblings.java | |||
@@ -0,0 +1,902 @@ | |||
1 | /** | ||
2 | * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql | ||
3 | */ | ||
4 | package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; | ||
5 | |||
6 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization; | ||
7 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex; | ||
8 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.Transition; | ||
9 | import java.util.Arrays; | ||
10 | import java.util.Collection; | ||
11 | import java.util.LinkedHashSet; | ||
12 | import java.util.List; | ||
13 | import java.util.Objects; | ||
14 | import java.util.Optional; | ||
15 | import java.util.Set; | ||
16 | import java.util.function.Consumer; | ||
17 | import java.util.stream.Collectors; | ||
18 | import java.util.stream.Stream; | ||
19 | import org.apache.log4j.Logger; | ||
20 | import org.eclipse.emf.ecore.EClass; | ||
21 | import org.eclipse.viatra.query.runtime.api.IPatternMatch; | ||
22 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification; | ||
23 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; | ||
24 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; | ||
25 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; | ||
26 | import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; | ||
27 | import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; | ||
28 | import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; | ||
29 | import org.eclipse.viatra.query.runtime.emf.types.EStructuralFeatureInstancesKey; | ||
30 | import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; | ||
31 | import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; | ||
32 | import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; | ||
33 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; | ||
34 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; | ||
35 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality; | ||
36 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; | ||
37 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Inequality; | ||
38 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall; | ||
39 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; | ||
40 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; | ||
41 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; | ||
42 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; | ||
43 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; | ||
44 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | ||
45 | import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; | ||
46 | |||
47 | /** | ||
48 | * A pattern-specific query specification that can instantiate Matcher in a type-safe way. | ||
49 | * | ||
50 | * <p>Original source: | ||
51 | * <code><pre> | ||
52 | * {@literal @}Constraint(severity="error", message="error", key = {s}) | ||
53 | * pattern SynchronizedRegionsAreNotSiblings(s : Synchronization, v1 : Vertex, v2 : Vertex) { | ||
54 | * find transition(_, v1, s); | ||
55 | * find transition(_, v2, s); | ||
56 | * CompositeElement.regions.vertices(r1, v1); | ||
57 | * CompositeElement.regions.vertices(r2, v2); | ||
58 | * r1 != r2; | ||
59 | * } or { | ||
60 | * find transition(_, s, v1); | ||
61 | * find transition(_, s, v2); | ||
62 | * CompositeElement.regions.vertices(r1, v1); | ||
63 | * CompositeElement.regions.vertices(r2, v2); | ||
64 | * r1 != r2; | ||
65 | * } | ||
66 | * </pre></code> | ||
67 | * | ||
68 | * @see Matcher | ||
69 | * @see Match | ||
70 | * | ||
71 | */ | ||
72 | @SuppressWarnings("all") | ||
73 | public final class SynchronizedRegionsAreNotSiblings extends BaseGeneratedEMFQuerySpecification<SynchronizedRegionsAreNotSiblings.Matcher> { | ||
74 | /** | ||
75 | * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedRegionsAreNotSiblings pattern, | ||
76 | * to be used in conjunction with {@link Matcher}. | ||
77 | * | ||
78 | * <p>Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. | ||
79 | * Each instance is a (possibly partial) substitution of pattern parameters, | ||
80 | * usable to represent a match of the pattern in the result of a query, | ||
81 | * or to specify the bound (fixed) input parameters when issuing a query. | ||
82 | * | ||
83 | * @see Matcher | ||
84 | * | ||
85 | */ | ||
86 | public static abstract class Match extends BasePatternMatch { | ||
87 | private Synchronization fS; | ||
88 | |||
89 | private Vertex fV1; | ||
90 | |||
91 | private Vertex fV2; | ||
92 | |||
93 | private static List<String> parameterNames = makeImmutableList("s", "v1", "v2"); | ||
94 | |||
95 | private Match(final Synchronization pS, final Vertex pV1, final Vertex pV2) { | ||
96 | this.fS = pS; | ||
97 | this.fV1 = pV1; | ||
98 | this.fV2 = pV2; | ||
99 | } | ||
100 | |||
101 | @Override | ||
102 | public Object get(final String parameterName) { | ||
103 | if ("s".equals(parameterName)) return this.fS; | ||
104 | if ("v1".equals(parameterName)) return this.fV1; | ||
105 | if ("v2".equals(parameterName)) return this.fV2; | ||
106 | return null; | ||
107 | } | ||
108 | |||
109 | public Synchronization getS() { | ||
110 | return this.fS; | ||
111 | } | ||
112 | |||
113 | public Vertex getV1() { | ||
114 | return this.fV1; | ||
115 | } | ||
116 | |||
117 | public Vertex getV2() { | ||
118 | return this.fV2; | ||
119 | } | ||
120 | |||
121 | @Override | ||
122 | public boolean set(final String parameterName, final Object newValue) { | ||
123 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
124 | if ("s".equals(parameterName) ) { | ||
125 | this.fS = (Synchronization) newValue; | ||
126 | return true; | ||
127 | } | ||
128 | if ("v1".equals(parameterName) ) { | ||
129 | this.fV1 = (Vertex) newValue; | ||
130 | return true; | ||
131 | } | ||
132 | if ("v2".equals(parameterName) ) { | ||
133 | this.fV2 = (Vertex) newValue; | ||
134 | return true; | ||
135 | } | ||
136 | return false; | ||
137 | } | ||
138 | |||
139 | public void setS(final Synchronization pS) { | ||
140 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
141 | this.fS = pS; | ||
142 | } | ||
143 | |||
144 | public void setV1(final Vertex pV1) { | ||
145 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
146 | this.fV1 = pV1; | ||
147 | } | ||
148 | |||
149 | public void setV2(final Vertex pV2) { | ||
150 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
151 | this.fV2 = pV2; | ||
152 | } | ||
153 | |||
154 | @Override | ||
155 | public String patternName() { | ||
156 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedRegionsAreNotSiblings"; | ||
157 | } | ||
158 | |||
159 | @Override | ||
160 | public List<String> parameterNames() { | ||
161 | return SynchronizedRegionsAreNotSiblings.Match.parameterNames; | ||
162 | } | ||
163 | |||
164 | @Override | ||
165 | public Object[] toArray() { | ||
166 | return new Object[]{fS, fV1, fV2}; | ||
167 | } | ||
168 | |||
169 | @Override | ||
170 | public SynchronizedRegionsAreNotSiblings.Match toImmutable() { | ||
171 | return isMutable() ? newMatch(fS, fV1, fV2) : this; | ||
172 | } | ||
173 | |||
174 | @Override | ||
175 | public String prettyPrint() { | ||
176 | StringBuilder result = new StringBuilder(); | ||
177 | result.append("\"s\"=" + prettyPrintValue(fS) + ", "); | ||
178 | result.append("\"v1\"=" + prettyPrintValue(fV1) + ", "); | ||
179 | result.append("\"v2\"=" + prettyPrintValue(fV2)); | ||
180 | return result.toString(); | ||
181 | } | ||
182 | |||
183 | @Override | ||
184 | public int hashCode() { | ||
185 | return Objects.hash(fS, fV1, fV2); | ||
186 | } | ||
187 | |||
188 | @Override | ||
189 | public boolean equals(final Object obj) { | ||
190 | if (this == obj) | ||
191 | return true; | ||
192 | if (obj == null) { | ||
193 | return false; | ||
194 | } | ||
195 | if ((obj instanceof SynchronizedRegionsAreNotSiblings.Match)) { | ||
196 | SynchronizedRegionsAreNotSiblings.Match other = (SynchronizedRegionsAreNotSiblings.Match) obj; | ||
197 | return Objects.equals(fS, other.fS) && Objects.equals(fV1, other.fV1) && Objects.equals(fV2, other.fV2); | ||
198 | } else { | ||
199 | // this should be infrequent | ||
200 | if (!(obj instanceof IPatternMatch)) { | ||
201 | return false; | ||
202 | } | ||
203 | IPatternMatch otherSig = (IPatternMatch) obj; | ||
204 | return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); | ||
205 | } | ||
206 | } | ||
207 | |||
208 | @Override | ||
209 | public SynchronizedRegionsAreNotSiblings specification() { | ||
210 | return SynchronizedRegionsAreNotSiblings.instance(); | ||
211 | } | ||
212 | |||
213 | /** | ||
214 | * Returns an empty, mutable match. | ||
215 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
216 | * | ||
217 | * @return the empty match. | ||
218 | * | ||
219 | */ | ||
220 | public static SynchronizedRegionsAreNotSiblings.Match newEmptyMatch() { | ||
221 | return new Mutable(null, null, null); | ||
222 | } | ||
223 | |||
224 | /** | ||
225 | * Returns a mutable (partial) match. | ||
226 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
227 | * | ||
228 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
229 | * @param pV1 the fixed value of pattern parameter v1, or null if not bound. | ||
230 | * @param pV2 the fixed value of pattern parameter v2, or null if not bound. | ||
231 | * @return the new, mutable (partial) match object. | ||
232 | * | ||
233 | */ | ||
234 | public static SynchronizedRegionsAreNotSiblings.Match newMutableMatch(final Synchronization pS, final Vertex pV1, final Vertex pV2) { | ||
235 | return new Mutable(pS, pV1, pV2); | ||
236 | } | ||
237 | |||
238 | /** | ||
239 | * Returns a new (partial) match. | ||
240 | * This can be used e.g. to call the matcher with a partial match. | ||
241 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
242 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
243 | * @param pV1 the fixed value of pattern parameter v1, or null if not bound. | ||
244 | * @param pV2 the fixed value of pattern parameter v2, or null if not bound. | ||
245 | * @return the (partial) match object. | ||
246 | * | ||
247 | */ | ||
248 | public static SynchronizedRegionsAreNotSiblings.Match newMatch(final Synchronization pS, final Vertex pV1, final Vertex pV2) { | ||
249 | return new Immutable(pS, pV1, pV2); | ||
250 | } | ||
251 | |||
252 | private static final class Mutable extends SynchronizedRegionsAreNotSiblings.Match { | ||
253 | Mutable(final Synchronization pS, final Vertex pV1, final Vertex pV2) { | ||
254 | super(pS, pV1, pV2); | ||
255 | } | ||
256 | |||
257 | @Override | ||
258 | public boolean isMutable() { | ||
259 | return true; | ||
260 | } | ||
261 | } | ||
262 | |||
263 | private static final class Immutable extends SynchronizedRegionsAreNotSiblings.Match { | ||
264 | Immutable(final Synchronization pS, final Vertex pV1, final Vertex pV2) { | ||
265 | super(pS, pV1, pV2); | ||
266 | } | ||
267 | |||
268 | @Override | ||
269 | public boolean isMutable() { | ||
270 | return false; | ||
271 | } | ||
272 | } | ||
273 | } | ||
274 | |||
275 | /** | ||
276 | * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedRegionsAreNotSiblings pattern, | ||
277 | * providing pattern-specific query methods. | ||
278 | * | ||
279 | * <p>Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, | ||
280 | * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. | ||
281 | * | ||
282 | * <p>Matches of the pattern will be represented as {@link Match}. | ||
283 | * | ||
284 | * <p>Original source: | ||
285 | * <code><pre> | ||
286 | * {@literal @}Constraint(severity="error", message="error", key = {s}) | ||
287 | * pattern SynchronizedRegionsAreNotSiblings(s : Synchronization, v1 : Vertex, v2 : Vertex) { | ||
288 | * find transition(_, v1, s); | ||
289 | * find transition(_, v2, s); | ||
290 | * CompositeElement.regions.vertices(r1, v1); | ||
291 | * CompositeElement.regions.vertices(r2, v2); | ||
292 | * r1 != r2; | ||
293 | * } or { | ||
294 | * find transition(_, s, v1); | ||
295 | * find transition(_, s, v2); | ||
296 | * CompositeElement.regions.vertices(r1, v1); | ||
297 | * CompositeElement.regions.vertices(r2, v2); | ||
298 | * r1 != r2; | ||
299 | * } | ||
300 | * </pre></code> | ||
301 | * | ||
302 | * @see Match | ||
303 | * @see SynchronizedRegionsAreNotSiblings | ||
304 | * | ||
305 | */ | ||
306 | public static class Matcher extends BaseMatcher<SynchronizedRegionsAreNotSiblings.Match> { | ||
307 | /** | ||
308 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
309 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
310 | * | ||
311 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
312 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
313 | * | ||
314 | */ | ||
315 | public static SynchronizedRegionsAreNotSiblings.Matcher on(final ViatraQueryEngine engine) { | ||
316 | // check if matcher already exists | ||
317 | Matcher matcher = engine.getExistingMatcher(querySpecification()); | ||
318 | if (matcher == null) { | ||
319 | matcher = (Matcher)engine.getMatcher(querySpecification()); | ||
320 | } | ||
321 | return matcher; | ||
322 | } | ||
323 | |||
324 | /** | ||
325 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
326 | * @return an initialized matcher | ||
327 | * @noreference This method is for internal matcher initialization by the framework, do not call it manually. | ||
328 | * | ||
329 | */ | ||
330 | public static SynchronizedRegionsAreNotSiblings.Matcher create() { | ||
331 | return new Matcher(); | ||
332 | } | ||
333 | |||
334 | private final static int POSITION_S = 0; | ||
335 | |||
336 | private final static int POSITION_V1 = 1; | ||
337 | |||
338 | private final static int POSITION_V2 = 2; | ||
339 | |||
340 | private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(SynchronizedRegionsAreNotSiblings.Matcher.class); | ||
341 | |||
342 | /** | ||
343 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
344 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
345 | * | ||
346 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
347 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
348 | * | ||
349 | */ | ||
350 | private Matcher() { | ||
351 | super(querySpecification()); | ||
352 | } | ||
353 | |||
354 | /** | ||
355 | * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. | ||
356 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
357 | * @param pV1 the fixed value of pattern parameter v1, or null if not bound. | ||
358 | * @param pV2 the fixed value of pattern parameter v2, or null if not bound. | ||
359 | * @return matches represented as a Match object. | ||
360 | * | ||
361 | */ | ||
362 | public Collection<SynchronizedRegionsAreNotSiblings.Match> getAllMatches(final Synchronization pS, final Vertex pV1, final Vertex pV2) { | ||
363 | return rawStreamAllMatches(new Object[]{pS, pV1, pV2}).collect(Collectors.toSet()); | ||
364 | } | ||
365 | |||
366 | /** | ||
367 | * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. | ||
368 | * </p> | ||
369 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
370 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
371 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
372 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
373 | * @param pV1 the fixed value of pattern parameter v1, or null if not bound. | ||
374 | * @param pV2 the fixed value of pattern parameter v2, or null if not bound. | ||
375 | * @return a stream of matches represented as a Match object. | ||
376 | * | ||
377 | */ | ||
378 | public Stream<SynchronizedRegionsAreNotSiblings.Match> streamAllMatches(final Synchronization pS, final Vertex pV1, final Vertex pV2) { | ||
379 | return rawStreamAllMatches(new Object[]{pS, pV1, pV2}); | ||
380 | } | ||
381 | |||
382 | /** | ||
383 | * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
384 | * Neither determinism nor randomness of selection is guaranteed. | ||
385 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
386 | * @param pV1 the fixed value of pattern parameter v1, or null if not bound. | ||
387 | * @param pV2 the fixed value of pattern parameter v2, or null if not bound. | ||
388 | * @return a match represented as a Match object, or null if no match is found. | ||
389 | * | ||
390 | */ | ||
391 | public Optional<SynchronizedRegionsAreNotSiblings.Match> getOneArbitraryMatch(final Synchronization pS, final Vertex pV1, final Vertex pV2) { | ||
392 | return rawGetOneArbitraryMatch(new Object[]{pS, pV1, pV2}); | ||
393 | } | ||
394 | |||
395 | /** | ||
396 | * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, | ||
397 | * under any possible substitution of the unspecified parameters (if any). | ||
398 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
399 | * @param pV1 the fixed value of pattern parameter v1, or null if not bound. | ||
400 | * @param pV2 the fixed value of pattern parameter v2, or null if not bound. | ||
401 | * @return true if the input is a valid (partial) match of the pattern. | ||
402 | * | ||
403 | */ | ||
404 | public boolean hasMatch(final Synchronization pS, final Vertex pV1, final Vertex pV2) { | ||
405 | return rawHasMatch(new Object[]{pS, pV1, pV2}); | ||
406 | } | ||
407 | |||
408 | /** | ||
409 | * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. | ||
410 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
411 | * @param pV1 the fixed value of pattern parameter v1, or null if not bound. | ||
412 | * @param pV2 the fixed value of pattern parameter v2, or null if not bound. | ||
413 | * @return the number of pattern matches found. | ||
414 | * | ||
415 | */ | ||
416 | public int countMatches(final Synchronization pS, final Vertex pV1, final Vertex pV2) { | ||
417 | return rawCountMatches(new Object[]{pS, pV1, pV2}); | ||
418 | } | ||
419 | |||
420 | /** | ||
421 | * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
422 | * Neither determinism nor randomness of selection is guaranteed. | ||
423 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
424 | * @param pV1 the fixed value of pattern parameter v1, or null if not bound. | ||
425 | * @param pV2 the fixed value of pattern parameter v2, or null if not bound. | ||
426 | * @param processor the action that will process the selected match. | ||
427 | * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked | ||
428 | * | ||
429 | */ | ||
430 | public boolean forOneArbitraryMatch(final Synchronization pS, final Vertex pV1, final Vertex pV2, final Consumer<? super SynchronizedRegionsAreNotSiblings.Match> processor) { | ||
431 | return rawForOneArbitraryMatch(new Object[]{pS, pV1, pV2}, processor); | ||
432 | } | ||
433 | |||
434 | /** | ||
435 | * Returns a new (partial) match. | ||
436 | * This can be used e.g. to call the matcher with a partial match. | ||
437 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
438 | * @param pS the fixed value of pattern parameter s, or null if not bound. | ||
439 | * @param pV1 the fixed value of pattern parameter v1, or null if not bound. | ||
440 | * @param pV2 the fixed value of pattern parameter v2, or null if not bound. | ||
441 | * @return the (partial) match object. | ||
442 | * | ||
443 | */ | ||
444 | public SynchronizedRegionsAreNotSiblings.Match newMatch(final Synchronization pS, final Vertex pV1, final Vertex pV2) { | ||
445 | return SynchronizedRegionsAreNotSiblings.Match.newMatch(pS, pV1, pV2); | ||
446 | } | ||
447 | |||
448 | /** | ||
449 | * Retrieve the set of values that occur in matches for s. | ||
450 | * @return the Set of all values or empty set if there are no matches | ||
451 | * | ||
452 | */ | ||
453 | protected Stream<Synchronization> rawStreamAllValuesOfs(final Object[] parameters) { | ||
454 | return rawStreamAllValues(POSITION_S, parameters).map(Synchronization.class::cast); | ||
455 | } | ||
456 | |||
457 | /** | ||
458 | * Retrieve the set of values that occur in matches for s. | ||
459 | * @return the Set of all values or empty set if there are no matches | ||
460 | * | ||
461 | */ | ||
462 | public Set<Synchronization> getAllValuesOfs() { | ||
463 | return rawStreamAllValuesOfs(emptyArray()).collect(Collectors.toSet()); | ||
464 | } | ||
465 | |||
466 | /** | ||
467 | * Retrieve the set of values that occur in matches for s. | ||
468 | * @return the Set of all values or empty set if there are no matches | ||
469 | * | ||
470 | */ | ||
471 | public Stream<Synchronization> streamAllValuesOfs() { | ||
472 | return rawStreamAllValuesOfs(emptyArray()); | ||
473 | } | ||
474 | |||
475 | /** | ||
476 | * Retrieve the set of values that occur in matches for s. | ||
477 | * </p> | ||
478 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
479 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
480 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
481 | * | ||
482 | * @return the Stream of all values or empty set if there are no matches | ||
483 | * | ||
484 | */ | ||
485 | public Stream<Synchronization> streamAllValuesOfs(final SynchronizedRegionsAreNotSiblings.Match partialMatch) { | ||
486 | return rawStreamAllValuesOfs(partialMatch.toArray()); | ||
487 | } | ||
488 | |||
489 | /** | ||
490 | * Retrieve the set of values that occur in matches for s. | ||
491 | * </p> | ||
492 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
493 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
494 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
495 | * | ||
496 | * @return the Stream of all values or empty set if there are no matches | ||
497 | * | ||
498 | */ | ||
499 | public Stream<Synchronization> streamAllValuesOfs(final Vertex pV1, final Vertex pV2) { | ||
500 | return rawStreamAllValuesOfs(new Object[]{null, pV1, pV2}); | ||
501 | } | ||
502 | |||
503 | /** | ||
504 | * Retrieve the set of values that occur in matches for s. | ||
505 | * @return the Set of all values or empty set if there are no matches | ||
506 | * | ||
507 | */ | ||
508 | public Set<Synchronization> getAllValuesOfs(final SynchronizedRegionsAreNotSiblings.Match partialMatch) { | ||
509 | return rawStreamAllValuesOfs(partialMatch.toArray()).collect(Collectors.toSet()); | ||
510 | } | ||
511 | |||
512 | /** | ||
513 | * Retrieve the set of values that occur in matches for s. | ||
514 | * @return the Set of all values or empty set if there are no matches | ||
515 | * | ||
516 | */ | ||
517 | public Set<Synchronization> getAllValuesOfs(final Vertex pV1, final Vertex pV2) { | ||
518 | return rawStreamAllValuesOfs(new Object[]{null, pV1, pV2}).collect(Collectors.toSet()); | ||
519 | } | ||
520 | |||
521 | /** | ||
522 | * Retrieve the set of values that occur in matches for v1. | ||
523 | * @return the Set of all values or empty set if there are no matches | ||
524 | * | ||
525 | */ | ||
526 | protected Stream<Vertex> rawStreamAllValuesOfv1(final Object[] parameters) { | ||
527 | return rawStreamAllValues(POSITION_V1, parameters).map(Vertex.class::cast); | ||
528 | } | ||
529 | |||
530 | /** | ||
531 | * Retrieve the set of values that occur in matches for v1. | ||
532 | * @return the Set of all values or empty set if there are no matches | ||
533 | * | ||
534 | */ | ||
535 | public Set<Vertex> getAllValuesOfv1() { | ||
536 | return rawStreamAllValuesOfv1(emptyArray()).collect(Collectors.toSet()); | ||
537 | } | ||
538 | |||
539 | /** | ||
540 | * Retrieve the set of values that occur in matches for v1. | ||
541 | * @return the Set of all values or empty set if there are no matches | ||
542 | * | ||
543 | */ | ||
544 | public Stream<Vertex> streamAllValuesOfv1() { | ||
545 | return rawStreamAllValuesOfv1(emptyArray()); | ||
546 | } | ||
547 | |||
548 | /** | ||
549 | * Retrieve the set of values that occur in matches for v1. | ||
550 | * </p> | ||
551 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
552 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
553 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
554 | * | ||
555 | * @return the Stream of all values or empty set if there are no matches | ||
556 | * | ||
557 | */ | ||
558 | public Stream<Vertex> streamAllValuesOfv1(final SynchronizedRegionsAreNotSiblings.Match partialMatch) { | ||
559 | return rawStreamAllValuesOfv1(partialMatch.toArray()); | ||
560 | } | ||
561 | |||
562 | /** | ||
563 | * Retrieve the set of values that occur in matches for v1. | ||
564 | * </p> | ||
565 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
566 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
567 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
568 | * | ||
569 | * @return the Stream of all values or empty set if there are no matches | ||
570 | * | ||
571 | */ | ||
572 | public Stream<Vertex> streamAllValuesOfv1(final Synchronization pS, final Vertex pV2) { | ||
573 | return rawStreamAllValuesOfv1(new Object[]{pS, null, pV2}); | ||
574 | } | ||
575 | |||
576 | /** | ||
577 | * Retrieve the set of values that occur in matches for v1. | ||
578 | * @return the Set of all values or empty set if there are no matches | ||
579 | * | ||
580 | */ | ||
581 | public Set<Vertex> getAllValuesOfv1(final SynchronizedRegionsAreNotSiblings.Match partialMatch) { | ||
582 | return rawStreamAllValuesOfv1(partialMatch.toArray()).collect(Collectors.toSet()); | ||
583 | } | ||
584 | |||
585 | /** | ||
586 | * Retrieve the set of values that occur in matches for v1. | ||
587 | * @return the Set of all values or empty set if there are no matches | ||
588 | * | ||
589 | */ | ||
590 | public Set<Vertex> getAllValuesOfv1(final Synchronization pS, final Vertex pV2) { | ||
591 | return rawStreamAllValuesOfv1(new Object[]{pS, null, pV2}).collect(Collectors.toSet()); | ||
592 | } | ||
593 | |||
594 | /** | ||
595 | * Retrieve the set of values that occur in matches for v2. | ||
596 | * @return the Set of all values or empty set if there are no matches | ||
597 | * | ||
598 | */ | ||
599 | protected Stream<Vertex> rawStreamAllValuesOfv2(final Object[] parameters) { | ||
600 | return rawStreamAllValues(POSITION_V2, parameters).map(Vertex.class::cast); | ||
601 | } | ||
602 | |||
603 | /** | ||
604 | * Retrieve the set of values that occur in matches for v2. | ||
605 | * @return the Set of all values or empty set if there are no matches | ||
606 | * | ||
607 | */ | ||
608 | public Set<Vertex> getAllValuesOfv2() { | ||
609 | return rawStreamAllValuesOfv2(emptyArray()).collect(Collectors.toSet()); | ||
610 | } | ||
611 | |||
612 | /** | ||
613 | * Retrieve the set of values that occur in matches for v2. | ||
614 | * @return the Set of all values or empty set if there are no matches | ||
615 | * | ||
616 | */ | ||
617 | public Stream<Vertex> streamAllValuesOfv2() { | ||
618 | return rawStreamAllValuesOfv2(emptyArray()); | ||
619 | } | ||
620 | |||
621 | /** | ||
622 | * Retrieve the set of values that occur in matches for v2. | ||
623 | * </p> | ||
624 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
625 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
626 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
627 | * | ||
628 | * @return the Stream of all values or empty set if there are no matches | ||
629 | * | ||
630 | */ | ||
631 | public Stream<Vertex> streamAllValuesOfv2(final SynchronizedRegionsAreNotSiblings.Match partialMatch) { | ||
632 | return rawStreamAllValuesOfv2(partialMatch.toArray()); | ||
633 | } | ||
634 | |||
635 | /** | ||
636 | * Retrieve the set of values that occur in matches for v2. | ||
637 | * </p> | ||
638 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
639 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
640 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
641 | * | ||
642 | * @return the Stream of all values or empty set if there are no matches | ||
643 | * | ||
644 | */ | ||
645 | public Stream<Vertex> streamAllValuesOfv2(final Synchronization pS, final Vertex pV1) { | ||
646 | return rawStreamAllValuesOfv2(new Object[]{pS, pV1, null}); | ||
647 | } | ||
648 | |||
649 | /** | ||
650 | * Retrieve the set of values that occur in matches for v2. | ||
651 | * @return the Set of all values or empty set if there are no matches | ||
652 | * | ||
653 | */ | ||
654 | public Set<Vertex> getAllValuesOfv2(final SynchronizedRegionsAreNotSiblings.Match partialMatch) { | ||
655 | return rawStreamAllValuesOfv2(partialMatch.toArray()).collect(Collectors.toSet()); | ||
656 | } | ||
657 | |||
658 | /** | ||
659 | * Retrieve the set of values that occur in matches for v2. | ||
660 | * @return the Set of all values or empty set if there are no matches | ||
661 | * | ||
662 | */ | ||
663 | public Set<Vertex> getAllValuesOfv2(final Synchronization pS, final Vertex pV1) { | ||
664 | return rawStreamAllValuesOfv2(new Object[]{pS, pV1, null}).collect(Collectors.toSet()); | ||
665 | } | ||
666 | |||
667 | @Override | ||
668 | protected SynchronizedRegionsAreNotSiblings.Match tupleToMatch(final Tuple t) { | ||
669 | try { | ||
670 | return SynchronizedRegionsAreNotSiblings.Match.newMatch((Synchronization) t.get(POSITION_S), (Vertex) t.get(POSITION_V1), (Vertex) t.get(POSITION_V2)); | ||
671 | } catch(ClassCastException e) { | ||
672 | LOGGER.error("Element(s) in tuple not properly typed!",e); | ||
673 | return null; | ||
674 | } | ||
675 | } | ||
676 | |||
677 | @Override | ||
678 | protected SynchronizedRegionsAreNotSiblings.Match arrayToMatch(final Object[] match) { | ||
679 | try { | ||
680 | return SynchronizedRegionsAreNotSiblings.Match.newMatch((Synchronization) match[POSITION_S], (Vertex) match[POSITION_V1], (Vertex) match[POSITION_V2]); | ||
681 | } catch(ClassCastException e) { | ||
682 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
683 | return null; | ||
684 | } | ||
685 | } | ||
686 | |||
687 | @Override | ||
688 | protected SynchronizedRegionsAreNotSiblings.Match arrayToMatchMutable(final Object[] match) { | ||
689 | try { | ||
690 | return SynchronizedRegionsAreNotSiblings.Match.newMutableMatch((Synchronization) match[POSITION_S], (Vertex) match[POSITION_V1], (Vertex) match[POSITION_V2]); | ||
691 | } catch(ClassCastException e) { | ||
692 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
693 | return null; | ||
694 | } | ||
695 | } | ||
696 | |||
697 | /** | ||
698 | * @return the singleton instance of the query specification of this pattern | ||
699 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
700 | * | ||
701 | */ | ||
702 | public static IQuerySpecification<SynchronizedRegionsAreNotSiblings.Matcher> querySpecification() { | ||
703 | return SynchronizedRegionsAreNotSiblings.instance(); | ||
704 | } | ||
705 | } | ||
706 | |||
707 | private SynchronizedRegionsAreNotSiblings() { | ||
708 | super(GeneratedPQuery.INSTANCE); | ||
709 | } | ||
710 | |||
711 | /** | ||
712 | * @return the singleton instance of the query specification | ||
713 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
714 | * | ||
715 | */ | ||
716 | public static SynchronizedRegionsAreNotSiblings instance() { | ||
717 | try{ | ||
718 | return LazyHolder.INSTANCE; | ||
719 | } catch (ExceptionInInitializerError err) { | ||
720 | throw processInitializerError(err); | ||
721 | } | ||
722 | } | ||
723 | |||
724 | @Override | ||
725 | protected SynchronizedRegionsAreNotSiblings.Matcher instantiate(final ViatraQueryEngine engine) { | ||
726 | return SynchronizedRegionsAreNotSiblings.Matcher.on(engine); | ||
727 | } | ||
728 | |||
729 | @Override | ||
730 | public SynchronizedRegionsAreNotSiblings.Matcher instantiate() { | ||
731 | return SynchronizedRegionsAreNotSiblings.Matcher.create(); | ||
732 | } | ||
733 | |||
734 | @Override | ||
735 | public SynchronizedRegionsAreNotSiblings.Match newEmptyMatch() { | ||
736 | return SynchronizedRegionsAreNotSiblings.Match.newEmptyMatch(); | ||
737 | } | ||
738 | |||
739 | @Override | ||
740 | public SynchronizedRegionsAreNotSiblings.Match newMatch(final Object... parameters) { | ||
741 | return SynchronizedRegionsAreNotSiblings.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization) parameters[0], (ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex) parameters[1], (ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex) parameters[2]); | ||
742 | } | ||
743 | |||
744 | /** | ||
745 | * Inner class allowing the singleton instance of {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedRegionsAreNotSiblings (visibility: PUBLIC, simpleName: SynchronizedRegionsAreNotSiblings, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedRegionsAreNotSiblings, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created | ||
746 | * <b>not</b> at the class load time of the outer class, | ||
747 | * but rather at the first call to {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedRegionsAreNotSiblings (visibility: PUBLIC, simpleName: SynchronizedRegionsAreNotSiblings, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedRegionsAreNotSiblings, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. | ||
748 | * | ||
749 | * <p> This workaround is required e.g. to support recursion. | ||
750 | * | ||
751 | */ | ||
752 | private static class LazyHolder { | ||
753 | private final static SynchronizedRegionsAreNotSiblings INSTANCE = new SynchronizedRegionsAreNotSiblings(); | ||
754 | |||
755 | /** | ||
756 | * Statically initializes the query specification <b>after</b> the field {@link #INSTANCE} is assigned. | ||
757 | * This initialization order is required to support indirect recursion. | ||
758 | * | ||
759 | * <p> The static initializer is defined using a helper field to work around limitations of the code generator. | ||
760 | * | ||
761 | */ | ||
762 | private final static Object STATIC_INITIALIZER = ensureInitialized(); | ||
763 | |||
764 | public static Object ensureInitialized() { | ||
765 | INSTANCE.ensureInitializedInternal(); | ||
766 | return null; | ||
767 | } | ||
768 | } | ||
769 | |||
770 | private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { | ||
771 | private final static SynchronizedRegionsAreNotSiblings.GeneratedPQuery INSTANCE = new GeneratedPQuery(); | ||
772 | |||
773 | private final PParameter parameter_s = new PParameter("s", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Synchronization")), PParameterDirection.INOUT); | ||
774 | |||
775 | private final PParameter parameter_v1 = new PParameter("v1", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Vertex")), PParameterDirection.INOUT); | ||
776 | |||
777 | private final PParameter parameter_v2 = new PParameter("v2", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Vertex")), PParameterDirection.INOUT); | ||
778 | |||
779 | private final List<PParameter> parameters = Arrays.asList(parameter_s, parameter_v1, parameter_v2); | ||
780 | |||
781 | private GeneratedPQuery() { | ||
782 | super(PVisibility.PUBLIC); | ||
783 | } | ||
784 | |||
785 | @Override | ||
786 | public String getFullyQualifiedName() { | ||
787 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedRegionsAreNotSiblings"; | ||
788 | } | ||
789 | |||
790 | @Override | ||
791 | public List<String> getParameterNames() { | ||
792 | return Arrays.asList("s","v1","v2"); | ||
793 | } | ||
794 | |||
795 | @Override | ||
796 | public List<PParameter> getParameters() { | ||
797 | return parameters; | ||
798 | } | ||
799 | |||
800 | @Override | ||
801 | public Set<PBody> doGetContainedBodies() { | ||
802 | setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); | ||
803 | Set<PBody> bodies = new LinkedHashSet<>(); | ||
804 | { | ||
805 | PBody body = new PBody(this); | ||
806 | PVariable var_s = body.getOrCreateVariableByName("s"); | ||
807 | PVariable var_v1 = body.getOrCreateVariableByName("v1"); | ||
808 | PVariable var_v2 = body.getOrCreateVariableByName("v2"); | ||
809 | PVariable var___0_ = body.getOrCreateVariableByName("_<0>"); | ||
810 | PVariable var___1_ = body.getOrCreateVariableByName("_<1>"); | ||
811 | PVariable var_r1 = body.getOrCreateVariableByName("r1"); | ||
812 | PVariable var_r2 = body.getOrCreateVariableByName("r2"); | ||
813 | new TypeConstraint(body, Tuples.flatTupleOf(var_s), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Synchronization"))); | ||
814 | new TypeConstraint(body, Tuples.flatTupleOf(var_v1), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); | ||
815 | new TypeConstraint(body, Tuples.flatTupleOf(var_v2), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); | ||
816 | body.setSymbolicParameters(Arrays.<ExportedParameter>asList( | ||
817 | new ExportedParameter(body, var_s, parameter_s), | ||
818 | new ExportedParameter(body, var_v1, parameter_v1), | ||
819 | new ExportedParameter(body, var_v2, parameter_v2) | ||
820 | )); | ||
821 | // find transition(_, v1, s) | ||
822 | new PositivePatternCall(body, Tuples.flatTupleOf(var___0_, var_v1, var_s), Transition.instance().getInternalQueryRepresentation()); | ||
823 | // find transition(_, v2, s) | ||
824 | new PositivePatternCall(body, Tuples.flatTupleOf(var___1_, var_v2, var_s), Transition.instance().getInternalQueryRepresentation()); | ||
825 | // CompositeElement.regions.vertices(r1, v1) | ||
826 | new TypeConstraint(body, Tuples.flatTupleOf(var_r1), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "CompositeElement"))); | ||
827 | PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); | ||
828 | new TypeConstraint(body, Tuples.flatTupleOf(var_r1, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "CompositeElement", "regions"))); | ||
829 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Region"))); | ||
830 | PVariable var__virtual_1_ = body.getOrCreateVariableByName(".virtual{1}"); | ||
831 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_, var__virtual_1_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Region", "vertices"))); | ||
832 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_1_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); | ||
833 | new Equality(body, var__virtual_1_, var_v1); | ||
834 | // CompositeElement.regions.vertices(r2, v2) | ||
835 | new TypeConstraint(body, Tuples.flatTupleOf(var_r2), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "CompositeElement"))); | ||
836 | PVariable var__virtual_2_ = body.getOrCreateVariableByName(".virtual{2}"); | ||
837 | new TypeConstraint(body, Tuples.flatTupleOf(var_r2, var__virtual_2_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "CompositeElement", "regions"))); | ||
838 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_2_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Region"))); | ||
839 | PVariable var__virtual_3_ = body.getOrCreateVariableByName(".virtual{3}"); | ||
840 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_2_, var__virtual_3_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Region", "vertices"))); | ||
841 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_3_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); | ||
842 | new Equality(body, var__virtual_3_, var_v2); | ||
843 | // r1 != r2 | ||
844 | new Inequality(body, var_r1, var_r2); | ||
845 | bodies.add(body); | ||
846 | } | ||
847 | { | ||
848 | PBody body = new PBody(this); | ||
849 | PVariable var_s = body.getOrCreateVariableByName("s"); | ||
850 | PVariable var_v1 = body.getOrCreateVariableByName("v1"); | ||
851 | PVariable var_v2 = body.getOrCreateVariableByName("v2"); | ||
852 | PVariable var___0_ = body.getOrCreateVariableByName("_<0>"); | ||
853 | PVariable var___1_ = body.getOrCreateVariableByName("_<1>"); | ||
854 | PVariable var_r1 = body.getOrCreateVariableByName("r1"); | ||
855 | PVariable var_r2 = body.getOrCreateVariableByName("r2"); | ||
856 | new TypeConstraint(body, Tuples.flatTupleOf(var_s), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Synchronization"))); | ||
857 | new TypeConstraint(body, Tuples.flatTupleOf(var_v1), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); | ||
858 | new TypeConstraint(body, Tuples.flatTupleOf(var_v2), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); | ||
859 | body.setSymbolicParameters(Arrays.<ExportedParameter>asList( | ||
860 | new ExportedParameter(body, var_s, parameter_s), | ||
861 | new ExportedParameter(body, var_v1, parameter_v1), | ||
862 | new ExportedParameter(body, var_v2, parameter_v2) | ||
863 | )); | ||
864 | // find transition(_, s, v1) | ||
865 | new PositivePatternCall(body, Tuples.flatTupleOf(var___0_, var_s, var_v1), Transition.instance().getInternalQueryRepresentation()); | ||
866 | // find transition(_, s, v2) | ||
867 | new PositivePatternCall(body, Tuples.flatTupleOf(var___1_, var_s, var_v2), Transition.instance().getInternalQueryRepresentation()); | ||
868 | // CompositeElement.regions.vertices(r1, v1) | ||
869 | new TypeConstraint(body, Tuples.flatTupleOf(var_r1), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "CompositeElement"))); | ||
870 | PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); | ||
871 | new TypeConstraint(body, Tuples.flatTupleOf(var_r1, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "CompositeElement", "regions"))); | ||
872 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Region"))); | ||
873 | PVariable var__virtual_1_ = body.getOrCreateVariableByName(".virtual{1}"); | ||
874 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_, var__virtual_1_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Region", "vertices"))); | ||
875 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_1_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); | ||
876 | new Equality(body, var__virtual_1_, var_v1); | ||
877 | // CompositeElement.regions.vertices(r2, v2) | ||
878 | new TypeConstraint(body, Tuples.flatTupleOf(var_r2), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "CompositeElement"))); | ||
879 | PVariable var__virtual_2_ = body.getOrCreateVariableByName(".virtual{2}"); | ||
880 | new TypeConstraint(body, Tuples.flatTupleOf(var_r2, var__virtual_2_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "CompositeElement", "regions"))); | ||
881 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_2_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Region"))); | ||
882 | PVariable var__virtual_3_ = body.getOrCreateVariableByName(".virtual{3}"); | ||
883 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_2_, var__virtual_3_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Region", "vertices"))); | ||
884 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_3_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); | ||
885 | new Equality(body, var__virtual_3_, var_v2); | ||
886 | // r1 != r2 | ||
887 | new Inequality(body, var_r1, var_r2); | ||
888 | bodies.add(body); | ||
889 | } | ||
890 | { | ||
891 | PAnnotation annotation = new PAnnotation("Constraint"); | ||
892 | annotation.addAttribute("severity", "error"); | ||
893 | annotation.addAttribute("message", "error"); | ||
894 | annotation.addAttribute("key", Arrays.asList(new Object[] { | ||
895 | new ParameterReference("s") | ||
896 | })); | ||
897 | addAnnotation(annotation); | ||
898 | } | ||
899 | return bodies; | ||
900 | } | ||
901 | } | ||
902 | } | ||
diff --git a/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/Transition.java b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/Transition.java new file mode 100644 index 00000000..185f348e --- /dev/null +++ b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/Transition.java | |||
@@ -0,0 +1,808 @@ | |||
1 | /** | ||
2 | * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql | ||
3 | */ | ||
4 | package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; | ||
5 | |||
6 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex; | ||
7 | import java.util.Arrays; | ||
8 | import java.util.Collection; | ||
9 | import java.util.LinkedHashSet; | ||
10 | import java.util.List; | ||
11 | import java.util.Objects; | ||
12 | import java.util.Optional; | ||
13 | import java.util.Set; | ||
14 | import java.util.function.Consumer; | ||
15 | import java.util.stream.Collectors; | ||
16 | import java.util.stream.Stream; | ||
17 | import org.apache.log4j.Logger; | ||
18 | import org.eclipse.emf.ecore.EClass; | ||
19 | import org.eclipse.viatra.query.runtime.api.IPatternMatch; | ||
20 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification; | ||
21 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; | ||
22 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; | ||
23 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; | ||
24 | import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; | ||
25 | import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; | ||
26 | import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; | ||
27 | import org.eclipse.viatra.query.runtime.emf.types.EStructuralFeatureInstancesKey; | ||
28 | import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; | ||
29 | import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; | ||
30 | import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; | ||
31 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality; | ||
32 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; | ||
33 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; | ||
34 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; | ||
35 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; | ||
36 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; | ||
37 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; | ||
38 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | ||
39 | import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; | ||
40 | |||
41 | /** | ||
42 | * A pattern-specific query specification that can instantiate Matcher in a type-safe way. | ||
43 | * | ||
44 | * <p>Original source: | ||
45 | * <code><pre> | ||
46 | * pattern transition(t : Transition, src : Vertex, trg : Vertex) { | ||
47 | * Transition.source(t, src); | ||
48 | * Transition.target(t, trg); | ||
49 | * } | ||
50 | * </pre></code> | ||
51 | * | ||
52 | * @see Matcher | ||
53 | * @see Match | ||
54 | * | ||
55 | */ | ||
56 | @SuppressWarnings("all") | ||
57 | public final class Transition extends BaseGeneratedEMFQuerySpecification<Transition.Matcher> { | ||
58 | /** | ||
59 | * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.transition pattern, | ||
60 | * to be used in conjunction with {@link Matcher}. | ||
61 | * | ||
62 | * <p>Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. | ||
63 | * Each instance is a (possibly partial) substitution of pattern parameters, | ||
64 | * usable to represent a match of the pattern in the result of a query, | ||
65 | * or to specify the bound (fixed) input parameters when issuing a query. | ||
66 | * | ||
67 | * @see Matcher | ||
68 | * | ||
69 | */ | ||
70 | public static abstract class Match extends BasePatternMatch { | ||
71 | private ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition fT; | ||
72 | |||
73 | private Vertex fSrc; | ||
74 | |||
75 | private Vertex fTrg; | ||
76 | |||
77 | private static List<String> parameterNames = makeImmutableList("t", "src", "trg"); | ||
78 | |||
79 | private Match(final ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition pT, final Vertex pSrc, final Vertex pTrg) { | ||
80 | this.fT = pT; | ||
81 | this.fSrc = pSrc; | ||
82 | this.fTrg = pTrg; | ||
83 | } | ||
84 | |||
85 | @Override | ||
86 | public Object get(final String parameterName) { | ||
87 | if ("t".equals(parameterName)) return this.fT; | ||
88 | if ("src".equals(parameterName)) return this.fSrc; | ||
89 | if ("trg".equals(parameterName)) return this.fTrg; | ||
90 | return null; | ||
91 | } | ||
92 | |||
93 | public ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition getT() { | ||
94 | return this.fT; | ||
95 | } | ||
96 | |||
97 | public Vertex getSrc() { | ||
98 | return this.fSrc; | ||
99 | } | ||
100 | |||
101 | public Vertex getTrg() { | ||
102 | return this.fTrg; | ||
103 | } | ||
104 | |||
105 | @Override | ||
106 | public boolean set(final String parameterName, final Object newValue) { | ||
107 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
108 | if ("t".equals(parameterName) ) { | ||
109 | this.fT = (ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition) newValue; | ||
110 | return true; | ||
111 | } | ||
112 | if ("src".equals(parameterName) ) { | ||
113 | this.fSrc = (Vertex) newValue; | ||
114 | return true; | ||
115 | } | ||
116 | if ("trg".equals(parameterName) ) { | ||
117 | this.fTrg = (Vertex) newValue; | ||
118 | return true; | ||
119 | } | ||
120 | return false; | ||
121 | } | ||
122 | |||
123 | public void setT(final ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition pT) { | ||
124 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
125 | this.fT = pT; | ||
126 | } | ||
127 | |||
128 | public void setSrc(final Vertex pSrc) { | ||
129 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
130 | this.fSrc = pSrc; | ||
131 | } | ||
132 | |||
133 | public void setTrg(final Vertex pTrg) { | ||
134 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
135 | this.fTrg = pTrg; | ||
136 | } | ||
137 | |||
138 | @Override | ||
139 | public String patternName() { | ||
140 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.transition"; | ||
141 | } | ||
142 | |||
143 | @Override | ||
144 | public List<String> parameterNames() { | ||
145 | return Transition.Match.parameterNames; | ||
146 | } | ||
147 | |||
148 | @Override | ||
149 | public Object[] toArray() { | ||
150 | return new Object[]{fT, fSrc, fTrg}; | ||
151 | } | ||
152 | |||
153 | @Override | ||
154 | public Transition.Match toImmutable() { | ||
155 | return isMutable() ? newMatch(fT, fSrc, fTrg) : this; | ||
156 | } | ||
157 | |||
158 | @Override | ||
159 | public String prettyPrint() { | ||
160 | StringBuilder result = new StringBuilder(); | ||
161 | result.append("\"t\"=" + prettyPrintValue(fT) + ", "); | ||
162 | result.append("\"src\"=" + prettyPrintValue(fSrc) + ", "); | ||
163 | result.append("\"trg\"=" + prettyPrintValue(fTrg)); | ||
164 | return result.toString(); | ||
165 | } | ||
166 | |||
167 | @Override | ||
168 | public int hashCode() { | ||
169 | return Objects.hash(fT, fSrc, fTrg); | ||
170 | } | ||
171 | |||
172 | @Override | ||
173 | public boolean equals(final Object obj) { | ||
174 | if (this == obj) | ||
175 | return true; | ||
176 | if (obj == null) { | ||
177 | return false; | ||
178 | } | ||
179 | if ((obj instanceof Transition.Match)) { | ||
180 | Transition.Match other = (Transition.Match) obj; | ||
181 | return Objects.equals(fT, other.fT) && Objects.equals(fSrc, other.fSrc) && Objects.equals(fTrg, other.fTrg); | ||
182 | } else { | ||
183 | // this should be infrequent | ||
184 | if (!(obj instanceof IPatternMatch)) { | ||
185 | return false; | ||
186 | } | ||
187 | IPatternMatch otherSig = (IPatternMatch) obj; | ||
188 | return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); | ||
189 | } | ||
190 | } | ||
191 | |||
192 | @Override | ||
193 | public Transition specification() { | ||
194 | return Transition.instance(); | ||
195 | } | ||
196 | |||
197 | /** | ||
198 | * Returns an empty, mutable match. | ||
199 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
200 | * | ||
201 | * @return the empty match. | ||
202 | * | ||
203 | */ | ||
204 | public static Transition.Match newEmptyMatch() { | ||
205 | return new Mutable(null, null, null); | ||
206 | } | ||
207 | |||
208 | /** | ||
209 | * Returns a mutable (partial) match. | ||
210 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
211 | * | ||
212 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
213 | * @param pSrc the fixed value of pattern parameter src, or null if not bound. | ||
214 | * @param pTrg the fixed value of pattern parameter trg, or null if not bound. | ||
215 | * @return the new, mutable (partial) match object. | ||
216 | * | ||
217 | */ | ||
218 | public static Transition.Match newMutableMatch(final ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition pT, final Vertex pSrc, final Vertex pTrg) { | ||
219 | return new Mutable(pT, pSrc, pTrg); | ||
220 | } | ||
221 | |||
222 | /** | ||
223 | * Returns a new (partial) match. | ||
224 | * This can be used e.g. to call the matcher with a partial match. | ||
225 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
226 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
227 | * @param pSrc the fixed value of pattern parameter src, or null if not bound. | ||
228 | * @param pTrg the fixed value of pattern parameter trg, or null if not bound. | ||
229 | * @return the (partial) match object. | ||
230 | * | ||
231 | */ | ||
232 | public static Transition.Match newMatch(final ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition pT, final Vertex pSrc, final Vertex pTrg) { | ||
233 | return new Immutable(pT, pSrc, pTrg); | ||
234 | } | ||
235 | |||
236 | private static final class Mutable extends Transition.Match { | ||
237 | Mutable(final ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition pT, final Vertex pSrc, final Vertex pTrg) { | ||
238 | super(pT, pSrc, pTrg); | ||
239 | } | ||
240 | |||
241 | @Override | ||
242 | public boolean isMutable() { | ||
243 | return true; | ||
244 | } | ||
245 | } | ||
246 | |||
247 | private static final class Immutable extends Transition.Match { | ||
248 | Immutable(final ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition pT, final Vertex pSrc, final Vertex pTrg) { | ||
249 | super(pT, pSrc, pTrg); | ||
250 | } | ||
251 | |||
252 | @Override | ||
253 | public boolean isMutable() { | ||
254 | return false; | ||
255 | } | ||
256 | } | ||
257 | } | ||
258 | |||
259 | /** | ||
260 | * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.transition pattern, | ||
261 | * providing pattern-specific query methods. | ||
262 | * | ||
263 | * <p>Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, | ||
264 | * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. | ||
265 | * | ||
266 | * <p>Matches of the pattern will be represented as {@link Match}. | ||
267 | * | ||
268 | * <p>Original source: | ||
269 | * <code><pre> | ||
270 | * pattern transition(t : Transition, src : Vertex, trg : Vertex) { | ||
271 | * Transition.source(t, src); | ||
272 | * Transition.target(t, trg); | ||
273 | * } | ||
274 | * </pre></code> | ||
275 | * | ||
276 | * @see Match | ||
277 | * @see Transition | ||
278 | * | ||
279 | */ | ||
280 | public static class Matcher extends BaseMatcher<Transition.Match> { | ||
281 | /** | ||
282 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
283 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
284 | * | ||
285 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
286 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
287 | * | ||
288 | */ | ||
289 | public static Transition.Matcher on(final ViatraQueryEngine engine) { | ||
290 | // check if matcher already exists | ||
291 | Matcher matcher = engine.getExistingMatcher(querySpecification()); | ||
292 | if (matcher == null) { | ||
293 | matcher = (Matcher)engine.getMatcher(querySpecification()); | ||
294 | } | ||
295 | return matcher; | ||
296 | } | ||
297 | |||
298 | /** | ||
299 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
300 | * @return an initialized matcher | ||
301 | * @noreference This method is for internal matcher initialization by the framework, do not call it manually. | ||
302 | * | ||
303 | */ | ||
304 | public static Transition.Matcher create() { | ||
305 | return new Matcher(); | ||
306 | } | ||
307 | |||
308 | private final static int POSITION_T = 0; | ||
309 | |||
310 | private final static int POSITION_SRC = 1; | ||
311 | |||
312 | private final static int POSITION_TRG = 2; | ||
313 | |||
314 | private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(Transition.Matcher.class); | ||
315 | |||
316 | /** | ||
317 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
318 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
319 | * | ||
320 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
321 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
322 | * | ||
323 | */ | ||
324 | private Matcher() { | ||
325 | super(querySpecification()); | ||
326 | } | ||
327 | |||
328 | /** | ||
329 | * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. | ||
330 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
331 | * @param pSrc the fixed value of pattern parameter src, or null if not bound. | ||
332 | * @param pTrg the fixed value of pattern parameter trg, or null if not bound. | ||
333 | * @return matches represented as a Match object. | ||
334 | * | ||
335 | */ | ||
336 | public Collection<Transition.Match> getAllMatches(final ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition pT, final Vertex pSrc, final Vertex pTrg) { | ||
337 | return rawStreamAllMatches(new Object[]{pT, pSrc, pTrg}).collect(Collectors.toSet()); | ||
338 | } | ||
339 | |||
340 | /** | ||
341 | * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. | ||
342 | * </p> | ||
343 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
344 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
345 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
346 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
347 | * @param pSrc the fixed value of pattern parameter src, or null if not bound. | ||
348 | * @param pTrg the fixed value of pattern parameter trg, or null if not bound. | ||
349 | * @return a stream of matches represented as a Match object. | ||
350 | * | ||
351 | */ | ||
352 | public Stream<Transition.Match> streamAllMatches(final ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition pT, final Vertex pSrc, final Vertex pTrg) { | ||
353 | return rawStreamAllMatches(new Object[]{pT, pSrc, pTrg}); | ||
354 | } | ||
355 | |||
356 | /** | ||
357 | * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
358 | * Neither determinism nor randomness of selection is guaranteed. | ||
359 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
360 | * @param pSrc the fixed value of pattern parameter src, or null if not bound. | ||
361 | * @param pTrg the fixed value of pattern parameter trg, or null if not bound. | ||
362 | * @return a match represented as a Match object, or null if no match is found. | ||
363 | * | ||
364 | */ | ||
365 | public Optional<Transition.Match> getOneArbitraryMatch(final ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition pT, final Vertex pSrc, final Vertex pTrg) { | ||
366 | return rawGetOneArbitraryMatch(new Object[]{pT, pSrc, pTrg}); | ||
367 | } | ||
368 | |||
369 | /** | ||
370 | * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, | ||
371 | * under any possible substitution of the unspecified parameters (if any). | ||
372 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
373 | * @param pSrc the fixed value of pattern parameter src, or null if not bound. | ||
374 | * @param pTrg the fixed value of pattern parameter trg, or null if not bound. | ||
375 | * @return true if the input is a valid (partial) match of the pattern. | ||
376 | * | ||
377 | */ | ||
378 | public boolean hasMatch(final ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition pT, final Vertex pSrc, final Vertex pTrg) { | ||
379 | return rawHasMatch(new Object[]{pT, pSrc, pTrg}); | ||
380 | } | ||
381 | |||
382 | /** | ||
383 | * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. | ||
384 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
385 | * @param pSrc the fixed value of pattern parameter src, or null if not bound. | ||
386 | * @param pTrg the fixed value of pattern parameter trg, or null if not bound. | ||
387 | * @return the number of pattern matches found. | ||
388 | * | ||
389 | */ | ||
390 | public int countMatches(final ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition pT, final Vertex pSrc, final Vertex pTrg) { | ||
391 | return rawCountMatches(new Object[]{pT, pSrc, pTrg}); | ||
392 | } | ||
393 | |||
394 | /** | ||
395 | * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
396 | * Neither determinism nor randomness of selection is guaranteed. | ||
397 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
398 | * @param pSrc the fixed value of pattern parameter src, or null if not bound. | ||
399 | * @param pTrg the fixed value of pattern parameter trg, or null if not bound. | ||
400 | * @param processor the action that will process the selected match. | ||
401 | * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked | ||
402 | * | ||
403 | */ | ||
404 | public boolean forOneArbitraryMatch(final ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition pT, final Vertex pSrc, final Vertex pTrg, final Consumer<? super Transition.Match> processor) { | ||
405 | return rawForOneArbitraryMatch(new Object[]{pT, pSrc, pTrg}, processor); | ||
406 | } | ||
407 | |||
408 | /** | ||
409 | * Returns a new (partial) match. | ||
410 | * This can be used e.g. to call the matcher with a partial match. | ||
411 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
412 | * @param pT the fixed value of pattern parameter t, or null if not bound. | ||
413 | * @param pSrc the fixed value of pattern parameter src, or null if not bound. | ||
414 | * @param pTrg the fixed value of pattern parameter trg, or null if not bound. | ||
415 | * @return the (partial) match object. | ||
416 | * | ||
417 | */ | ||
418 | public Transition.Match newMatch(final ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition pT, final Vertex pSrc, final Vertex pTrg) { | ||
419 | return Transition.Match.newMatch(pT, pSrc, pTrg); | ||
420 | } | ||
421 | |||
422 | /** | ||
423 | * Retrieve the set of values that occur in matches for t. | ||
424 | * @return the Set of all values or empty set if there are no matches | ||
425 | * | ||
426 | */ | ||
427 | protected Stream<ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition> rawStreamAllValuesOft(final Object[] parameters) { | ||
428 | return rawStreamAllValues(POSITION_T, parameters).map(ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition.class::cast); | ||
429 | } | ||
430 | |||
431 | /** | ||
432 | * Retrieve the set of values that occur in matches for t. | ||
433 | * @return the Set of all values or empty set if there are no matches | ||
434 | * | ||
435 | */ | ||
436 | public Set<ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition> getAllValuesOft() { | ||
437 | return rawStreamAllValuesOft(emptyArray()).collect(Collectors.toSet()); | ||
438 | } | ||
439 | |||
440 | /** | ||
441 | * Retrieve the set of values that occur in matches for t. | ||
442 | * @return the Set of all values or empty set if there are no matches | ||
443 | * | ||
444 | */ | ||
445 | public Stream<ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition> streamAllValuesOft() { | ||
446 | return rawStreamAllValuesOft(emptyArray()); | ||
447 | } | ||
448 | |||
449 | /** | ||
450 | * Retrieve the set of values that occur in matches for t. | ||
451 | * </p> | ||
452 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
453 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
454 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
455 | * | ||
456 | * @return the Stream of all values or empty set if there are no matches | ||
457 | * | ||
458 | */ | ||
459 | public Stream<ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition> streamAllValuesOft(final Transition.Match partialMatch) { | ||
460 | return rawStreamAllValuesOft(partialMatch.toArray()); | ||
461 | } | ||
462 | |||
463 | /** | ||
464 | * Retrieve the set of values that occur in matches for t. | ||
465 | * </p> | ||
466 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
467 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
468 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
469 | * | ||
470 | * @return the Stream of all values or empty set if there are no matches | ||
471 | * | ||
472 | */ | ||
473 | public Stream<ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition> streamAllValuesOft(final Vertex pSrc, final Vertex pTrg) { | ||
474 | return rawStreamAllValuesOft(new Object[]{null, pSrc, pTrg}); | ||
475 | } | ||
476 | |||
477 | /** | ||
478 | * Retrieve the set of values that occur in matches for t. | ||
479 | * @return the Set of all values or empty set if there are no matches | ||
480 | * | ||
481 | */ | ||
482 | public Set<ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition> getAllValuesOft(final Transition.Match partialMatch) { | ||
483 | return rawStreamAllValuesOft(partialMatch.toArray()).collect(Collectors.toSet()); | ||
484 | } | ||
485 | |||
486 | /** | ||
487 | * Retrieve the set of values that occur in matches for t. | ||
488 | * @return the Set of all values or empty set if there are no matches | ||
489 | * | ||
490 | */ | ||
491 | public Set<ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition> getAllValuesOft(final Vertex pSrc, final Vertex pTrg) { | ||
492 | return rawStreamAllValuesOft(new Object[]{null, pSrc, pTrg}).collect(Collectors.toSet()); | ||
493 | } | ||
494 | |||
495 | /** | ||
496 | * Retrieve the set of values that occur in matches for src. | ||
497 | * @return the Set of all values or empty set if there are no matches | ||
498 | * | ||
499 | */ | ||
500 | protected Stream<Vertex> rawStreamAllValuesOfsrc(final Object[] parameters) { | ||
501 | return rawStreamAllValues(POSITION_SRC, parameters).map(Vertex.class::cast); | ||
502 | } | ||
503 | |||
504 | /** | ||
505 | * Retrieve the set of values that occur in matches for src. | ||
506 | * @return the Set of all values or empty set if there are no matches | ||
507 | * | ||
508 | */ | ||
509 | public Set<Vertex> getAllValuesOfsrc() { | ||
510 | return rawStreamAllValuesOfsrc(emptyArray()).collect(Collectors.toSet()); | ||
511 | } | ||
512 | |||
513 | /** | ||
514 | * Retrieve the set of values that occur in matches for src. | ||
515 | * @return the Set of all values or empty set if there are no matches | ||
516 | * | ||
517 | */ | ||
518 | public Stream<Vertex> streamAllValuesOfsrc() { | ||
519 | return rawStreamAllValuesOfsrc(emptyArray()); | ||
520 | } | ||
521 | |||
522 | /** | ||
523 | * Retrieve the set of values that occur in matches for src. | ||
524 | * </p> | ||
525 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
526 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
527 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
528 | * | ||
529 | * @return the Stream of all values or empty set if there are no matches | ||
530 | * | ||
531 | */ | ||
532 | public Stream<Vertex> streamAllValuesOfsrc(final Transition.Match partialMatch) { | ||
533 | return rawStreamAllValuesOfsrc(partialMatch.toArray()); | ||
534 | } | ||
535 | |||
536 | /** | ||
537 | * Retrieve the set of values that occur in matches for src. | ||
538 | * </p> | ||
539 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
540 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
541 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
542 | * | ||
543 | * @return the Stream of all values or empty set if there are no matches | ||
544 | * | ||
545 | */ | ||
546 | public Stream<Vertex> streamAllValuesOfsrc(final ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition pT, final Vertex pTrg) { | ||
547 | return rawStreamAllValuesOfsrc(new Object[]{pT, null, pTrg}); | ||
548 | } | ||
549 | |||
550 | /** | ||
551 | * Retrieve the set of values that occur in matches for src. | ||
552 | * @return the Set of all values or empty set if there are no matches | ||
553 | * | ||
554 | */ | ||
555 | public Set<Vertex> getAllValuesOfsrc(final Transition.Match partialMatch) { | ||
556 | return rawStreamAllValuesOfsrc(partialMatch.toArray()).collect(Collectors.toSet()); | ||
557 | } | ||
558 | |||
559 | /** | ||
560 | * Retrieve the set of values that occur in matches for src. | ||
561 | * @return the Set of all values or empty set if there are no matches | ||
562 | * | ||
563 | */ | ||
564 | public Set<Vertex> getAllValuesOfsrc(final ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition pT, final Vertex pTrg) { | ||
565 | return rawStreamAllValuesOfsrc(new Object[]{pT, null, pTrg}).collect(Collectors.toSet()); | ||
566 | } | ||
567 | |||
568 | /** | ||
569 | * Retrieve the set of values that occur in matches for trg. | ||
570 | * @return the Set of all values or empty set if there are no matches | ||
571 | * | ||
572 | */ | ||
573 | protected Stream<Vertex> rawStreamAllValuesOftrg(final Object[] parameters) { | ||
574 | return rawStreamAllValues(POSITION_TRG, parameters).map(Vertex.class::cast); | ||
575 | } | ||
576 | |||
577 | /** | ||
578 | * Retrieve the set of values that occur in matches for trg. | ||
579 | * @return the Set of all values or empty set if there are no matches | ||
580 | * | ||
581 | */ | ||
582 | public Set<Vertex> getAllValuesOftrg() { | ||
583 | return rawStreamAllValuesOftrg(emptyArray()).collect(Collectors.toSet()); | ||
584 | } | ||
585 | |||
586 | /** | ||
587 | * Retrieve the set of values that occur in matches for trg. | ||
588 | * @return the Set of all values or empty set if there are no matches | ||
589 | * | ||
590 | */ | ||
591 | public Stream<Vertex> streamAllValuesOftrg() { | ||
592 | return rawStreamAllValuesOftrg(emptyArray()); | ||
593 | } | ||
594 | |||
595 | /** | ||
596 | * Retrieve the set of values that occur in matches for trg. | ||
597 | * </p> | ||
598 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
599 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
600 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
601 | * | ||
602 | * @return the Stream of all values or empty set if there are no matches | ||
603 | * | ||
604 | */ | ||
605 | public Stream<Vertex> streamAllValuesOftrg(final Transition.Match partialMatch) { | ||
606 | return rawStreamAllValuesOftrg(partialMatch.toArray()); | ||
607 | } | ||
608 | |||
609 | /** | ||
610 | * Retrieve the set of values that occur in matches for trg. | ||
611 | * </p> | ||
612 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
613 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
614 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
615 | * | ||
616 | * @return the Stream of all values or empty set if there are no matches | ||
617 | * | ||
618 | */ | ||
619 | public Stream<Vertex> streamAllValuesOftrg(final ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition pT, final Vertex pSrc) { | ||
620 | return rawStreamAllValuesOftrg(new Object[]{pT, pSrc, null}); | ||
621 | } | ||
622 | |||
623 | /** | ||
624 | * Retrieve the set of values that occur in matches for trg. | ||
625 | * @return the Set of all values or empty set if there are no matches | ||
626 | * | ||
627 | */ | ||
628 | public Set<Vertex> getAllValuesOftrg(final Transition.Match partialMatch) { | ||
629 | return rawStreamAllValuesOftrg(partialMatch.toArray()).collect(Collectors.toSet()); | ||
630 | } | ||
631 | |||
632 | /** | ||
633 | * Retrieve the set of values that occur in matches for trg. | ||
634 | * @return the Set of all values or empty set if there are no matches | ||
635 | * | ||
636 | */ | ||
637 | public Set<Vertex> getAllValuesOftrg(final ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition pT, final Vertex pSrc) { | ||
638 | return rawStreamAllValuesOftrg(new Object[]{pT, pSrc, null}).collect(Collectors.toSet()); | ||
639 | } | ||
640 | |||
641 | @Override | ||
642 | protected Transition.Match tupleToMatch(final Tuple t) { | ||
643 | try { | ||
644 | return Transition.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition) t.get(POSITION_T), (Vertex) t.get(POSITION_SRC), (Vertex) t.get(POSITION_TRG)); | ||
645 | } catch(ClassCastException e) { | ||
646 | LOGGER.error("Element(s) in tuple not properly typed!",e); | ||
647 | return null; | ||
648 | } | ||
649 | } | ||
650 | |||
651 | @Override | ||
652 | protected Transition.Match arrayToMatch(final Object[] match) { | ||
653 | try { | ||
654 | return Transition.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition) match[POSITION_T], (Vertex) match[POSITION_SRC], (Vertex) match[POSITION_TRG]); | ||
655 | } catch(ClassCastException e) { | ||
656 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
657 | return null; | ||
658 | } | ||
659 | } | ||
660 | |||
661 | @Override | ||
662 | protected Transition.Match arrayToMatchMutable(final Object[] match) { | ||
663 | try { | ||
664 | return Transition.Match.newMutableMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition) match[POSITION_T], (Vertex) match[POSITION_SRC], (Vertex) match[POSITION_TRG]); | ||
665 | } catch(ClassCastException e) { | ||
666 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
667 | return null; | ||
668 | } | ||
669 | } | ||
670 | |||
671 | /** | ||
672 | * @return the singleton instance of the query specification of this pattern | ||
673 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
674 | * | ||
675 | */ | ||
676 | public static IQuerySpecification<Transition.Matcher> querySpecification() { | ||
677 | return Transition.instance(); | ||
678 | } | ||
679 | } | ||
680 | |||
681 | private Transition() { | ||
682 | super(GeneratedPQuery.INSTANCE); | ||
683 | } | ||
684 | |||
685 | /** | ||
686 | * @return the singleton instance of the query specification | ||
687 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
688 | * | ||
689 | */ | ||
690 | public static Transition instance() { | ||
691 | try{ | ||
692 | return LazyHolder.INSTANCE; | ||
693 | } catch (ExceptionInInitializerError err) { | ||
694 | throw processInitializerError(err); | ||
695 | } | ||
696 | } | ||
697 | |||
698 | @Override | ||
699 | protected Transition.Matcher instantiate(final ViatraQueryEngine engine) { | ||
700 | return Transition.Matcher.on(engine); | ||
701 | } | ||
702 | |||
703 | @Override | ||
704 | public Transition.Matcher instantiate() { | ||
705 | return Transition.Matcher.create(); | ||
706 | } | ||
707 | |||
708 | @Override | ||
709 | public Transition.Match newEmptyMatch() { | ||
710 | return Transition.Match.newEmptyMatch(); | ||
711 | } | ||
712 | |||
713 | @Override | ||
714 | public Transition.Match newMatch(final Object... parameters) { | ||
715 | return Transition.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition) parameters[0], (ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex) parameters[1], (ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex) parameters[2]); | ||
716 | } | ||
717 | |||
718 | /** | ||
719 | * Inner class allowing the singleton instance of {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.Transition (visibility: PUBLIC, simpleName: Transition, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.Transition, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created | ||
720 | * <b>not</b> at the class load time of the outer class, | ||
721 | * but rather at the first call to {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.Transition (visibility: PUBLIC, simpleName: Transition, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.Transition, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. | ||
722 | * | ||
723 | * <p> This workaround is required e.g. to support recursion. | ||
724 | * | ||
725 | */ | ||
726 | private static class LazyHolder { | ||
727 | private final static Transition INSTANCE = new Transition(); | ||
728 | |||
729 | /** | ||
730 | * Statically initializes the query specification <b>after</b> the field {@link #INSTANCE} is assigned. | ||
731 | * This initialization order is required to support indirect recursion. | ||
732 | * | ||
733 | * <p> The static initializer is defined using a helper field to work around limitations of the code generator. | ||
734 | * | ||
735 | */ | ||
736 | private final static Object STATIC_INITIALIZER = ensureInitialized(); | ||
737 | |||
738 | public static Object ensureInitialized() { | ||
739 | INSTANCE.ensureInitializedInternal(); | ||
740 | return null; | ||
741 | } | ||
742 | } | ||
743 | |||
744 | private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { | ||
745 | private final static Transition.GeneratedPQuery INSTANCE = new GeneratedPQuery(); | ||
746 | |||
747 | private final PParameter parameter_t = new PParameter("t", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Transition")), PParameterDirection.INOUT); | ||
748 | |||
749 | private final PParameter parameter_src = new PParameter("src", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Vertex")), PParameterDirection.INOUT); | ||
750 | |||
751 | private final PParameter parameter_trg = new PParameter("trg", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Vertex")), PParameterDirection.INOUT); | ||
752 | |||
753 | private final List<PParameter> parameters = Arrays.asList(parameter_t, parameter_src, parameter_trg); | ||
754 | |||
755 | private GeneratedPQuery() { | ||
756 | super(PVisibility.PUBLIC); | ||
757 | } | ||
758 | |||
759 | @Override | ||
760 | public String getFullyQualifiedName() { | ||
761 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.transition"; | ||
762 | } | ||
763 | |||
764 | @Override | ||
765 | public List<String> getParameterNames() { | ||
766 | return Arrays.asList("t","src","trg"); | ||
767 | } | ||
768 | |||
769 | @Override | ||
770 | public List<PParameter> getParameters() { | ||
771 | return parameters; | ||
772 | } | ||
773 | |||
774 | @Override | ||
775 | public Set<PBody> doGetContainedBodies() { | ||
776 | setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); | ||
777 | Set<PBody> bodies = new LinkedHashSet<>(); | ||
778 | { | ||
779 | PBody body = new PBody(this); | ||
780 | PVariable var_t = body.getOrCreateVariableByName("t"); | ||
781 | PVariable var_src = body.getOrCreateVariableByName("src"); | ||
782 | PVariable var_trg = body.getOrCreateVariableByName("trg"); | ||
783 | new TypeConstraint(body, Tuples.flatTupleOf(var_t), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); | ||
784 | new TypeConstraint(body, Tuples.flatTupleOf(var_src), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); | ||
785 | new TypeConstraint(body, Tuples.flatTupleOf(var_trg), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); | ||
786 | body.setSymbolicParameters(Arrays.<ExportedParameter>asList( | ||
787 | new ExportedParameter(body, var_t, parameter_t), | ||
788 | new ExportedParameter(body, var_src, parameter_src), | ||
789 | new ExportedParameter(body, var_trg, parameter_trg) | ||
790 | )); | ||
791 | // Transition.source(t, src) | ||
792 | new TypeConstraint(body, Tuples.flatTupleOf(var_t), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); | ||
793 | PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); | ||
794 | new TypeConstraint(body, Tuples.flatTupleOf(var_t, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Transition", "source"))); | ||
795 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); | ||
796 | new Equality(body, var__virtual_0_, var_src); | ||
797 | // Transition.target(t, trg) | ||
798 | new TypeConstraint(body, Tuples.flatTupleOf(var_t), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); | ||
799 | PVariable var__virtual_1_ = body.getOrCreateVariableByName(".virtual{1}"); | ||
800 | new TypeConstraint(body, Tuples.flatTupleOf(var_t, var__virtual_1_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Transition", "target"))); | ||
801 | new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_1_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); | ||
802 | new Equality(body, var__virtual_1_, var_trg); | ||
803 | bodies.add(body); | ||
804 | } | ||
805 | return bodies; | ||
806 | } | ||
807 | } | ||
808 | } | ||
diff --git a/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/TwoSynch.java b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/TwoSynch.java new file mode 100644 index 00000000..4595f6bc --- /dev/null +++ b/Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/TwoSynch.java | |||
@@ -0,0 +1,714 @@ | |||
1 | /** | ||
2 | * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql | ||
3 | */ | ||
4 | package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; | ||
5 | |||
6 | import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization; | ||
7 | import java.util.Arrays; | ||
8 | import java.util.Collection; | ||
9 | import java.util.LinkedHashSet; | ||
10 | import java.util.List; | ||
11 | import java.util.Objects; | ||
12 | import java.util.Optional; | ||
13 | import java.util.Set; | ||
14 | import java.util.function.Consumer; | ||
15 | import java.util.stream.Collectors; | ||
16 | import java.util.stream.Stream; | ||
17 | import org.apache.log4j.Logger; | ||
18 | import org.eclipse.emf.ecore.EClass; | ||
19 | import org.eclipse.viatra.query.runtime.api.IPatternMatch; | ||
20 | import org.eclipse.viatra.query.runtime.api.IQuerySpecification; | ||
21 | import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; | ||
22 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; | ||
23 | import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; | ||
24 | import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; | ||
25 | import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; | ||
26 | import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; | ||
27 | import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; | ||
28 | import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; | ||
29 | import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; | ||
30 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; | ||
31 | import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; | ||
32 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; | ||
33 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Inequality; | ||
34 | import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; | ||
35 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; | ||
36 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; | ||
37 | import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; | ||
38 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; | ||
39 | import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; | ||
40 | import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; | ||
41 | |||
42 | /** | ||
43 | * A pattern-specific query specification that can instantiate Matcher in a type-safe way. | ||
44 | * | ||
45 | * <p>Original source: | ||
46 | * <code><pre> | ||
47 | * Simplifying model generation | ||
48 | * | ||
49 | * {@literal @}Constraint(severity="error", message="error", key = {s1,s2}) | ||
50 | * pattern twoSynch(s1 : Synchronization, s2 : Synchronization) { | ||
51 | * Synchronization(s1); | ||
52 | * Synchronization(s2); | ||
53 | * s1 != s2; | ||
54 | * } | ||
55 | * </pre></code> | ||
56 | * | ||
57 | * @see Matcher | ||
58 | * @see Match | ||
59 | * | ||
60 | */ | ||
61 | @SuppressWarnings("all") | ||
62 | public final class TwoSynch extends BaseGeneratedEMFQuerySpecification<TwoSynch.Matcher> { | ||
63 | /** | ||
64 | * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.twoSynch pattern, | ||
65 | * to be used in conjunction with {@link Matcher}. | ||
66 | * | ||
67 | * <p>Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. | ||
68 | * Each instance is a (possibly partial) substitution of pattern parameters, | ||
69 | * usable to represent a match of the pattern in the result of a query, | ||
70 | * or to specify the bound (fixed) input parameters when issuing a query. | ||
71 | * | ||
72 | * @see Matcher | ||
73 | * | ||
74 | */ | ||
75 | public static abstract class Match extends BasePatternMatch { | ||
76 | private Synchronization fS1; | ||
77 | |||
78 | private Synchronization fS2; | ||
79 | |||
80 | private static List<String> parameterNames = makeImmutableList("s1", "s2"); | ||
81 | |||
82 | private Match(final Synchronization pS1, final Synchronization pS2) { | ||
83 | this.fS1 = pS1; | ||
84 | this.fS2 = pS2; | ||
85 | } | ||
86 | |||
87 | @Override | ||
88 | public Object get(final String parameterName) { | ||
89 | if ("s1".equals(parameterName)) return this.fS1; | ||
90 | if ("s2".equals(parameterName)) return this.fS2; | ||
91 | return null; | ||
92 | } | ||
93 | |||
94 | public Synchronization getS1() { | ||
95 | return this.fS1; | ||
96 | } | ||
97 | |||
98 | public Synchronization getS2() { | ||
99 | return this.fS2; | ||
100 | } | ||
101 | |||
102 | @Override | ||
103 | public boolean set(final String parameterName, final Object newValue) { | ||
104 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
105 | if ("s1".equals(parameterName) ) { | ||
106 | this.fS1 = (Synchronization) newValue; | ||
107 | return true; | ||
108 | } | ||
109 | if ("s2".equals(parameterName) ) { | ||
110 | this.fS2 = (Synchronization) newValue; | ||
111 | return true; | ||
112 | } | ||
113 | return false; | ||
114 | } | ||
115 | |||
116 | public void setS1(final Synchronization pS1) { | ||
117 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
118 | this.fS1 = pS1; | ||
119 | } | ||
120 | |||
121 | public void setS2(final Synchronization pS2) { | ||
122 | if (!isMutable()) throw new java.lang.UnsupportedOperationException(); | ||
123 | this.fS2 = pS2; | ||
124 | } | ||
125 | |||
126 | @Override | ||
127 | public String patternName() { | ||
128 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.twoSynch"; | ||
129 | } | ||
130 | |||
131 | @Override | ||
132 | public List<String> parameterNames() { | ||
133 | return TwoSynch.Match.parameterNames; | ||
134 | } | ||
135 | |||
136 | @Override | ||
137 | public Object[] toArray() { | ||
138 | return new Object[]{fS1, fS2}; | ||
139 | } | ||
140 | |||
141 | @Override | ||
142 | public TwoSynch.Match toImmutable() { | ||
143 | return isMutable() ? newMatch(fS1, fS2) : this; | ||
144 | } | ||
145 | |||
146 | @Override | ||
147 | public String prettyPrint() { | ||
148 | StringBuilder result = new StringBuilder(); | ||
149 | result.append("\"s1\"=" + prettyPrintValue(fS1) + ", "); | ||
150 | result.append("\"s2\"=" + prettyPrintValue(fS2)); | ||
151 | return result.toString(); | ||
152 | } | ||
153 | |||
154 | @Override | ||
155 | public int hashCode() { | ||
156 | return Objects.hash(fS1, fS2); | ||
157 | } | ||
158 | |||
159 | @Override | ||
160 | public boolean equals(final Object obj) { | ||
161 | if (this == obj) | ||
162 | return true; | ||
163 | if (obj == null) { | ||
164 | return false; | ||
165 | } | ||
166 | if ((obj instanceof TwoSynch.Match)) { | ||
167 | TwoSynch.Match other = (TwoSynch.Match) obj; | ||
168 | return Objects.equals(fS1, other.fS1) && Objects.equals(fS2, other.fS2); | ||
169 | } else { | ||
170 | // this should be infrequent | ||
171 | if (!(obj instanceof IPatternMatch)) { | ||
172 | return false; | ||
173 | } | ||
174 | IPatternMatch otherSig = (IPatternMatch) obj; | ||
175 | return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); | ||
176 | } | ||
177 | } | ||
178 | |||
179 | @Override | ||
180 | public TwoSynch specification() { | ||
181 | return TwoSynch.instance(); | ||
182 | } | ||
183 | |||
184 | /** | ||
185 | * Returns an empty, mutable match. | ||
186 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
187 | * | ||
188 | * @return the empty match. | ||
189 | * | ||
190 | */ | ||
191 | public static TwoSynch.Match newEmptyMatch() { | ||
192 | return new Mutable(null, null); | ||
193 | } | ||
194 | |||
195 | /** | ||
196 | * Returns a mutable (partial) match. | ||
197 | * Fields of the mutable match can be filled to create a partial match, usable as matcher input. | ||
198 | * | ||
199 | * @param pS1 the fixed value of pattern parameter s1, or null if not bound. | ||
200 | * @param pS2 the fixed value of pattern parameter s2, or null if not bound. | ||
201 | * @return the new, mutable (partial) match object. | ||
202 | * | ||
203 | */ | ||
204 | public static TwoSynch.Match newMutableMatch(final Synchronization pS1, final Synchronization pS2) { | ||
205 | return new Mutable(pS1, pS2); | ||
206 | } | ||
207 | |||
208 | /** | ||
209 | * Returns a new (partial) match. | ||
210 | * This can be used e.g. to call the matcher with a partial match. | ||
211 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
212 | * @param pS1 the fixed value of pattern parameter s1, or null if not bound. | ||
213 | * @param pS2 the fixed value of pattern parameter s2, or null if not bound. | ||
214 | * @return the (partial) match object. | ||
215 | * | ||
216 | */ | ||
217 | public static TwoSynch.Match newMatch(final Synchronization pS1, final Synchronization pS2) { | ||
218 | return new Immutable(pS1, pS2); | ||
219 | } | ||
220 | |||
221 | private static final class Mutable extends TwoSynch.Match { | ||
222 | Mutable(final Synchronization pS1, final Synchronization pS2) { | ||
223 | super(pS1, pS2); | ||
224 | } | ||
225 | |||
226 | @Override | ||
227 | public boolean isMutable() { | ||
228 | return true; | ||
229 | } | ||
230 | } | ||
231 | |||
232 | private static final class Immutable extends TwoSynch.Match { | ||
233 | Immutable(final Synchronization pS1, final Synchronization pS2) { | ||
234 | super(pS1, pS2); | ||
235 | } | ||
236 | |||
237 | @Override | ||
238 | public boolean isMutable() { | ||
239 | return false; | ||
240 | } | ||
241 | } | ||
242 | } | ||
243 | |||
244 | /** | ||
245 | * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.twoSynch pattern, | ||
246 | * providing pattern-specific query methods. | ||
247 | * | ||
248 | * <p>Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, | ||
249 | * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. | ||
250 | * | ||
251 | * <p>Matches of the pattern will be represented as {@link Match}. | ||
252 | * | ||
253 | * <p>Original source: | ||
254 | * <code><pre> | ||
255 | * Simplifying model generation | ||
256 | * | ||
257 | * {@literal @}Constraint(severity="error", message="error", key = {s1,s2}) | ||
258 | * pattern twoSynch(s1 : Synchronization, s2 : Synchronization) { | ||
259 | * Synchronization(s1); | ||
260 | * Synchronization(s2); | ||
261 | * s1 != s2; | ||
262 | * } | ||
263 | * </pre></code> | ||
264 | * | ||
265 | * @see Match | ||
266 | * @see TwoSynch | ||
267 | * | ||
268 | */ | ||
269 | public static class Matcher extends BaseMatcher<TwoSynch.Match> { | ||
270 | /** | ||
271 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
272 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
273 | * | ||
274 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
275 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
276 | * | ||
277 | */ | ||
278 | public static TwoSynch.Matcher on(final ViatraQueryEngine engine) { | ||
279 | // check if matcher already exists | ||
280 | Matcher matcher = engine.getExistingMatcher(querySpecification()); | ||
281 | if (matcher == null) { | ||
282 | matcher = (Matcher)engine.getMatcher(querySpecification()); | ||
283 | } | ||
284 | return matcher; | ||
285 | } | ||
286 | |||
287 | /** | ||
288 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
289 | * @return an initialized matcher | ||
290 | * @noreference This method is for internal matcher initialization by the framework, do not call it manually. | ||
291 | * | ||
292 | */ | ||
293 | public static TwoSynch.Matcher create() { | ||
294 | return new Matcher(); | ||
295 | } | ||
296 | |||
297 | private final static int POSITION_S1 = 0; | ||
298 | |||
299 | private final static int POSITION_S2 = 1; | ||
300 | |||
301 | private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(TwoSynch.Matcher.class); | ||
302 | |||
303 | /** | ||
304 | * Initializes the pattern matcher within an existing VIATRA Query engine. | ||
305 | * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. | ||
306 | * | ||
307 | * @param engine the existing VIATRA Query engine in which this matcher will be created. | ||
308 | * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation | ||
309 | * | ||
310 | */ | ||
311 | private Matcher() { | ||
312 | super(querySpecification()); | ||
313 | } | ||
314 | |||
315 | /** | ||
316 | * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. | ||
317 | * @param pS1 the fixed value of pattern parameter s1, or null if not bound. | ||
318 | * @param pS2 the fixed value of pattern parameter s2, or null if not bound. | ||
319 | * @return matches represented as a Match object. | ||
320 | * | ||
321 | */ | ||
322 | public Collection<TwoSynch.Match> getAllMatches(final Synchronization pS1, final Synchronization pS2) { | ||
323 | return rawStreamAllMatches(new Object[]{pS1, pS2}).collect(Collectors.toSet()); | ||
324 | } | ||
325 | |||
326 | /** | ||
327 | * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. | ||
328 | * </p> | ||
329 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
330 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
331 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
332 | * @param pS1 the fixed value of pattern parameter s1, or null if not bound. | ||
333 | * @param pS2 the fixed value of pattern parameter s2, or null if not bound. | ||
334 | * @return a stream of matches represented as a Match object. | ||
335 | * | ||
336 | */ | ||
337 | public Stream<TwoSynch.Match> streamAllMatches(final Synchronization pS1, final Synchronization pS2) { | ||
338 | return rawStreamAllMatches(new Object[]{pS1, pS2}); | ||
339 | } | ||
340 | |||
341 | /** | ||
342 | * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
343 | * Neither determinism nor randomness of selection is guaranteed. | ||
344 | * @param pS1 the fixed value of pattern parameter s1, or null if not bound. | ||
345 | * @param pS2 the fixed value of pattern parameter s2, or null if not bound. | ||
346 | * @return a match represented as a Match object, or null if no match is found. | ||
347 | * | ||
348 | */ | ||
349 | public Optional<TwoSynch.Match> getOneArbitraryMatch(final Synchronization pS1, final Synchronization pS2) { | ||
350 | return rawGetOneArbitraryMatch(new Object[]{pS1, pS2}); | ||
351 | } | ||
352 | |||
353 | /** | ||
354 | * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, | ||
355 | * under any possible substitution of the unspecified parameters (if any). | ||
356 | * @param pS1 the fixed value of pattern parameter s1, or null if not bound. | ||
357 | * @param pS2 the fixed value of pattern parameter s2, or null if not bound. | ||
358 | * @return true if the input is a valid (partial) match of the pattern. | ||
359 | * | ||
360 | */ | ||
361 | public boolean hasMatch(final Synchronization pS1, final Synchronization pS2) { | ||
362 | return rawHasMatch(new Object[]{pS1, pS2}); | ||
363 | } | ||
364 | |||
365 | /** | ||
366 | * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. | ||
367 | * @param pS1 the fixed value of pattern parameter s1, or null if not bound. | ||
368 | * @param pS2 the fixed value of pattern parameter s2, or null if not bound. | ||
369 | * @return the number of pattern matches found. | ||
370 | * | ||
371 | */ | ||
372 | public int countMatches(final Synchronization pS1, final Synchronization pS2) { | ||
373 | return rawCountMatches(new Object[]{pS1, pS2}); | ||
374 | } | ||
375 | |||
376 | /** | ||
377 | * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. | ||
378 | * Neither determinism nor randomness of selection is guaranteed. | ||
379 | * @param pS1 the fixed value of pattern parameter s1, or null if not bound. | ||
380 | * @param pS2 the fixed value of pattern parameter s2, or null if not bound. | ||
381 | * @param processor the action that will process the selected match. | ||
382 | * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked | ||
383 | * | ||
384 | */ | ||
385 | public boolean forOneArbitraryMatch(final Synchronization pS1, final Synchronization pS2, final Consumer<? super TwoSynch.Match> processor) { | ||
386 | return rawForOneArbitraryMatch(new Object[]{pS1, pS2}, processor); | ||
387 | } | ||
388 | |||
389 | /** | ||
390 | * Returns a new (partial) match. | ||
391 | * This can be used e.g. to call the matcher with a partial match. | ||
392 | * <p>The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. | ||
393 | * @param pS1 the fixed value of pattern parameter s1, or null if not bound. | ||
394 | * @param pS2 the fixed value of pattern parameter s2, or null if not bound. | ||
395 | * @return the (partial) match object. | ||
396 | * | ||
397 | */ | ||
398 | public TwoSynch.Match newMatch(final Synchronization pS1, final Synchronization pS2) { | ||
399 | return TwoSynch.Match.newMatch(pS1, pS2); | ||
400 | } | ||
401 | |||
402 | /** | ||
403 | * Retrieve the set of values that occur in matches for s1. | ||
404 | * @return the Set of all values or empty set if there are no matches | ||
405 | * | ||
406 | */ | ||
407 | protected Stream<Synchronization> rawStreamAllValuesOfs1(final Object[] parameters) { | ||
408 | return rawStreamAllValues(POSITION_S1, parameters).map(Synchronization.class::cast); | ||
409 | } | ||
410 | |||
411 | /** | ||
412 | * Retrieve the set of values that occur in matches for s1. | ||
413 | * @return the Set of all values or empty set if there are no matches | ||
414 | * | ||
415 | */ | ||
416 | public Set<Synchronization> getAllValuesOfs1() { | ||
417 | return rawStreamAllValuesOfs1(emptyArray()).collect(Collectors.toSet()); | ||
418 | } | ||
419 | |||
420 | /** | ||
421 | * Retrieve the set of values that occur in matches for s1. | ||
422 | * @return the Set of all values or empty set if there are no matches | ||
423 | * | ||
424 | */ | ||
425 | public Stream<Synchronization> streamAllValuesOfs1() { | ||
426 | return rawStreamAllValuesOfs1(emptyArray()); | ||
427 | } | ||
428 | |||
429 | /** | ||
430 | * Retrieve the set of values that occur in matches for s1. | ||
431 | * </p> | ||
432 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
433 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
434 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
435 | * | ||
436 | * @return the Stream of all values or empty set if there are no matches | ||
437 | * | ||
438 | */ | ||
439 | public Stream<Synchronization> streamAllValuesOfs1(final TwoSynch.Match partialMatch) { | ||
440 | return rawStreamAllValuesOfs1(partialMatch.toArray()); | ||
441 | } | ||
442 | |||
443 | /** | ||
444 | * Retrieve the set of values that occur in matches for s1. | ||
445 | * </p> | ||
446 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
447 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
448 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
449 | * | ||
450 | * @return the Stream of all values or empty set if there are no matches | ||
451 | * | ||
452 | */ | ||
453 | public Stream<Synchronization> streamAllValuesOfs1(final Synchronization pS2) { | ||
454 | return rawStreamAllValuesOfs1(new Object[]{null, pS2}); | ||
455 | } | ||
456 | |||
457 | /** | ||
458 | * Retrieve the set of values that occur in matches for s1. | ||
459 | * @return the Set of all values or empty set if there are no matches | ||
460 | * | ||
461 | */ | ||
462 | public Set<Synchronization> getAllValuesOfs1(final TwoSynch.Match partialMatch) { | ||
463 | return rawStreamAllValuesOfs1(partialMatch.toArray()).collect(Collectors.toSet()); | ||
464 | } | ||
465 | |||
466 | /** | ||
467 | * Retrieve the set of values that occur in matches for s1. | ||
468 | * @return the Set of all values or empty set if there are no matches | ||
469 | * | ||
470 | */ | ||
471 | public Set<Synchronization> getAllValuesOfs1(final Synchronization pS2) { | ||
472 | return rawStreamAllValuesOfs1(new Object[]{null, pS2}).collect(Collectors.toSet()); | ||
473 | } | ||
474 | |||
475 | /** | ||
476 | * Retrieve the set of values that occur in matches for s2. | ||
477 | * @return the Set of all values or empty set if there are no matches | ||
478 | * | ||
479 | */ | ||
480 | protected Stream<Synchronization> rawStreamAllValuesOfs2(final Object[] parameters) { | ||
481 | return rawStreamAllValues(POSITION_S2, parameters).map(Synchronization.class::cast); | ||
482 | } | ||
483 | |||
484 | /** | ||
485 | * Retrieve the set of values that occur in matches for s2. | ||
486 | * @return the Set of all values or empty set if there are no matches | ||
487 | * | ||
488 | */ | ||
489 | public Set<Synchronization> getAllValuesOfs2() { | ||
490 | return rawStreamAllValuesOfs2(emptyArray()).collect(Collectors.toSet()); | ||
491 | } | ||
492 | |||
493 | /** | ||
494 | * Retrieve the set of values that occur in matches for s2. | ||
495 | * @return the Set of all values or empty set if there are no matches | ||
496 | * | ||
497 | */ | ||
498 | public Stream<Synchronization> streamAllValuesOfs2() { | ||
499 | return rawStreamAllValuesOfs2(emptyArray()); | ||
500 | } | ||
501 | |||
502 | /** | ||
503 | * Retrieve the set of values that occur in matches for s2. | ||
504 | * </p> | ||
505 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
506 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
507 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
508 | * | ||
509 | * @return the Stream of all values or empty set if there are no matches | ||
510 | * | ||
511 | */ | ||
512 | public Stream<Synchronization> streamAllValuesOfs2(final TwoSynch.Match partialMatch) { | ||
513 | return rawStreamAllValuesOfs2(partialMatch.toArray()); | ||
514 | } | ||
515 | |||
516 | /** | ||
517 | * Retrieve the set of values that occur in matches for s2. | ||
518 | * </p> | ||
519 | * <strong>NOTE</strong>: It is important not to modify the source model while the stream is being processed. | ||
520 | * If the match set of the pattern changes during processing, the contents of the stream is <strong>undefined</strong>. | ||
521 | * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. | ||
522 | * | ||
523 | * @return the Stream of all values or empty set if there are no matches | ||
524 | * | ||
525 | */ | ||
526 | public Stream<Synchronization> streamAllValuesOfs2(final Synchronization pS1) { | ||
527 | return rawStreamAllValuesOfs2(new Object[]{pS1, null}); | ||
528 | } | ||
529 | |||
530 | /** | ||
531 | * Retrieve the set of values that occur in matches for s2. | ||
532 | * @return the Set of all values or empty set if there are no matches | ||
533 | * | ||
534 | */ | ||
535 | public Set<Synchronization> getAllValuesOfs2(final TwoSynch.Match partialMatch) { | ||
536 | return rawStreamAllValuesOfs2(partialMatch.toArray()).collect(Collectors.toSet()); | ||
537 | } | ||
538 | |||
539 | /** | ||
540 | * Retrieve the set of values that occur in matches for s2. | ||
541 | * @return the Set of all values or empty set if there are no matches | ||
542 | * | ||
543 | */ | ||
544 | public Set<Synchronization> getAllValuesOfs2(final Synchronization pS1) { | ||
545 | return rawStreamAllValuesOfs2(new Object[]{pS1, null}).collect(Collectors.toSet()); | ||
546 | } | ||
547 | |||
548 | @Override | ||
549 | protected TwoSynch.Match tupleToMatch(final Tuple t) { | ||
550 | try { | ||
551 | return TwoSynch.Match.newMatch((Synchronization) t.get(POSITION_S1), (Synchronization) t.get(POSITION_S2)); | ||
552 | } catch(ClassCastException e) { | ||
553 | LOGGER.error("Element(s) in tuple not properly typed!",e); | ||
554 | return null; | ||
555 | } | ||
556 | } | ||
557 | |||
558 | @Override | ||
559 | protected TwoSynch.Match arrayToMatch(final Object[] match) { | ||
560 | try { | ||
561 | return TwoSynch.Match.newMatch((Synchronization) match[POSITION_S1], (Synchronization) match[POSITION_S2]); | ||
562 | } catch(ClassCastException e) { | ||
563 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
564 | return null; | ||
565 | } | ||
566 | } | ||
567 | |||
568 | @Override | ||
569 | protected TwoSynch.Match arrayToMatchMutable(final Object[] match) { | ||
570 | try { | ||
571 | return TwoSynch.Match.newMutableMatch((Synchronization) match[POSITION_S1], (Synchronization) match[POSITION_S2]); | ||
572 | } catch(ClassCastException e) { | ||
573 | LOGGER.error("Element(s) in array not properly typed!",e); | ||
574 | return null; | ||
575 | } | ||
576 | } | ||
577 | |||
578 | /** | ||
579 | * @return the singleton instance of the query specification of this pattern | ||
580 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
581 | * | ||
582 | */ | ||
583 | public static IQuerySpecification<TwoSynch.Matcher> querySpecification() { | ||
584 | return TwoSynch.instance(); | ||
585 | } | ||
586 | } | ||
587 | |||
588 | private TwoSynch() { | ||
589 | super(GeneratedPQuery.INSTANCE); | ||
590 | } | ||
591 | |||
592 | /** | ||
593 | * @return the singleton instance of the query specification | ||
594 | * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded | ||
595 | * | ||
596 | */ | ||
597 | public static TwoSynch instance() { | ||
598 | try{ | ||
599 | return LazyHolder.INSTANCE; | ||
600 | } catch (ExceptionInInitializerError err) { | ||
601 | throw processInitializerError(err); | ||
602 | } | ||
603 | } | ||
604 | |||
605 | @Override | ||
606 | protected TwoSynch.Matcher instantiate(final ViatraQueryEngine engine) { | ||
607 | return TwoSynch.Matcher.on(engine); | ||
608 | } | ||
609 | |||
610 | @Override | ||
611 | public TwoSynch.Matcher instantiate() { | ||
612 | return TwoSynch.Matcher.create(); | ||
613 | } | ||
614 | |||
615 | @Override | ||
616 | public TwoSynch.Match newEmptyMatch() { | ||
617 | return TwoSynch.Match.newEmptyMatch(); | ||
618 | } | ||
619 | |||
620 | @Override | ||
621 | public TwoSynch.Match newMatch(final Object... parameters) { | ||
622 | return TwoSynch.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization) parameters[0], (ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization) parameters[1]); | ||
623 | } | ||
624 | |||
625 | /** | ||
626 | * Inner class allowing the singleton instance of {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.TwoSynch (visibility: PUBLIC, simpleName: TwoSynch, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.TwoSynch, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created | ||
627 | * <b>not</b> at the class load time of the outer class, | ||
628 | * but rather at the first call to {@link JvmGenericType: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.TwoSynch (visibility: PUBLIC, simpleName: TwoSynch, identifier: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.TwoSynch, deprecated: <unset>) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. | ||
629 | * | ||
630 | * <p> This workaround is required e.g. to support recursion. | ||
631 | * | ||
632 | */ | ||
633 | private static class LazyHolder { | ||
634 | private final static TwoSynch INSTANCE = new TwoSynch(); | ||
635 | |||
636 | /** | ||
637 | * Statically initializes the query specification <b>after</b> the field {@link #INSTANCE} is assigned. | ||
638 | * This initialization order is required to support indirect recursion. | ||
639 | * | ||
640 | * <p> The static initializer is defined using a helper field to work around limitations of the code generator. | ||
641 | * | ||
642 | */ | ||
643 | private final static Object STATIC_INITIALIZER = ensureInitialized(); | ||
644 | |||
645 | public static Object ensureInitialized() { | ||
646 | INSTANCE.ensureInitializedInternal(); | ||
647 | return null; | ||
648 | } | ||
649 | } | ||
650 | |||
651 | private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { | ||
652 | private final static TwoSynch.GeneratedPQuery INSTANCE = new GeneratedPQuery(); | ||
653 | |||
654 | private final PParameter parameter_s1 = new PParameter("s1", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Synchronization")), PParameterDirection.INOUT); | ||
655 | |||
656 | private final PParameter parameter_s2 = new PParameter("s2", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Synchronization")), PParameterDirection.INOUT); | ||
657 | |||
658 | private final List<PParameter> parameters = Arrays.asList(parameter_s1, parameter_s2); | ||
659 | |||
660 | private GeneratedPQuery() { | ||
661 | super(PVisibility.PUBLIC); | ||
662 | } | ||
663 | |||
664 | @Override | ||
665 | public String getFullyQualifiedName() { | ||
666 | return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.twoSynch"; | ||
667 | } | ||
668 | |||
669 | @Override | ||
670 | public List<String> getParameterNames() { | ||
671 | return Arrays.asList("s1","s2"); | ||
672 | } | ||
673 | |||
674 | @Override | ||
675 | public List<PParameter> getParameters() { | ||
676 | return parameters; | ||
677 | } | ||
678 | |||
679 | @Override | ||
680 | public Set<PBody> doGetContainedBodies() { | ||
681 | setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); | ||
682 | Set<PBody> bodies = new LinkedHashSet<>(); | ||
683 | { | ||
684 | PBody body = new PBody(this); | ||
685 | PVariable var_s1 = body.getOrCreateVariableByName("s1"); | ||
686 | PVariable var_s2 = body.getOrCreateVariableByName("s2"); | ||
687 | new TypeConstraint(body, Tuples.flatTupleOf(var_s1), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Synchronization"))); | ||
688 | new TypeConstraint(body, Tuples.flatTupleOf(var_s2), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Synchronization"))); | ||
689 | body.setSymbolicParameters(Arrays.<ExportedParameter>asList( | ||
690 | new ExportedParameter(body, var_s1, parameter_s1), | ||
691 | new ExportedParameter(body, var_s2, parameter_s2) | ||
692 | )); | ||
693 | // Synchronization(s1) | ||
694 | new TypeConstraint(body, Tuples.flatTupleOf(var_s1), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Synchronization"))); | ||
695 | // Synchronization(s2) | ||
696 | new TypeConstraint(body, Tuples.flatTupleOf(var_s2), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Synchronization"))); | ||
697 | // s1 != s2 | ||
698 | new Inequality(body, var_s1, var_s2); | ||
699 | bodies.add(body); | ||
700 | } | ||
701 | { | ||
702 | PAnnotation annotation = new PAnnotation("Constraint"); | ||
703 | annotation.addAttribute("severity", "error"); | ||
704 | annotation.addAttribute("message", "error"); | ||
705 | annotation.addAttribute("key", Arrays.asList(new Object[] { | ||
706 | new ParameterReference("s1"), | ||
707 | new ParameterReference("s2") | ||
708 | })); | ||
709 | addAnnotation(annotation); | ||
710 | } | ||
711 | return bodies; | ||
712 | } | ||
713 | } | ||
714 | } | ||