From d6839b05d1e1f2dede0acc58ba2d39f89e8163e4 Mon Sep 17 00:00:00 2001 From: ArenBabikian Date: Sat, 16 Feb 2019 15:45:14 -0500 Subject: Integrate queries partially #19 --- .../standalone/test/ecore/queries/.gitignore | 13 + .../standalone/test/fam/queries/.gitignore | 10 + .../test/fam/queries/TerminatorAndInformation.java | 747 +++++++++++++++++ .../standalone/test/fam/queries/Type.java | 770 ++++++++++++++++++ .../standalone/test/filesystem/queries/.gitignore | 9 + .../standalone/test/yakindu/queries/.gitignore | 158 ++++ .../standalone/test/yakindu/queries/Child.java | 721 ++++++++++++++++ .../test/yakindu/queries/ChoiceHasNoIncoming.java | 551 +++++++++++++ .../test/yakindu/queries/ChoiceHasNoOutgoing.java | 559 +++++++++++++ .../test/yakindu/queries/EntryInRegion.java | 702 ++++++++++++++++ .../queries/HasMultipleIncomingTrainsition.java | 549 +++++++++++++ .../queries/HasMultipleOutgoingTrainsition.java | 549 +++++++++++++ .../test/yakindu/queries/HasMultipleRegions.java | 555 +++++++++++++ .../test/yakindu/queries/IncomingToEntry.java | 703 ++++++++++++++++ .../queries/MultipleTransitionFromEntry.java | 827 +++++++++++++++++++ .../test/yakindu/queries/NoEntryInRegion.java | 550 +++++++++++++ .../queries/NoOutgoingTransitionFromEntry.java | 551 +++++++++++++ .../test/yakindu/queries/NoStateInRegion.java | 558 +++++++++++++ .../yakindu/queries/NotSynchronizingStates.java | 554 +++++++++++++ .../test/yakindu/queries/OutgoingFromExit.java | 715 ++++++++++++++++ .../test/yakindu/queries/OutgoingFromFinal.java | 715 ++++++++++++++++ .../test/yakindu/queries/StateInRegion.java | 694 ++++++++++++++++ .../test/yakindu/queries/SynchHasNoIncoming.java | 551 +++++++++++++ .../test/yakindu/queries/SynchHasNoOutgoing.java | 559 +++++++++++++ .../test/yakindu/queries/SynchThree.java | 639 +++++++++++++++ .../queries/SynchronizedIncomingInSameRegion.java | 888 ++++++++++++++++++++ ...nchronizedRegionDoesNotHaveMultipleRegions.java | 744 +++++++++++++++++ .../queries/SynchronizedRegionsAreNotSiblings.java | 902 +++++++++++++++++++++ .../test/yakindu/queries/Transition.java | 808 ++++++++++++++++++ .../standalone/test/yakindu/queries/TwoSynch.java | 714 ++++++++++++++++ 30 files changed, 17565 insertions(+) create mode 100644 Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/ecore/queries/.gitignore create mode 100644 Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/fam/queries/.gitignore create mode 100644 Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/fam/queries/TerminatorAndInformation.java create mode 100644 Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/fam/queries/Type.java create mode 100644 Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/filesystem/queries/.gitignore create mode 100644 Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/.gitignore create mode 100644 Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/Child.java create mode 100644 Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/ChoiceHasNoIncoming.java create mode 100644 Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/ChoiceHasNoOutgoing.java create mode 100644 Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/EntryInRegion.java create mode 100644 Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/HasMultipleIncomingTrainsition.java create mode 100644 Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/HasMultipleOutgoingTrainsition.java create mode 100644 Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/HasMultipleRegions.java create mode 100644 Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/IncomingToEntry.java create mode 100644 Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/MultipleTransitionFromEntry.java create mode 100644 Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/NoEntryInRegion.java create mode 100644 Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/NoOutgoingTransitionFromEntry.java create mode 100644 Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/NoStateInRegion.java create mode 100644 Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/NotSynchronizingStates.java create mode 100644 Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/OutgoingFromExit.java create mode 100644 Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/OutgoingFromFinal.java create mode 100644 Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/StateInRegion.java create mode 100644 Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/SynchHasNoIncoming.java create mode 100644 Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/SynchHasNoOutgoing.java create mode 100644 Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/SynchThree.java create mode 100644 Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/SynchronizedIncomingInSameRegion.java create mode 100644 Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/SynchronizedRegionDoesNotHaveMultipleRegions.java create mode 100644 Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/SynchronizedRegionsAreNotSiblings.java create mode 100644 Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/Transition.java create mode 100644 Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/TwoSynch.java (limited to 'Tests/ca.mcgill.ecse.dslreasoner.standalone.test/src-gen/ca/mcgill/ecse/dslreasoner/standalone') 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 @@ +/.DirectSupertype.java._trace +/.Ecore.java._trace +/.LoopInInheritence.java._trace +/.NonSymmetricOpposite.java._trace +/.Opposite.java._trace +/.OppositeDifferentClass.java._trace +/.EcorePatterns.java._trace +/DirectSupertype.java +/EcorePatterns.java +/LoopInInheritence.java +/NonSymmetricOpposite.java +/Opposite.java +/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 @@ +/.FamPatterns.java._trace +/.Model.java._trace +/.Parent.java._trace +/.RootElements.java._trace +/.TerminatorAndInformation.java._trace +/.Type.java._trace +/FamPatterns.java +/Model.java +/Parent.java +/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 @@ +/** + * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/fam/queries/famPatterns.vql + */ +package ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries; + +import ca.mcgill.ecse.dslreasoner.standalone.test.fam.FAMTerminator; +import ca.mcgill.ecse.dslreasoner.standalone.test.fam.InformationLink; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.log4j.Logger; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.viatra.query.runtime.api.IPatternMatch; +import org.eclipse.viatra.query.runtime.api.IQuerySpecification; +import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; +import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; +import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; +import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; +import org.eclipse.viatra.query.runtime.emf.types.EStructuralFeatureInstancesKey; +import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; +import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; +import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; +import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; + +/** + * A pattern-specific query specification that can instantiate Matcher in a type-safe way. + * + *

Original source: + *

+ *         {@literal @}Constraint(message="terminatorAndInformation", severity="error", key={T})
+ *         pattern terminatorAndInformation(T : FAMTerminator, I : InformationLink) = {
+ *         	FunctionalOutput.outgoingLinks(Out,I);
+ *         	FunctionalOutput.terminator(Out,T); 
+ *         } or {
+ *         	InformationLink.to(I,In);
+ *         	FunctionalInput.terminator(In,T);
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class TerminatorAndInformation extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries.terminatorAndInformation pattern, + * to be used in conjunction with {@link Matcher}. + * + *

Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. + * Each instance is a (possibly partial) substitution of pattern parameters, + * usable to represent a match of the pattern in the result of a query, + * or to specify the bound (fixed) input parameters when issuing a query. + * + * @see Matcher + * + */ + public static abstract class Match extends BasePatternMatch { + private FAMTerminator fT; + + private InformationLink fI; + + private static List parameterNames = makeImmutableList("T", "I"); + + private Match(final FAMTerminator pT, final InformationLink pI) { + this.fT = pT; + this.fI = pI; + } + + @Override + public Object get(final String parameterName) { + if ("T".equals(parameterName)) return this.fT; + if ("I".equals(parameterName)) return this.fI; + return null; + } + + public FAMTerminator getT() { + return this.fT; + } + + public InformationLink getI() { + return this.fI; + } + + @Override + public boolean set(final String parameterName, final Object newValue) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + if ("T".equals(parameterName) ) { + this.fT = (FAMTerminator) newValue; + return true; + } + if ("I".equals(parameterName) ) { + this.fI = (InformationLink) newValue; + return true; + } + return false; + } + + public void setT(final FAMTerminator pT) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fT = pT; + } + + public void setI(final InformationLink pI) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fI = pI; + } + + @Override + public String patternName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries.terminatorAndInformation"; + } + + @Override + public List parameterNames() { + return TerminatorAndInformation.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fT, fI}; + } + + @Override + public TerminatorAndInformation.Match toImmutable() { + return isMutable() ? newMatch(fT, fI) : this; + } + + @Override + public String prettyPrint() { + StringBuilder result = new StringBuilder(); + result.append("\"T\"=" + prettyPrintValue(fT) + ", "); + result.append("\"I\"=" + prettyPrintValue(fI)); + return result.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(fT, fI); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) { + return false; + } + if ((obj instanceof TerminatorAndInformation.Match)) { + TerminatorAndInformation.Match other = (TerminatorAndInformation.Match) obj; + return Objects.equals(fT, other.fT) && Objects.equals(fI, other.fI); + } else { + // this should be infrequent + if (!(obj instanceof IPatternMatch)) { + return false; + } + IPatternMatch otherSig = (IPatternMatch) obj; + return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); + } + } + + @Override + public TerminatorAndInformation specification() { + return TerminatorAndInformation.instance(); + } + + /** + * Returns an empty, mutable match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @return the empty match. + * + */ + public static TerminatorAndInformation.Match newEmptyMatch() { + return new Mutable(null, null); + } + + /** + * Returns a mutable (partial) match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @param pT the fixed value of pattern parameter T, or null if not bound. + * @param pI the fixed value of pattern parameter I, or null if not bound. + * @return the new, mutable (partial) match object. + * + */ + public static TerminatorAndInformation.Match newMutableMatch(final FAMTerminator pT, final InformationLink pI) { + return new Mutable(pT, pI); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pT the fixed value of pattern parameter T, or null if not bound. + * @param pI the fixed value of pattern parameter I, or null if not bound. + * @return the (partial) match object. + * + */ + public static TerminatorAndInformation.Match newMatch(final FAMTerminator pT, final InformationLink pI) { + return new Immutable(pT, pI); + } + + private static final class Mutable extends TerminatorAndInformation.Match { + Mutable(final FAMTerminator pT, final InformationLink pI) { + super(pT, pI); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends TerminatorAndInformation.Match { + Immutable(final FAMTerminator pT, final InformationLink pI) { + super(pT, pI); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries.terminatorAndInformation pattern, + * providing pattern-specific query methods. + * + *

Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, + * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. + * + *

Matches of the pattern will be represented as {@link Match}. + * + *

Original source: + *

+   * {@literal @}Constraint(message="terminatorAndInformation", severity="error", key={T})
+   * pattern terminatorAndInformation(T : FAMTerminator, I : InformationLink) = {
+   * 	FunctionalOutput.outgoingLinks(Out,I);
+   * 	FunctionalOutput.terminator(Out,T); 
+   * } or {
+   * 	InformationLink.to(I,In);
+   * 	FunctionalInput.terminator(In,T);
+   * }
+   * 
+ * + * @see Match + * @see TerminatorAndInformation + * + */ + public static class Matcher extends BaseMatcher { + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + public static TerminatorAndInformation.Matcher on(final ViatraQueryEngine engine) { + // check if matcher already exists + Matcher matcher = engine.getExistingMatcher(querySpecification()); + if (matcher == null) { + matcher = (Matcher)engine.getMatcher(querySpecification()); + } + return matcher; + } + + /** + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * @return an initialized matcher + * @noreference This method is for internal matcher initialization by the framework, do not call it manually. + * + */ + public static TerminatorAndInformation.Matcher create() { + return new Matcher(); + } + + private final static int POSITION_T = 0; + + private final static int POSITION_I = 1; + + private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(TerminatorAndInformation.Matcher.class); + + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + private Matcher() { + super(querySpecification()); + } + + /** + * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pT the fixed value of pattern parameter T, or null if not bound. + * @param pI the fixed value of pattern parameter I, or null if not bound. + * @return matches represented as a Match object. + * + */ + public Collection getAllMatches(final FAMTerminator pT, final InformationLink pI) { + return rawStreamAllMatches(new Object[]{pT, pI}).collect(Collectors.toSet()); + } + + /** + * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * @param pT the fixed value of pattern parameter T, or null if not bound. + * @param pI the fixed value of pattern parameter I, or null if not bound. + * @return a stream of matches represented as a Match object. + * + */ + public Stream streamAllMatches(final FAMTerminator pT, final InformationLink pI) { + return rawStreamAllMatches(new Object[]{pT, pI}); + } + + /** + * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pT the fixed value of pattern parameter T, or null if not bound. + * @param pI the fixed value of pattern parameter I, or null if not bound. + * @return a match represented as a Match object, or null if no match is found. + * + */ + public Optional getOneArbitraryMatch(final FAMTerminator pT, final InformationLink pI) { + return rawGetOneArbitraryMatch(new Object[]{pT, pI}); + } + + /** + * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, + * under any possible substitution of the unspecified parameters (if any). + * @param pT the fixed value of pattern parameter T, or null if not bound. + * @param pI the fixed value of pattern parameter I, or null if not bound. + * @return true if the input is a valid (partial) match of the pattern. + * + */ + public boolean hasMatch(final FAMTerminator pT, final InformationLink pI) { + return rawHasMatch(new Object[]{pT, pI}); + } + + /** + * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pT the fixed value of pattern parameter T, or null if not bound. + * @param pI the fixed value of pattern parameter I, or null if not bound. + * @return the number of pattern matches found. + * + */ + public int countMatches(final FAMTerminator pT, final InformationLink pI) { + return rawCountMatches(new Object[]{pT, pI}); + } + + /** + * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pT the fixed value of pattern parameter T, or null if not bound. + * @param pI the fixed value of pattern parameter I, or null if not bound. + * @param processor the action that will process the selected match. + * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked + * + */ + public boolean forOneArbitraryMatch(final FAMTerminator pT, final InformationLink pI, final Consumer processor) { + return rawForOneArbitraryMatch(new Object[]{pT, pI}, processor); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pT the fixed value of pattern parameter T, or null if not bound. + * @param pI the fixed value of pattern parameter I, or null if not bound. + * @return the (partial) match object. + * + */ + public TerminatorAndInformation.Match newMatch(final FAMTerminator pT, final InformationLink pI) { + return TerminatorAndInformation.Match.newMatch(pT, pI); + } + + /** + * Retrieve the set of values that occur in matches for T. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfT(final Object[] parameters) { + return rawStreamAllValues(POSITION_T, parameters).map(FAMTerminator.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for T. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfT() { + return rawStreamAllValuesOfT(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for T. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfT() { + return rawStreamAllValuesOfT(emptyArray()); + } + + /** + * Retrieve the set of values that occur in matches for T. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfT(final TerminatorAndInformation.Match partialMatch) { + return rawStreamAllValuesOfT(partialMatch.toArray()); + } + + /** + * Retrieve the set of values that occur in matches for T. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfT(final InformationLink pI) { + return rawStreamAllValuesOfT(new Object[]{null, pI}); + } + + /** + * Retrieve the set of values that occur in matches for T. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfT(final TerminatorAndInformation.Match partialMatch) { + return rawStreamAllValuesOfT(partialMatch.toArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for T. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfT(final InformationLink pI) { + return rawStreamAllValuesOfT(new Object[]{null, pI}).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for I. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfI(final Object[] parameters) { + return rawStreamAllValues(POSITION_I, parameters).map(InformationLink.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for I. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfI() { + return rawStreamAllValuesOfI(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for I. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfI() { + return rawStreamAllValuesOfI(emptyArray()); + } + + /** + * Retrieve the set of values that occur in matches for I. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfI(final TerminatorAndInformation.Match partialMatch) { + return rawStreamAllValuesOfI(partialMatch.toArray()); + } + + /** + * Retrieve the set of values that occur in matches for I. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfI(final FAMTerminator pT) { + return rawStreamAllValuesOfI(new Object[]{pT, null}); + } + + /** + * Retrieve the set of values that occur in matches for I. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfI(final TerminatorAndInformation.Match partialMatch) { + return rawStreamAllValuesOfI(partialMatch.toArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for I. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfI(final FAMTerminator pT) { + return rawStreamAllValuesOfI(new Object[]{pT, null}).collect(Collectors.toSet()); + } + + @Override + protected TerminatorAndInformation.Match tupleToMatch(final Tuple t) { + try { + return TerminatorAndInformation.Match.newMatch((FAMTerminator) t.get(POSITION_T), (InformationLink) t.get(POSITION_I)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected TerminatorAndInformation.Match arrayToMatch(final Object[] match) { + try { + return TerminatorAndInformation.Match.newMatch((FAMTerminator) match[POSITION_T], (InformationLink) match[POSITION_I]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected TerminatorAndInformation.Match arrayToMatchMutable(final Object[] match) { + try { + return TerminatorAndInformation.Match.newMutableMatch((FAMTerminator) match[POSITION_T], (InformationLink) match[POSITION_I]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + /** + * @return the singleton instance of the query specification of this pattern + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static IQuerySpecification querySpecification() { + return TerminatorAndInformation.instance(); + } + } + + private TerminatorAndInformation() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static TerminatorAndInformation instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected TerminatorAndInformation.Matcher instantiate(final ViatraQueryEngine engine) { + return TerminatorAndInformation.Matcher.on(engine); + } + + @Override + public TerminatorAndInformation.Matcher instantiate() { + return TerminatorAndInformation.Matcher.create(); + } + + @Override + public TerminatorAndInformation.Match newEmptyMatch() { + return TerminatorAndInformation.Match.newEmptyMatch(); + } + + @Override + public TerminatorAndInformation.Match newMatch(final Object... parameters) { + return TerminatorAndInformation.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.fam.FAMTerminator) parameters[0], (ca.mcgill.ecse.dslreasoner.standalone.test.fam.InformationLink) parameters[1]); + } + + /** + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created + * not at the class load time of the outer class, + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private final static TerminatorAndInformation INSTANCE = new TerminatorAndInformation(); + + /** + * Statically initializes the query specification after the field {@link #INSTANCE} is assigned. + * This initialization order is required to support indirect recursion. + * + *

The static initializer is defined using a helper field to work around limitations of the code generator. + * + */ + private final static Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private final static TerminatorAndInformation.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_T = new PParameter("T", "ca.mcgill.ecse.dslreasoner.standalone.test.fam.FAMTerminator", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("FamMetamodel", "FAMTerminator")), PParameterDirection.INOUT); + + private final PParameter parameter_I = new PParameter("I", "ca.mcgill.ecse.dslreasoner.standalone.test.fam.InformationLink", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("FamMetamodel", "InformationLink")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_T, parameter_I); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries.terminatorAndInformation"; + } + + @Override + public List getParameterNames() { + return Arrays.asList("T","I"); + } + + @Override + public List getParameters() { + return parameters; + } + + @Override + public Set doGetContainedBodies() { + setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); + Set bodies = new LinkedHashSet<>(); + { + PBody body = new PBody(this); + PVariable var_T = body.getOrCreateVariableByName("T"); + PVariable var_I = body.getOrCreateVariableByName("I"); + PVariable var_Out = body.getOrCreateVariableByName("Out"); + new TypeConstraint(body, Tuples.flatTupleOf(var_T), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("FamMetamodel", "FAMTerminator"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_I), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("FamMetamodel", "InformationLink"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_T, parameter_T), + new ExportedParameter(body, var_I, parameter_I) + )); + // FunctionalOutput.outgoingLinks(Out,I) + new TypeConstraint(body, Tuples.flatTupleOf(var_Out), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("FamMetamodel", "FunctionalOutput"))); + PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_Out, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("FamMetamodel", "FunctionalOutput", "outgoingLinks"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("FamMetamodel", "InformationLink"))); + new Equality(body, var__virtual_0_, var_I); + // FunctionalOutput.terminator(Out,T) + new TypeConstraint(body, Tuples.flatTupleOf(var_Out), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("FamMetamodel", "FunctionalOutput"))); + PVariable var__virtual_1_ = body.getOrCreateVariableByName(".virtual{1}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_Out, var__virtual_1_), new EStructuralFeatureInstancesKey(getFeatureLiteral("FamMetamodel", "FunctionalData", "terminator"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_1_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("FamMetamodel", "FAMTerminator"))); + new Equality(body, var__virtual_1_, var_T); + bodies.add(body); + } + { + PBody body = new PBody(this); + PVariable var_T = body.getOrCreateVariableByName("T"); + PVariable var_I = body.getOrCreateVariableByName("I"); + PVariable var_In = body.getOrCreateVariableByName("In"); + new TypeConstraint(body, Tuples.flatTupleOf(var_T), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("FamMetamodel", "FAMTerminator"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_I), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("FamMetamodel", "InformationLink"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_T, parameter_T), + new ExportedParameter(body, var_I, parameter_I) + )); + // InformationLink.to(I,In) + new TypeConstraint(body, Tuples.flatTupleOf(var_I), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("FamMetamodel", "InformationLink"))); + PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_I, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("FamMetamodel", "InformationLink", "to"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("FamMetamodel", "FunctionalInput"))); + new Equality(body, var__virtual_0_, var_In); + // FunctionalInput.terminator(In,T) + new TypeConstraint(body, Tuples.flatTupleOf(var_In), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("FamMetamodel", "FunctionalInput"))); + PVariable var__virtual_1_ = body.getOrCreateVariableByName(".virtual{1}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_In, var__virtual_1_), new EStructuralFeatureInstancesKey(getFeatureLiteral("FamMetamodel", "FunctionalData", "terminator"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_1_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("FamMetamodel", "FAMTerminator"))); + new Equality(body, var__virtual_1_, var_T); + bodies.add(body); + } + { + PAnnotation annotation = new PAnnotation("Constraint"); + annotation.addAttribute("message", "terminatorAndInformation"); + annotation.addAttribute("severity", "error"); + annotation.addAttribute("key", Arrays.asList(new Object[] { + new ParameterReference("T") + })); + addAnnotation(annotation); + } + return bodies; + } + } +} 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 @@ +/** + * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/fam/queries/famPatterns.vql + */ +package ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries; + +import ca.mcgill.ecse.dslreasoner.standalone.test.fam.Function; +import ca.mcgill.ecse.dslreasoner.standalone.test.fam.FunctionType; +import ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries.Parent; +import ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries.RootElements; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.log4j.Logger; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EDataType; +import org.eclipse.viatra.query.runtime.api.IPatternMatch; +import org.eclipse.viatra.query.runtime.api.IQuerySpecification; +import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; +import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; +import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; +import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; +import org.eclipse.viatra.query.runtime.emf.types.EDataTypeInSlotsKey; +import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; +import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; +import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.NegativePatternCall; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.ConstantValue; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; +import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; + +/** + * A pattern-specific query specification that can instantiate Matcher in a type-safe way. + * + *

Original source: + *

+ *         {@literal @}QueryBasedFeature 
+ *         pattern type(This : Function, Target : FunctionType) = {
+ *         	find rootElements(_Model, This);
+ *         	Target == FunctionType::Root;
+ *         } or {
+ *         	neg find parent(_Child, This);
+ *         	neg find rootElements(_Model, This);
+ *         	Target == FunctionType::Leaf;
+ *         } or  {
+ *         	find parent(This, _Par);
+ *         	find parent(_Child, This);
+ *         	Target == FunctionType::Intermediate;
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class Type extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries.type pattern, + * to be used in conjunction with {@link Matcher}. + * + *

Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. + * Each instance is a (possibly partial) substitution of pattern parameters, + * usable to represent a match of the pattern in the result of a query, + * or to specify the bound (fixed) input parameters when issuing a query. + * + * @see Matcher + * + */ + public static abstract class Match extends BasePatternMatch { + private Function fThis; + + private FunctionType fTarget; + + private static List parameterNames = makeImmutableList("This", "Target"); + + private Match(final Function pThis, final FunctionType pTarget) { + this.fThis = pThis; + this.fTarget = pTarget; + } + + @Override + public Object get(final String parameterName) { + if ("This".equals(parameterName)) return this.fThis; + if ("Target".equals(parameterName)) return this.fTarget; + return null; + } + + public Function getThis() { + return this.fThis; + } + + public FunctionType getTarget() { + return this.fTarget; + } + + @Override + public boolean set(final String parameterName, final Object newValue) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + if ("This".equals(parameterName) ) { + this.fThis = (Function) newValue; + return true; + } + if ("Target".equals(parameterName) ) { + this.fTarget = (FunctionType) newValue; + return true; + } + return false; + } + + public void setThis(final Function pThis) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fThis = pThis; + } + + public void setTarget(final FunctionType pTarget) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fTarget = pTarget; + } + + @Override + public String patternName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries.type"; + } + + @Override + public List parameterNames() { + return Type.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fThis, fTarget}; + } + + @Override + public Type.Match toImmutable() { + return isMutable() ? newMatch(fThis, fTarget) : this; + } + + @Override + public String prettyPrint() { + StringBuilder result = new StringBuilder(); + result.append("\"This\"=" + prettyPrintValue(fThis) + ", "); + result.append("\"Target\"=" + prettyPrintValue(fTarget)); + return result.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(fThis, fTarget); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) { + return false; + } + if ((obj instanceof Type.Match)) { + Type.Match other = (Type.Match) obj; + return Objects.equals(fThis, other.fThis) && Objects.equals(fTarget, other.fTarget); + } else { + // this should be infrequent + if (!(obj instanceof IPatternMatch)) { + return false; + } + IPatternMatch otherSig = (IPatternMatch) obj; + return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); + } + } + + @Override + public Type specification() { + return Type.instance(); + } + + /** + * Returns an empty, mutable match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @return the empty match. + * + */ + public static Type.Match newEmptyMatch() { + return new Mutable(null, null); + } + + /** + * Returns a mutable (partial) match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @param pThis the fixed value of pattern parameter This, or null if not bound. + * @param pTarget the fixed value of pattern parameter Target, or null if not bound. + * @return the new, mutable (partial) match object. + * + */ + public static Type.Match newMutableMatch(final Function pThis, final FunctionType pTarget) { + return new Mutable(pThis, pTarget); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pThis the fixed value of pattern parameter This, or null if not bound. + * @param pTarget the fixed value of pattern parameter Target, or null if not bound. + * @return the (partial) match object. + * + */ + public static Type.Match newMatch(final Function pThis, final FunctionType pTarget) { + return new Immutable(pThis, pTarget); + } + + private static final class Mutable extends Type.Match { + Mutable(final Function pThis, final FunctionType pTarget) { + super(pThis, pTarget); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends Type.Match { + Immutable(final Function pThis, final FunctionType pTarget) { + super(pThis, pTarget); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries.type pattern, + * providing pattern-specific query methods. + * + *

Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, + * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. + * + *

Matches of the pattern will be represented as {@link Match}. + * + *

Original source: + *

+   * {@literal @}QueryBasedFeature 
+   * pattern type(This : Function, Target : FunctionType) = {
+   * 	find rootElements(_Model, This);
+   * 	Target == FunctionType::Root;
+   * } or {
+   * 	neg find parent(_Child, This);
+   * 	neg find rootElements(_Model, This);
+   * 	Target == FunctionType::Leaf;
+   * } or  {
+   * 	find parent(This, _Par);
+   * 	find parent(_Child, This);
+   * 	Target == FunctionType::Intermediate;
+   * }
+   * 
+ * + * @see Match + * @see Type + * + */ + public static class Matcher extends BaseMatcher { + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + public static Type.Matcher on(final ViatraQueryEngine engine) { + // check if matcher already exists + Matcher matcher = engine.getExistingMatcher(querySpecification()); + if (matcher == null) { + matcher = (Matcher)engine.getMatcher(querySpecification()); + } + return matcher; + } + + /** + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * @return an initialized matcher + * @noreference This method is for internal matcher initialization by the framework, do not call it manually. + * + */ + public static Type.Matcher create() { + return new Matcher(); + } + + private final static int POSITION_THIS = 0; + + private final static int POSITION_TARGET = 1; + + private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(Type.Matcher.class); + + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + private Matcher() { + super(querySpecification()); + } + + /** + * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pThis the fixed value of pattern parameter This, or null if not bound. + * @param pTarget the fixed value of pattern parameter Target, or null if not bound. + * @return matches represented as a Match object. + * + */ + public Collection getAllMatches(final Function pThis, final FunctionType pTarget) { + return rawStreamAllMatches(new Object[]{pThis, pTarget}).collect(Collectors.toSet()); + } + + /** + * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * @param pThis the fixed value of pattern parameter This, or null if not bound. + * @param pTarget the fixed value of pattern parameter Target, or null if not bound. + * @return a stream of matches represented as a Match object. + * + */ + public Stream streamAllMatches(final Function pThis, final FunctionType pTarget) { + return rawStreamAllMatches(new Object[]{pThis, pTarget}); + } + + /** + * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pThis the fixed value of pattern parameter This, or null if not bound. + * @param pTarget the fixed value of pattern parameter Target, or null if not bound. + * @return a match represented as a Match object, or null if no match is found. + * + */ + public Optional getOneArbitraryMatch(final Function pThis, final FunctionType pTarget) { + return rawGetOneArbitraryMatch(new Object[]{pThis, pTarget}); + } + + /** + * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, + * under any possible substitution of the unspecified parameters (if any). + * @param pThis the fixed value of pattern parameter This, or null if not bound. + * @param pTarget the fixed value of pattern parameter Target, or null if not bound. + * @return true if the input is a valid (partial) match of the pattern. + * + */ + public boolean hasMatch(final Function pThis, final FunctionType pTarget) { + return rawHasMatch(new Object[]{pThis, pTarget}); + } + + /** + * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pThis the fixed value of pattern parameter This, or null if not bound. + * @param pTarget the fixed value of pattern parameter Target, or null if not bound. + * @return the number of pattern matches found. + * + */ + public int countMatches(final Function pThis, final FunctionType pTarget) { + return rawCountMatches(new Object[]{pThis, pTarget}); + } + + /** + * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pThis the fixed value of pattern parameter This, or null if not bound. + * @param pTarget the fixed value of pattern parameter Target, or null if not bound. + * @param processor the action that will process the selected match. + * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked + * + */ + public boolean forOneArbitraryMatch(final Function pThis, final FunctionType pTarget, final Consumer processor) { + return rawForOneArbitraryMatch(new Object[]{pThis, pTarget}, processor); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pThis the fixed value of pattern parameter This, or null if not bound. + * @param pTarget the fixed value of pattern parameter Target, or null if not bound. + * @return the (partial) match object. + * + */ + public Type.Match newMatch(final Function pThis, final FunctionType pTarget) { + return Type.Match.newMatch(pThis, pTarget); + } + + /** + * Retrieve the set of values that occur in matches for This. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfThis(final Object[] parameters) { + return rawStreamAllValues(POSITION_THIS, parameters).map(Function.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for This. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfThis() { + return rawStreamAllValuesOfThis(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for This. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfThis() { + return rawStreamAllValuesOfThis(emptyArray()); + } + + /** + * Retrieve the set of values that occur in matches for This. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfThis(final Type.Match partialMatch) { + return rawStreamAllValuesOfThis(partialMatch.toArray()); + } + + /** + * Retrieve the set of values that occur in matches for This. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfThis(final FunctionType pTarget) { + return rawStreamAllValuesOfThis(new Object[]{null, pTarget}); + } + + /** + * Retrieve the set of values that occur in matches for This. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfThis(final Type.Match partialMatch) { + return rawStreamAllValuesOfThis(partialMatch.toArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for This. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfThis(final FunctionType pTarget) { + return rawStreamAllValuesOfThis(new Object[]{null, pTarget}).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for Target. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfTarget(final Object[] parameters) { + return rawStreamAllValues(POSITION_TARGET, parameters).map(FunctionType.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for Target. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfTarget() { + return rawStreamAllValuesOfTarget(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for Target. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfTarget() { + return rawStreamAllValuesOfTarget(emptyArray()); + } + + /** + * Retrieve the set of values that occur in matches for Target. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfTarget(final Type.Match partialMatch) { + return rawStreamAllValuesOfTarget(partialMatch.toArray()); + } + + /** + * Retrieve the set of values that occur in matches for Target. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfTarget(final Function pThis) { + return rawStreamAllValuesOfTarget(new Object[]{pThis, null}); + } + + /** + * Retrieve the set of values that occur in matches for Target. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfTarget(final Type.Match partialMatch) { + return rawStreamAllValuesOfTarget(partialMatch.toArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for Target. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfTarget(final Function pThis) { + return rawStreamAllValuesOfTarget(new Object[]{pThis, null}).collect(Collectors.toSet()); + } + + @Override + protected Type.Match tupleToMatch(final Tuple t) { + try { + return Type.Match.newMatch((Function) t.get(POSITION_THIS), (FunctionType) t.get(POSITION_TARGET)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected Type.Match arrayToMatch(final Object[] match) { + try { + return Type.Match.newMatch((Function) match[POSITION_THIS], (FunctionType) match[POSITION_TARGET]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected Type.Match arrayToMatchMutable(final Object[] match) { + try { + return Type.Match.newMutableMatch((Function) match[POSITION_THIS], (FunctionType) match[POSITION_TARGET]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + /** + * @return the singleton instance of the query specification of this pattern + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static IQuerySpecification querySpecification() { + return Type.instance(); + } + } + + private Type() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static Type instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected Type.Matcher instantiate(final ViatraQueryEngine engine) { + return Type.Matcher.on(engine); + } + + @Override + public Type.Matcher instantiate() { + return Type.Matcher.create(); + } + + @Override + public Type.Match newEmptyMatch() { + return Type.Match.newEmptyMatch(); + } + + @Override + public Type.Match newMatch(final Object... parameters) { + return Type.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.fam.Function) parameters[0], (ca.mcgill.ecse.dslreasoner.standalone.test.fam.FunctionType) parameters[1]); + } + + /** + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created + * not at the class load time of the outer class, + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private final static Type INSTANCE = new Type(); + + /** + * Statically initializes the query specification after the field {@link #INSTANCE} is assigned. + * This initialization order is required to support indirect recursion. + * + *

The static initializer is defined using a helper field to work around limitations of the code generator. + * + */ + private final static Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private final static Type.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_This = new PParameter("This", "ca.mcgill.ecse.dslreasoner.standalone.test.fam.Function", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("FamMetamodel", "Function")), PParameterDirection.INOUT); + + private final PParameter parameter_Target = new PParameter("Target", "ca.mcgill.ecse.dslreasoner.standalone.test.fam.FunctionType", new EDataTypeInSlotsKey((EDataType)getClassifierLiteralSafe("FamMetamodel", "FunctionType")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_This, parameter_Target); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.fam.queries.type"; + } + + @Override + public List getParameterNames() { + return Arrays.asList("This","Target"); + } + + @Override + public List getParameters() { + return parameters; + } + + @Override + public Set doGetContainedBodies() { + setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); + Set bodies = new LinkedHashSet<>(); + { + PBody body = new PBody(this); + PVariable var_This = body.getOrCreateVariableByName("This"); + PVariable var_Target = body.getOrCreateVariableByName("Target"); + PVariable var__Model = body.getOrCreateVariableByName("_Model"); + new TypeConstraint(body, Tuples.flatTupleOf(var_This), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("FamMetamodel", "Function"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_Target), new EDataTypeInSlotsKey((EDataType)getClassifierLiteral("FamMetamodel", "FunctionType"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_This, parameter_This), + new ExportedParameter(body, var_Target, parameter_Target) + )); + // find rootElements(_Model, This) + new PositivePatternCall(body, Tuples.flatTupleOf(var__Model, var_This), RootElements.instance().getInternalQueryRepresentation()); + // Target == FunctionType::Root + PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); + new ConstantValue(body, var__virtual_0_, getEnumLiteral("FamMetamodel", "FunctionType", "Root").getInstance()); + new Equality(body, var_Target, var__virtual_0_); + bodies.add(body); + } + { + PBody body = new PBody(this); + PVariable var_This = body.getOrCreateVariableByName("This"); + PVariable var_Target = body.getOrCreateVariableByName("Target"); + PVariable var__Child = body.getOrCreateVariableByName("_Child"); + PVariable var__Model = body.getOrCreateVariableByName("_Model"); + new TypeConstraint(body, Tuples.flatTupleOf(var_This), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("FamMetamodel", "Function"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_Target), new EDataTypeInSlotsKey((EDataType)getClassifierLiteral("FamMetamodel", "FunctionType"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_This, parameter_This), + new ExportedParameter(body, var_Target, parameter_Target) + )); + // neg find parent(_Child, This) + new NegativePatternCall(body, Tuples.flatTupleOf(var__Child, var_This), Parent.instance().getInternalQueryRepresentation()); + // neg find rootElements(_Model, This) + new NegativePatternCall(body, Tuples.flatTupleOf(var__Model, var_This), RootElements.instance().getInternalQueryRepresentation()); + // Target == FunctionType::Leaf + PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); + new ConstantValue(body, var__virtual_0_, getEnumLiteral("FamMetamodel", "FunctionType", "Leaf").getInstance()); + new Equality(body, var_Target, var__virtual_0_); + bodies.add(body); + } + { + PBody body = new PBody(this); + PVariable var_This = body.getOrCreateVariableByName("This"); + PVariable var_Target = body.getOrCreateVariableByName("Target"); + PVariable var__Par = body.getOrCreateVariableByName("_Par"); + PVariable var__Child = body.getOrCreateVariableByName("_Child"); + new TypeConstraint(body, Tuples.flatTupleOf(var_This), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("FamMetamodel", "Function"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_Target), new EDataTypeInSlotsKey((EDataType)getClassifierLiteral("FamMetamodel", "FunctionType"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_This, parameter_This), + new ExportedParameter(body, var_Target, parameter_Target) + )); + // find parent(This, _Par) + new PositivePatternCall(body, Tuples.flatTupleOf(var_This, var__Par), Parent.instance().getInternalQueryRepresentation()); + // find parent(_Child, This) + new PositivePatternCall(body, Tuples.flatTupleOf(var__Child, var_This), Parent.instance().getInternalQueryRepresentation()); + // Target == FunctionType::Intermediate + PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); + new ConstantValue(body, var__virtual_0_, getEnumLiteral("FamMetamodel", "FunctionType", "Intermediate").getInstance()); + new Equality(body, var_Target, var__virtual_0_); + bodies.add(body); + } + { + PAnnotation annotation = new PAnnotation("QueryBasedFeature"); + addAnnotation(annotation); + } + return bodies; + } + } +} 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 @@ +/.ContentInNotLive.java._trace +/.FileSystem.java._trace +/.Live.java._trace +/.PatternContent.java._trace +/.FileSystemPatterns.java._trace +/PatternContent.java +/ContentInNotLive.java +/FileSystemPatterns.java +/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 @@ +/.EntryInRegion_M0.java._trace +/.EntryInRegion_M1.java._trace +/.EntryInRegion_M2.java._trace +/.MultipleEntryInRegion_M0.java._trace +/.MultipleEntryInRegion_M1.java._trace +/.MultipleEntryInRegion_M2.java._trace +/.NoEntryInRegion_M0.java._trace +/.NoEntryInRegion_M1.java._trace +/.NoEntryInRegion_M2.java._trace +/.NoEntryInRegion_M3.java._trace +/.NoEntryInRegion_M4.java._trace +/.NoEntryInRegion_M5.java._trace +/.MultipleEntryInRegion_M3.java._trace +/.EntryInRegion.java._trace +/.MultipleEntryInRegion.java._trace +/.NoEntryInRegion.java._trace +/.Transition.java._trace +/.Child.java._trace +/.ChoiceHasNoIncoming.java._trace +/.ChoiceHasNoOutgoing.java._trace +/.HasMultipleIncomingTrainsition.java._trace +/.HasMultipleOutgoingTrainsition.java._trace +/.HasMultipleRegions.java._trace +/.IncomingToEntry.java._trace +/.MultipleTransitionFromEntry.java._trace +/.NoOutgoingTransitionFromEntry.java._trace +/.NoStateInRegion.java._trace +/.NotSynchronizingStates.java._trace +/.OutgoingFromExit.java._trace +/.OutgoingFromFinal.java._trace +/.StateInRegion.java._trace +/.SynchHasNoIncoming.java._trace +/.SynchHasNoOutgoing.java._trace +/.SynchThree.java._trace +/.SynchronizedIncomingInSameRegion.java._trace +/.SynchronizedRegionDoesNotHaveMultipleRegions.java._trace +/.SynchronizedRegionsAreNotSiblings.java._trace +/.TwoSynch.java._trace +/.YakinduPatterns.java._trace +/.ChoiceHasNoIncoming_M0.java._trace +/.ChoiceHasNoIncoming_M1.java._trace +/.ChoiceHasNoIncoming_M2.java._trace +/.ChoiceHasNoIncoming_M3.java._trace +/.ChoiceHasNoIncoming_M4.java._trace +/.ChoiceHasNoIncoming_M5.java._trace +/.ChoiceHasNoIncoming_M6.java._trace +/.ChoiceHasNoOutgoing_M0.java._trace +/.ChoiceHasNoOutgoing_M1.java._trace +/.ChoiceHasNoOutgoing_M2.java._trace +/.ChoiceHasNoOutgoing_M3.java._trace +/.ChoiceHasNoOutgoing_M4.java._trace +/.ChoiceHasNoOutgoing_M5.java._trace +/.ChoiceHasNoOutgoing_M6.java._trace +/.IncomingToEntry_1.java._trace +/.IncomingToEntry_2.java._trace +/.IncomingToEntry_3.java._trace +/.IncomingToEntry_4.java._trace +/.IncomingToEntry_5.java._trace +/.IncomingToEntry_M0.java._trace +/.MultipleEntryInRegion_M4.java._trace +/.MultipleEntryInRegion_M5.java._trace +/.MultipleTransitionFromEntry_M0.java._trace +/.MultipleTransitionFromEntry_M1.java._trace +/.MultipleTransitionFromEntry_M2.java._trace +/.MultipleTransitionFromEntry_M3.java._trace +/.MultipleTransitionFromEntry_M4.java._trace +/.NoOutgoingTransitionFromEntry_M0.java._trace +/.NoOutgoingTransitionFromEntry_M1.java._trace +/.NoOutgoingTransitionFromEntry_M2.java._trace +/.NoOutgoingTransitionFromEntry_M3.java._trace +/.NoOutgoingTransitionFromEntry_M4.java._trace +/.NoOutgoingTransitionFromEntry_M5.java._trace +/.NoStateInRegion_M0.java._trace +/.NoStateInRegion_M1.java._trace +/.NoStateInRegion_M2.java._trace +/.NoStateInRegion_M3.java._trace +/.OutgoingFromExit_M0.java._trace +/.OutgoingFromExit_M1.java._trace +/.OutgoingFromExit_M2.java._trace +/.OutgoingFromFinal_M0.java._trace +/.OutgoingFromFinal_M1.java._trace +/.OutgoingFromFinal_M2.java._trace +/.StateInRegion_M0.java._trace +/.StateInRegion_M1.java._trace +/.StateInRegion_M2.java._trace +/.Transition_M0.java._trace +/.Transition_M1.java._trace +/.Transition_M2.java._trace +/.Transition_M3.java._trace +/.Transition_M4.java._trace +/.YakinduMutatedPatterns.java._trace +/YakinduPatterns.java +/MultipleEntryInRegion.java +/ChoiceHasNoIncoming_M0.java +/ChoiceHasNoIncoming_M1.java +/ChoiceHasNoIncoming_M2.java +/ChoiceHasNoIncoming_M3.java +/ChoiceHasNoIncoming_M4.java +/ChoiceHasNoIncoming_M5.java +/ChoiceHasNoIncoming_M6.java +/ChoiceHasNoOutgoing_M0.java +/ChoiceHasNoOutgoing_M1.java +/ChoiceHasNoOutgoing_M2.java +/ChoiceHasNoOutgoing_M3.java +/ChoiceHasNoOutgoing_M4.java +/ChoiceHasNoOutgoing_M5.java +/ChoiceHasNoOutgoing_M6.java +/EntryInRegion_M0.java +/EntryInRegion_M1.java +/EntryInRegion_M2.java +/IncomingToEntry_1.java +/IncomingToEntry_2.java +/IncomingToEntry_3.java +/IncomingToEntry_4.java +/IncomingToEntry_5.java +/IncomingToEntry_M0.java +/MultipleEntryInRegion_M0.java +/MultipleEntryInRegion_M1.java +/MultipleEntryInRegion_M2.java +/MultipleEntryInRegion_M3.java +/MultipleEntryInRegion_M4.java +/MultipleEntryInRegion_M5.java +/MultipleTransitionFromEntry_M0.java +/MultipleTransitionFromEntry_M1.java +/MultipleTransitionFromEntry_M2.java +/MultipleTransitionFromEntry_M3.java +/MultipleTransitionFromEntry_M4.java +/NoEntryInRegion_M0.java +/NoEntryInRegion_M1.java +/NoEntryInRegion_M2.java +/NoEntryInRegion_M3.java +/NoEntryInRegion_M4.java +/NoEntryInRegion_M5.java +/NoOutgoingTransitionFromEntry_M0.java +/NoOutgoingTransitionFromEntry_M1.java +/NoOutgoingTransitionFromEntry_M2.java +/NoOutgoingTransitionFromEntry_M3.java +/NoOutgoingTransitionFromEntry_M4.java +/NoOutgoingTransitionFromEntry_M5.java +/NoStateInRegion_M0.java +/NoStateInRegion_M1.java +/NoStateInRegion_M2.java +/NoStateInRegion_M3.java +/OutgoingFromExit_M0.java +/OutgoingFromExit_M1.java +/OutgoingFromExit_M2.java +/OutgoingFromFinal_M0.java +/OutgoingFromFinal_M1.java +/OutgoingFromFinal_M2.java +/StateInRegion_M0.java +/StateInRegion_M1.java +/StateInRegion_M2.java +/Transition_M0.java +/Transition_M1.java +/Transition_M2.java +/Transition_M3.java +/Transition_M4.java +/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 @@ +/** + * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql + */ +package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; + +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.CompositeElement; +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.log4j.Logger; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.viatra.query.runtime.api.IPatternMatch; +import org.eclipse.viatra.query.runtime.api.IQuerySpecification; +import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; +import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; +import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; +import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; +import org.eclipse.viatra.query.runtime.emf.types.EStructuralFeatureInstancesKey; +import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; +import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; +import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; +import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; + +/** + * A pattern-specific query specification that can instantiate Matcher in a type-safe way. + * + *

Original source: + *

+ *         ///////////////////////////////
+ *         // Extra
+ *         //
+ *         //{@literal @}Constraint(severity="error", message="error", key = {s})
+ *         //pattern SynchronizedRegionDoesNotHaveParent(s : Synchronization, v : Vertex) {
+ *         //	find transition(_, v, s);
+ *         //	neg find child(_,v);
+ *         //} or {
+ *         //	find transition(_, s, v);
+ *         //	neg find child(_,v);
+ *         //}
+ *         
+ *         pattern child(parent: CompositeElement, child: Vertex) {
+ *         	CompositeElement.regions.vertices(parent, child);
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class Child extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.child pattern, + * to be used in conjunction with {@link Matcher}. + * + *

Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. + * Each instance is a (possibly partial) substitution of pattern parameters, + * usable to represent a match of the pattern in the result of a query, + * or to specify the bound (fixed) input parameters when issuing a query. + * + * @see Matcher + * + */ + public static abstract class Match extends BasePatternMatch { + private CompositeElement fParent; + + private Vertex fChild; + + private static List parameterNames = makeImmutableList("parent", "child"); + + private Match(final CompositeElement pParent, final Vertex pChild) { + this.fParent = pParent; + this.fChild = pChild; + } + + @Override + public Object get(final String parameterName) { + if ("parent".equals(parameterName)) return this.fParent; + if ("child".equals(parameterName)) return this.fChild; + return null; + } + + public CompositeElement getParent() { + return this.fParent; + } + + public Vertex getChild() { + return this.fChild; + } + + @Override + public boolean set(final String parameterName, final Object newValue) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + if ("parent".equals(parameterName) ) { + this.fParent = (CompositeElement) newValue; + return true; + } + if ("child".equals(parameterName) ) { + this.fChild = (Vertex) newValue; + return true; + } + return false; + } + + public void setParent(final CompositeElement pParent) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fParent = pParent; + } + + public void setChild(final Vertex pChild) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fChild = pChild; + } + + @Override + public String patternName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.child"; + } + + @Override + public List parameterNames() { + return Child.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fParent, fChild}; + } + + @Override + public Child.Match toImmutable() { + return isMutable() ? newMatch(fParent, fChild) : this; + } + + @Override + public String prettyPrint() { + StringBuilder result = new StringBuilder(); + result.append("\"parent\"=" + prettyPrintValue(fParent) + ", "); + result.append("\"child\"=" + prettyPrintValue(fChild)); + return result.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(fParent, fChild); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) { + return false; + } + if ((obj instanceof Child.Match)) { + Child.Match other = (Child.Match) obj; + return Objects.equals(fParent, other.fParent) && Objects.equals(fChild, other.fChild); + } else { + // this should be infrequent + if (!(obj instanceof IPatternMatch)) { + return false; + } + IPatternMatch otherSig = (IPatternMatch) obj; + return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); + } + } + + @Override + public Child specification() { + return Child.instance(); + } + + /** + * Returns an empty, mutable match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @return the empty match. + * + */ + public static Child.Match newEmptyMatch() { + return new Mutable(null, null); + } + + /** + * Returns a mutable (partial) match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @param pParent the fixed value of pattern parameter parent, or null if not bound. + * @param pChild the fixed value of pattern parameter child, or null if not bound. + * @return the new, mutable (partial) match object. + * + */ + public static Child.Match newMutableMatch(final CompositeElement pParent, final Vertex pChild) { + return new Mutable(pParent, pChild); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pParent the fixed value of pattern parameter parent, or null if not bound. + * @param pChild the fixed value of pattern parameter child, or null if not bound. + * @return the (partial) match object. + * + */ + public static Child.Match newMatch(final CompositeElement pParent, final Vertex pChild) { + return new Immutable(pParent, pChild); + } + + private static final class Mutable extends Child.Match { + Mutable(final CompositeElement pParent, final Vertex pChild) { + super(pParent, pChild); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends Child.Match { + Immutable(final CompositeElement pParent, final Vertex pChild) { + super(pParent, pChild); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.child pattern, + * providing pattern-specific query methods. + * + *

Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, + * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. + * + *

Matches of the pattern will be represented as {@link Match}. + * + *

Original source: + *

+   * ///////////////////////////////
+   * // Extra
+   * //
+   * //{@literal @}Constraint(severity="error", message="error", key = {s})
+   * //pattern SynchronizedRegionDoesNotHaveParent(s : Synchronization, v : Vertex) {
+   * //	find transition(_, v, s);
+   * //	neg find child(_,v);
+   * //} or {
+   * //	find transition(_, s, v);
+   * //	neg find child(_,v);
+   * //}
+   * 
+   * pattern child(parent: CompositeElement, child: Vertex) {
+   * 	CompositeElement.regions.vertices(parent, child);
+   * }
+   * 
+ * + * @see Match + * @see Child + * + */ + public static class Matcher extends BaseMatcher { + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + public static Child.Matcher on(final ViatraQueryEngine engine) { + // check if matcher already exists + Matcher matcher = engine.getExistingMatcher(querySpecification()); + if (matcher == null) { + matcher = (Matcher)engine.getMatcher(querySpecification()); + } + return matcher; + } + + /** + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * @return an initialized matcher + * @noreference This method is for internal matcher initialization by the framework, do not call it manually. + * + */ + public static Child.Matcher create() { + return new Matcher(); + } + + private final static int POSITION_PARENT = 0; + + private final static int POSITION_CHILD = 1; + + private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(Child.Matcher.class); + + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + private Matcher() { + super(querySpecification()); + } + + /** + * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pParent the fixed value of pattern parameter parent, or null if not bound. + * @param pChild the fixed value of pattern parameter child, or null if not bound. + * @return matches represented as a Match object. + * + */ + public Collection getAllMatches(final CompositeElement pParent, final Vertex pChild) { + return rawStreamAllMatches(new Object[]{pParent, pChild}).collect(Collectors.toSet()); + } + + /** + * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * @param pParent the fixed value of pattern parameter parent, or null if not bound. + * @param pChild the fixed value of pattern parameter child, or null if not bound. + * @return a stream of matches represented as a Match object. + * + */ + public Stream streamAllMatches(final CompositeElement pParent, final Vertex pChild) { + return rawStreamAllMatches(new Object[]{pParent, pChild}); + } + + /** + * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pParent the fixed value of pattern parameter parent, or null if not bound. + * @param pChild the fixed value of pattern parameter child, or null if not bound. + * @return a match represented as a Match object, or null if no match is found. + * + */ + public Optional getOneArbitraryMatch(final CompositeElement pParent, final Vertex pChild) { + return rawGetOneArbitraryMatch(new Object[]{pParent, pChild}); + } + + /** + * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, + * under any possible substitution of the unspecified parameters (if any). + * @param pParent the fixed value of pattern parameter parent, or null if not bound. + * @param pChild the fixed value of pattern parameter child, or null if not bound. + * @return true if the input is a valid (partial) match of the pattern. + * + */ + public boolean hasMatch(final CompositeElement pParent, final Vertex pChild) { + return rawHasMatch(new Object[]{pParent, pChild}); + } + + /** + * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pParent the fixed value of pattern parameter parent, or null if not bound. + * @param pChild the fixed value of pattern parameter child, or null if not bound. + * @return the number of pattern matches found. + * + */ + public int countMatches(final CompositeElement pParent, final Vertex pChild) { + return rawCountMatches(new Object[]{pParent, pChild}); + } + + /** + * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pParent the fixed value of pattern parameter parent, or null if not bound. + * @param pChild the fixed value of pattern parameter child, or null if not bound. + * @param processor the action that will process the selected match. + * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked + * + */ + public boolean forOneArbitraryMatch(final CompositeElement pParent, final Vertex pChild, final Consumer processor) { + return rawForOneArbitraryMatch(new Object[]{pParent, pChild}, processor); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pParent the fixed value of pattern parameter parent, or null if not bound. + * @param pChild the fixed value of pattern parameter child, or null if not bound. + * @return the (partial) match object. + * + */ + public Child.Match newMatch(final CompositeElement pParent, final Vertex pChild) { + return Child.Match.newMatch(pParent, pChild); + } + + /** + * Retrieve the set of values that occur in matches for parent. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfparent(final Object[] parameters) { + return rawStreamAllValues(POSITION_PARENT, parameters).map(CompositeElement.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for parent. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfparent() { + return rawStreamAllValuesOfparent(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for parent. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfparent() { + return rawStreamAllValuesOfparent(emptyArray()); + } + + /** + * Retrieve the set of values that occur in matches for parent. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfparent(final Child.Match partialMatch) { + return rawStreamAllValuesOfparent(partialMatch.toArray()); + } + + /** + * Retrieve the set of values that occur in matches for parent. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfparent(final Vertex pChild) { + return rawStreamAllValuesOfparent(new Object[]{null, pChild}); + } + + /** + * Retrieve the set of values that occur in matches for parent. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfparent(final Child.Match partialMatch) { + return rawStreamAllValuesOfparent(partialMatch.toArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for parent. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfparent(final Vertex pChild) { + return rawStreamAllValuesOfparent(new Object[]{null, pChild}).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for child. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfchild(final Object[] parameters) { + return rawStreamAllValues(POSITION_CHILD, parameters).map(Vertex.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for child. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfchild() { + return rawStreamAllValuesOfchild(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for child. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfchild() { + return rawStreamAllValuesOfchild(emptyArray()); + } + + /** + * Retrieve the set of values that occur in matches for child. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfchild(final Child.Match partialMatch) { + return rawStreamAllValuesOfchild(partialMatch.toArray()); + } + + /** + * Retrieve the set of values that occur in matches for child. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfchild(final CompositeElement pParent) { + return rawStreamAllValuesOfchild(new Object[]{pParent, null}); + } + + /** + * Retrieve the set of values that occur in matches for child. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfchild(final Child.Match partialMatch) { + return rawStreamAllValuesOfchild(partialMatch.toArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for child. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfchild(final CompositeElement pParent) { + return rawStreamAllValuesOfchild(new Object[]{pParent, null}).collect(Collectors.toSet()); + } + + @Override + protected Child.Match tupleToMatch(final Tuple t) { + try { + return Child.Match.newMatch((CompositeElement) t.get(POSITION_PARENT), (Vertex) t.get(POSITION_CHILD)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected Child.Match arrayToMatch(final Object[] match) { + try { + return Child.Match.newMatch((CompositeElement) match[POSITION_PARENT], (Vertex) match[POSITION_CHILD]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected Child.Match arrayToMatchMutable(final Object[] match) { + try { + return Child.Match.newMutableMatch((CompositeElement) match[POSITION_PARENT], (Vertex) match[POSITION_CHILD]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + /** + * @return the singleton instance of the query specification of this pattern + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static IQuerySpecification querySpecification() { + return Child.instance(); + } + } + + private Child() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static Child instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected Child.Matcher instantiate(final ViatraQueryEngine engine) { + return Child.Matcher.on(engine); + } + + @Override + public Child.Matcher instantiate() { + return Child.Matcher.create(); + } + + @Override + public Child.Match newEmptyMatch() { + return Child.Match.newEmptyMatch(); + } + + @Override + public Child.Match newMatch(final Object... parameters) { + return Child.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.CompositeElement) parameters[0], (ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex) parameters[1]); + } + + /** + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created + * not at the class load time of the outer class, + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private final static Child INSTANCE = new Child(); + + /** + * Statically initializes the query specification after the field {@link #INSTANCE} is assigned. + * This initialization order is required to support indirect recursion. + * + *

The static initializer is defined using a helper field to work around limitations of the code generator. + * + */ + private final static Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private final static Child.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_parent = new PParameter("parent", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.CompositeElement", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "CompositeElement")), PParameterDirection.INOUT); + + private final PParameter parameter_child = new PParameter("child", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Vertex")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_parent, parameter_child); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.child"; + } + + @Override + public List getParameterNames() { + return Arrays.asList("parent","child"); + } + + @Override + public List getParameters() { + return parameters; + } + + @Override + public Set doGetContainedBodies() { + setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); + Set bodies = new LinkedHashSet<>(); + { + PBody body = new PBody(this); + PVariable var_parent = body.getOrCreateVariableByName("parent"); + PVariable var_child = body.getOrCreateVariableByName("child"); + new TypeConstraint(body, Tuples.flatTupleOf(var_parent), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "CompositeElement"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_child), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_parent, parameter_parent), + new ExportedParameter(body, var_child, parameter_child) + )); + // CompositeElement.regions.vertices(parent, child) + new TypeConstraint(body, Tuples.flatTupleOf(var_parent), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "CompositeElement"))); + PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_parent, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "CompositeElement", "regions"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Region"))); + PVariable var__virtual_1_ = body.getOrCreateVariableByName(".virtual{1}"); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_, var__virtual_1_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Region", "vertices"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_1_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); + new Equality(body, var__virtual_1_, var_child); + bodies.add(body); + } + return bodies; + } + } +} 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 @@ +/** + * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql + */ +package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; + +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Choice; +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.Transition; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.log4j.Logger; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.viatra.query.runtime.api.IPatternMatch; +import org.eclipse.viatra.query.runtime.api.IQuerySpecification; +import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; +import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; +import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; +import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; +import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; +import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; +import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.NegativePatternCall; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; +import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; + +/** + * A pattern-specific query specification that can instantiate Matcher in a type-safe way. + * + *

Original source: + *

+ *         {@literal @}Constraint(severity="error", message="error", key = {c})
+ *         pattern choiceHasNoIncoming(c: Choice) {
+ *         	neg find transition(_, _, c);
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class ChoiceHasNoIncoming extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.choiceHasNoIncoming pattern, + * to be used in conjunction with {@link Matcher}. + * + *

Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. + * Each instance is a (possibly partial) substitution of pattern parameters, + * usable to represent a match of the pattern in the result of a query, + * or to specify the bound (fixed) input parameters when issuing a query. + * + * @see Matcher + * + */ + public static abstract class Match extends BasePatternMatch { + private Choice fC; + + private static List parameterNames = makeImmutableList("c"); + + private Match(final Choice pC) { + this.fC = pC; + } + + @Override + public Object get(final String parameterName) { + if ("c".equals(parameterName)) return this.fC; + return null; + } + + public Choice getC() { + return this.fC; + } + + @Override + public boolean set(final String parameterName, final Object newValue) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + if ("c".equals(parameterName) ) { + this.fC = (Choice) newValue; + return true; + } + return false; + } + + public void setC(final Choice pC) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fC = pC; + } + + @Override + public String patternName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.choiceHasNoIncoming"; + } + + @Override + public List parameterNames() { + return ChoiceHasNoIncoming.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fC}; + } + + @Override + public ChoiceHasNoIncoming.Match toImmutable() { + return isMutable() ? newMatch(fC) : this; + } + + @Override + public String prettyPrint() { + StringBuilder result = new StringBuilder(); + result.append("\"c\"=" + prettyPrintValue(fC)); + return result.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(fC); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) { + return false; + } + if ((obj instanceof ChoiceHasNoIncoming.Match)) { + ChoiceHasNoIncoming.Match other = (ChoiceHasNoIncoming.Match) obj; + return Objects.equals(fC, other.fC); + } else { + // this should be infrequent + if (!(obj instanceof IPatternMatch)) { + return false; + } + IPatternMatch otherSig = (IPatternMatch) obj; + return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); + } + } + + @Override + public ChoiceHasNoIncoming specification() { + return ChoiceHasNoIncoming.instance(); + } + + /** + * Returns an empty, mutable match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @return the empty match. + * + */ + public static ChoiceHasNoIncoming.Match newEmptyMatch() { + return new Mutable(null); + } + + /** + * Returns a mutable (partial) match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @param pC the fixed value of pattern parameter c, or null if not bound. + * @return the new, mutable (partial) match object. + * + */ + public static ChoiceHasNoIncoming.Match newMutableMatch(final Choice pC) { + return new Mutable(pC); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pC the fixed value of pattern parameter c, or null if not bound. + * @return the (partial) match object. + * + */ + public static ChoiceHasNoIncoming.Match newMatch(final Choice pC) { + return new Immutable(pC); + } + + private static final class Mutable extends ChoiceHasNoIncoming.Match { + Mutable(final Choice pC) { + super(pC); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends ChoiceHasNoIncoming.Match { + Immutable(final Choice pC) { + super(pC); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.choiceHasNoIncoming pattern, + * providing pattern-specific query methods. + * + *

Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, + * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. + * + *

Matches of the pattern will be represented as {@link Match}. + * + *

Original source: + *

+   * {@literal @}Constraint(severity="error", message="error", key = {c})
+   * pattern choiceHasNoIncoming(c: Choice) {
+   * 	neg find transition(_, _, c);
+   * }
+   * 
+ * + * @see Match + * @see ChoiceHasNoIncoming + * + */ + public static class Matcher extends BaseMatcher { + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + public static ChoiceHasNoIncoming.Matcher on(final ViatraQueryEngine engine) { + // check if matcher already exists + Matcher matcher = engine.getExistingMatcher(querySpecification()); + if (matcher == null) { + matcher = (Matcher)engine.getMatcher(querySpecification()); + } + return matcher; + } + + /** + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * @return an initialized matcher + * @noreference This method is for internal matcher initialization by the framework, do not call it manually. + * + */ + public static ChoiceHasNoIncoming.Matcher create() { + return new Matcher(); + } + + private final static int POSITION_C = 0; + + private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(ChoiceHasNoIncoming.Matcher.class); + + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + private Matcher() { + super(querySpecification()); + } + + /** + * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pC the fixed value of pattern parameter c, or null if not bound. + * @return matches represented as a Match object. + * + */ + public Collection getAllMatches(final Choice pC) { + return rawStreamAllMatches(new Object[]{pC}).collect(Collectors.toSet()); + } + + /** + * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * @param pC the fixed value of pattern parameter c, or null if not bound. + * @return a stream of matches represented as a Match object. + * + */ + public Stream streamAllMatches(final Choice pC) { + return rawStreamAllMatches(new Object[]{pC}); + } + + /** + * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pC the fixed value of pattern parameter c, or null if not bound. + * @return a match represented as a Match object, or null if no match is found. + * + */ + public Optional getOneArbitraryMatch(final Choice pC) { + return rawGetOneArbitraryMatch(new Object[]{pC}); + } + + /** + * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, + * under any possible substitution of the unspecified parameters (if any). + * @param pC the fixed value of pattern parameter c, or null if not bound. + * @return true if the input is a valid (partial) match of the pattern. + * + */ + public boolean hasMatch(final Choice pC) { + return rawHasMatch(new Object[]{pC}); + } + + /** + * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pC the fixed value of pattern parameter c, or null if not bound. + * @return the number of pattern matches found. + * + */ + public int countMatches(final Choice pC) { + return rawCountMatches(new Object[]{pC}); + } + + /** + * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pC the fixed value of pattern parameter c, or null if not bound. + * @param processor the action that will process the selected match. + * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked + * + */ + public boolean forOneArbitraryMatch(final Choice pC, final Consumer processor) { + return rawForOneArbitraryMatch(new Object[]{pC}, processor); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pC the fixed value of pattern parameter c, or null if not bound. + * @return the (partial) match object. + * + */ + public ChoiceHasNoIncoming.Match newMatch(final Choice pC) { + return ChoiceHasNoIncoming.Match.newMatch(pC); + } + + /** + * Retrieve the set of values that occur in matches for c. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfc(final Object[] parameters) { + return rawStreamAllValues(POSITION_C, parameters).map(Choice.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for c. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfc() { + return rawStreamAllValuesOfc(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for c. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfc() { + return rawStreamAllValuesOfc(emptyArray()); + } + + @Override + protected ChoiceHasNoIncoming.Match tupleToMatch(final Tuple t) { + try { + return ChoiceHasNoIncoming.Match.newMatch((Choice) t.get(POSITION_C)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected ChoiceHasNoIncoming.Match arrayToMatch(final Object[] match) { + try { + return ChoiceHasNoIncoming.Match.newMatch((Choice) match[POSITION_C]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected ChoiceHasNoIncoming.Match arrayToMatchMutable(final Object[] match) { + try { + return ChoiceHasNoIncoming.Match.newMutableMatch((Choice) match[POSITION_C]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + /** + * @return the singleton instance of the query specification of this pattern + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static IQuerySpecification querySpecification() { + return ChoiceHasNoIncoming.instance(); + } + } + + private ChoiceHasNoIncoming() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static ChoiceHasNoIncoming instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected ChoiceHasNoIncoming.Matcher instantiate(final ViatraQueryEngine engine) { + return ChoiceHasNoIncoming.Matcher.on(engine); + } + + @Override + public ChoiceHasNoIncoming.Matcher instantiate() { + return ChoiceHasNoIncoming.Matcher.create(); + } + + @Override + public ChoiceHasNoIncoming.Match newEmptyMatch() { + return ChoiceHasNoIncoming.Match.newEmptyMatch(); + } + + @Override + public ChoiceHasNoIncoming.Match newMatch(final Object... parameters) { + return ChoiceHasNoIncoming.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Choice) parameters[0]); + } + + /** + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created + * not at the class load time of the outer class, + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private final static ChoiceHasNoIncoming INSTANCE = new ChoiceHasNoIncoming(); + + /** + * Statically initializes the query specification after the field {@link #INSTANCE} is assigned. + * This initialization order is required to support indirect recursion. + * + *

The static initializer is defined using a helper field to work around limitations of the code generator. + * + */ + private final static Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private final static ChoiceHasNoIncoming.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_c = new PParameter("c", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Choice", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Choice")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_c); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.choiceHasNoIncoming"; + } + + @Override + public List getParameterNames() { + return Arrays.asList("c"); + } + + @Override + public List getParameters() { + return parameters; + } + + @Override + public Set doGetContainedBodies() { + setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); + Set bodies = new LinkedHashSet<>(); + { + PBody body = new PBody(this); + PVariable var_c = body.getOrCreateVariableByName("c"); + PVariable var___0_ = body.getOrCreateVariableByName("_<0>"); + PVariable var___1_ = body.getOrCreateVariableByName("_<1>"); + new TypeConstraint(body, Tuples.flatTupleOf(var_c), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Choice"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_c, parameter_c) + )); + // neg find transition(_, _, c) + new NegativePatternCall(body, Tuples.flatTupleOf(var___0_, var___1_, var_c), Transition.instance().getInternalQueryRepresentation()); + bodies.add(body); + } + { + PAnnotation annotation = new PAnnotation("Constraint"); + annotation.addAttribute("severity", "error"); + annotation.addAttribute("message", "error"); + annotation.addAttribute("key", Arrays.asList(new Object[] { + new ParameterReference("c") + })); + addAnnotation(annotation); + } + return bodies; + } + } +} 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 @@ +/** + * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql + */ +package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; + +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Choice; +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.Transition; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.log4j.Logger; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.viatra.query.runtime.api.IPatternMatch; +import org.eclipse.viatra.query.runtime.api.IQuerySpecification; +import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; +import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; +import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; +import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; +import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; +import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; +import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.NegativePatternCall; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; +import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; + +/** + * A pattern-specific query specification that can instantiate Matcher in a type-safe way. + * + *

Original source: + *

+ *         /////////
+ *         // Choice
+ *         /////////
+ *         
+ *         {@literal @}Constraint(severity="error", message="error", key = {c})
+ *         pattern choiceHasNoOutgoing(c : Choice) {
+ *         	neg find transition(_, c, _);
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class ChoiceHasNoOutgoing extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.choiceHasNoOutgoing pattern, + * to be used in conjunction with {@link Matcher}. + * + *

Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. + * Each instance is a (possibly partial) substitution of pattern parameters, + * usable to represent a match of the pattern in the result of a query, + * or to specify the bound (fixed) input parameters when issuing a query. + * + * @see Matcher + * + */ + public static abstract class Match extends BasePatternMatch { + private Choice fC; + + private static List parameterNames = makeImmutableList("c"); + + private Match(final Choice pC) { + this.fC = pC; + } + + @Override + public Object get(final String parameterName) { + if ("c".equals(parameterName)) return this.fC; + return null; + } + + public Choice getC() { + return this.fC; + } + + @Override + public boolean set(final String parameterName, final Object newValue) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + if ("c".equals(parameterName) ) { + this.fC = (Choice) newValue; + return true; + } + return false; + } + + public void setC(final Choice pC) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fC = pC; + } + + @Override + public String patternName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.choiceHasNoOutgoing"; + } + + @Override + public List parameterNames() { + return ChoiceHasNoOutgoing.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fC}; + } + + @Override + public ChoiceHasNoOutgoing.Match toImmutable() { + return isMutable() ? newMatch(fC) : this; + } + + @Override + public String prettyPrint() { + StringBuilder result = new StringBuilder(); + result.append("\"c\"=" + prettyPrintValue(fC)); + return result.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(fC); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) { + return false; + } + if ((obj instanceof ChoiceHasNoOutgoing.Match)) { + ChoiceHasNoOutgoing.Match other = (ChoiceHasNoOutgoing.Match) obj; + return Objects.equals(fC, other.fC); + } else { + // this should be infrequent + if (!(obj instanceof IPatternMatch)) { + return false; + } + IPatternMatch otherSig = (IPatternMatch) obj; + return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); + } + } + + @Override + public ChoiceHasNoOutgoing specification() { + return ChoiceHasNoOutgoing.instance(); + } + + /** + * Returns an empty, mutable match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @return the empty match. + * + */ + public static ChoiceHasNoOutgoing.Match newEmptyMatch() { + return new Mutable(null); + } + + /** + * Returns a mutable (partial) match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @param pC the fixed value of pattern parameter c, or null if not bound. + * @return the new, mutable (partial) match object. + * + */ + public static ChoiceHasNoOutgoing.Match newMutableMatch(final Choice pC) { + return new Mutable(pC); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pC the fixed value of pattern parameter c, or null if not bound. + * @return the (partial) match object. + * + */ + public static ChoiceHasNoOutgoing.Match newMatch(final Choice pC) { + return new Immutable(pC); + } + + private static final class Mutable extends ChoiceHasNoOutgoing.Match { + Mutable(final Choice pC) { + super(pC); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends ChoiceHasNoOutgoing.Match { + Immutable(final Choice pC) { + super(pC); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.choiceHasNoOutgoing pattern, + * providing pattern-specific query methods. + * + *

Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, + * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. + * + *

Matches of the pattern will be represented as {@link Match}. + * + *

Original source: + *

+   * /////////
+   * // Choice
+   * /////////
+   * 
+   * {@literal @}Constraint(severity="error", message="error", key = {c})
+   * pattern choiceHasNoOutgoing(c : Choice) {
+   * 	neg find transition(_, c, _);
+   * }
+   * 
+ * + * @see Match + * @see ChoiceHasNoOutgoing + * + */ + public static class Matcher extends BaseMatcher { + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + public static ChoiceHasNoOutgoing.Matcher on(final ViatraQueryEngine engine) { + // check if matcher already exists + Matcher matcher = engine.getExistingMatcher(querySpecification()); + if (matcher == null) { + matcher = (Matcher)engine.getMatcher(querySpecification()); + } + return matcher; + } + + /** + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * @return an initialized matcher + * @noreference This method is for internal matcher initialization by the framework, do not call it manually. + * + */ + public static ChoiceHasNoOutgoing.Matcher create() { + return new Matcher(); + } + + private final static int POSITION_C = 0; + + private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(ChoiceHasNoOutgoing.Matcher.class); + + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + private Matcher() { + super(querySpecification()); + } + + /** + * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pC the fixed value of pattern parameter c, or null if not bound. + * @return matches represented as a Match object. + * + */ + public Collection getAllMatches(final Choice pC) { + return rawStreamAllMatches(new Object[]{pC}).collect(Collectors.toSet()); + } + + /** + * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * @param pC the fixed value of pattern parameter c, or null if not bound. + * @return a stream of matches represented as a Match object. + * + */ + public Stream streamAllMatches(final Choice pC) { + return rawStreamAllMatches(new Object[]{pC}); + } + + /** + * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pC the fixed value of pattern parameter c, or null if not bound. + * @return a match represented as a Match object, or null if no match is found. + * + */ + public Optional getOneArbitraryMatch(final Choice pC) { + return rawGetOneArbitraryMatch(new Object[]{pC}); + } + + /** + * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, + * under any possible substitution of the unspecified parameters (if any). + * @param pC the fixed value of pattern parameter c, or null if not bound. + * @return true if the input is a valid (partial) match of the pattern. + * + */ + public boolean hasMatch(final Choice pC) { + return rawHasMatch(new Object[]{pC}); + } + + /** + * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pC the fixed value of pattern parameter c, or null if not bound. + * @return the number of pattern matches found. + * + */ + public int countMatches(final Choice pC) { + return rawCountMatches(new Object[]{pC}); + } + + /** + * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pC the fixed value of pattern parameter c, or null if not bound. + * @param processor the action that will process the selected match. + * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked + * + */ + public boolean forOneArbitraryMatch(final Choice pC, final Consumer processor) { + return rawForOneArbitraryMatch(new Object[]{pC}, processor); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pC the fixed value of pattern parameter c, or null if not bound. + * @return the (partial) match object. + * + */ + public ChoiceHasNoOutgoing.Match newMatch(final Choice pC) { + return ChoiceHasNoOutgoing.Match.newMatch(pC); + } + + /** + * Retrieve the set of values that occur in matches for c. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfc(final Object[] parameters) { + return rawStreamAllValues(POSITION_C, parameters).map(Choice.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for c. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfc() { + return rawStreamAllValuesOfc(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for c. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfc() { + return rawStreamAllValuesOfc(emptyArray()); + } + + @Override + protected ChoiceHasNoOutgoing.Match tupleToMatch(final Tuple t) { + try { + return ChoiceHasNoOutgoing.Match.newMatch((Choice) t.get(POSITION_C)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected ChoiceHasNoOutgoing.Match arrayToMatch(final Object[] match) { + try { + return ChoiceHasNoOutgoing.Match.newMatch((Choice) match[POSITION_C]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected ChoiceHasNoOutgoing.Match arrayToMatchMutable(final Object[] match) { + try { + return ChoiceHasNoOutgoing.Match.newMutableMatch((Choice) match[POSITION_C]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + /** + * @return the singleton instance of the query specification of this pattern + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static IQuerySpecification querySpecification() { + return ChoiceHasNoOutgoing.instance(); + } + } + + private ChoiceHasNoOutgoing() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static ChoiceHasNoOutgoing instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected ChoiceHasNoOutgoing.Matcher instantiate(final ViatraQueryEngine engine) { + return ChoiceHasNoOutgoing.Matcher.on(engine); + } + + @Override + public ChoiceHasNoOutgoing.Matcher instantiate() { + return ChoiceHasNoOutgoing.Matcher.create(); + } + + @Override + public ChoiceHasNoOutgoing.Match newEmptyMatch() { + return ChoiceHasNoOutgoing.Match.newEmptyMatch(); + } + + @Override + public ChoiceHasNoOutgoing.Match newMatch(final Object... parameters) { + return ChoiceHasNoOutgoing.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Choice) parameters[0]); + } + + /** + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created + * not at the class load time of the outer class, + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private final static ChoiceHasNoOutgoing INSTANCE = new ChoiceHasNoOutgoing(); + + /** + * Statically initializes the query specification after the field {@link #INSTANCE} is assigned. + * This initialization order is required to support indirect recursion. + * + *

The static initializer is defined using a helper field to work around limitations of the code generator. + * + */ + private final static Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private final static ChoiceHasNoOutgoing.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_c = new PParameter("c", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Choice", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Choice")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_c); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.choiceHasNoOutgoing"; + } + + @Override + public List getParameterNames() { + return Arrays.asList("c"); + } + + @Override + public List getParameters() { + return parameters; + } + + @Override + public Set doGetContainedBodies() { + setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); + Set bodies = new LinkedHashSet<>(); + { + PBody body = new PBody(this); + PVariable var_c = body.getOrCreateVariableByName("c"); + PVariable var___0_ = body.getOrCreateVariableByName("_<0>"); + PVariable var___1_ = body.getOrCreateVariableByName("_<1>"); + new TypeConstraint(body, Tuples.flatTupleOf(var_c), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Choice"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_c, parameter_c) + )); + // neg find transition(_, c, _) + new NegativePatternCall(body, Tuples.flatTupleOf(var___0_, var_c, var___1_), Transition.instance().getInternalQueryRepresentation()); + bodies.add(body); + } + { + PAnnotation annotation = new PAnnotation("Constraint"); + annotation.addAttribute("severity", "error"); + annotation.addAttribute("message", "error"); + annotation.addAttribute("key", Arrays.asList(new Object[] { + new ParameterReference("c") + })); + addAnnotation(annotation); + } + return bodies; + } + } +} 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 @@ +/** + * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql + */ +package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; + +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Entry; +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Region; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.log4j.Logger; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.viatra.query.runtime.api.IPatternMatch; +import org.eclipse.viatra.query.runtime.api.IQuerySpecification; +import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; +import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; +import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; +import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; +import org.eclipse.viatra.query.runtime.emf.types.EStructuralFeatureInstancesKey; +import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; +import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; +import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; +import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; + +/** + * A pattern-specific query specification that can instantiate Matcher in a type-safe way. + * + *

Original source: + *

+ *         /////////
+ *         // Entry
+ *         /////////
+ *         
+ *         pattern entryInRegion(r1 : Region, e1 : Entry) {
+ *         	Region.vertices(r1, e1);
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class EntryInRegion extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.entryInRegion pattern, + * to be used in conjunction with {@link Matcher}. + * + *

Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. + * Each instance is a (possibly partial) substitution of pattern parameters, + * usable to represent a match of the pattern in the result of a query, + * or to specify the bound (fixed) input parameters when issuing a query. + * + * @see Matcher + * + */ + public static abstract class Match extends BasePatternMatch { + private Region fR1; + + private Entry fE1; + + private static List parameterNames = makeImmutableList("r1", "e1"); + + private Match(final Region pR1, final Entry pE1) { + this.fR1 = pR1; + this.fE1 = pE1; + } + + @Override + public Object get(final String parameterName) { + if ("r1".equals(parameterName)) return this.fR1; + if ("e1".equals(parameterName)) return this.fE1; + return null; + } + + public Region getR1() { + return this.fR1; + } + + public Entry getE1() { + return this.fE1; + } + + @Override + public boolean set(final String parameterName, final Object newValue) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + if ("r1".equals(parameterName) ) { + this.fR1 = (Region) newValue; + return true; + } + if ("e1".equals(parameterName) ) { + this.fE1 = (Entry) newValue; + return true; + } + return false; + } + + public void setR1(final Region pR1) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fR1 = pR1; + } + + public void setE1(final Entry pE1) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fE1 = pE1; + } + + @Override + public String patternName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.entryInRegion"; + } + + @Override + public List parameterNames() { + return EntryInRegion.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fR1, fE1}; + } + + @Override + public EntryInRegion.Match toImmutable() { + return isMutable() ? newMatch(fR1, fE1) : this; + } + + @Override + public String prettyPrint() { + StringBuilder result = new StringBuilder(); + result.append("\"r1\"=" + prettyPrintValue(fR1) + ", "); + result.append("\"e1\"=" + prettyPrintValue(fE1)); + return result.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(fR1, fE1); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) { + return false; + } + if ((obj instanceof EntryInRegion.Match)) { + EntryInRegion.Match other = (EntryInRegion.Match) obj; + return Objects.equals(fR1, other.fR1) && Objects.equals(fE1, other.fE1); + } else { + // this should be infrequent + if (!(obj instanceof IPatternMatch)) { + return false; + } + IPatternMatch otherSig = (IPatternMatch) obj; + return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); + } + } + + @Override + public EntryInRegion specification() { + return EntryInRegion.instance(); + } + + /** + * Returns an empty, mutable match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @return the empty match. + * + */ + public static EntryInRegion.Match newEmptyMatch() { + return new Mutable(null, null); + } + + /** + * Returns a mutable (partial) match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @param pR1 the fixed value of pattern parameter r1, or null if not bound. + * @param pE1 the fixed value of pattern parameter e1, or null if not bound. + * @return the new, mutable (partial) match object. + * + */ + public static EntryInRegion.Match newMutableMatch(final Region pR1, final Entry pE1) { + return new Mutable(pR1, pE1); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pR1 the fixed value of pattern parameter r1, or null if not bound. + * @param pE1 the fixed value of pattern parameter e1, or null if not bound. + * @return the (partial) match object. + * + */ + public static EntryInRegion.Match newMatch(final Region pR1, final Entry pE1) { + return new Immutable(pR1, pE1); + } + + private static final class Mutable extends EntryInRegion.Match { + Mutable(final Region pR1, final Entry pE1) { + super(pR1, pE1); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends EntryInRegion.Match { + Immutable(final Region pR1, final Entry pE1) { + super(pR1, pE1); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.entryInRegion pattern, + * providing pattern-specific query methods. + * + *

Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, + * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. + * + *

Matches of the pattern will be represented as {@link Match}. + * + *

Original source: + *

+   * /////////
+   * // Entry
+   * /////////
+   * 
+   * pattern entryInRegion(r1 : Region, e1 : Entry) {
+   * 	Region.vertices(r1, e1);
+   * }
+   * 
+ * + * @see Match + * @see EntryInRegion + * + */ + public static class Matcher extends BaseMatcher { + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + public static EntryInRegion.Matcher on(final ViatraQueryEngine engine) { + // check if matcher already exists + Matcher matcher = engine.getExistingMatcher(querySpecification()); + if (matcher == null) { + matcher = (Matcher)engine.getMatcher(querySpecification()); + } + return matcher; + } + + /** + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * @return an initialized matcher + * @noreference This method is for internal matcher initialization by the framework, do not call it manually. + * + */ + public static EntryInRegion.Matcher create() { + return new Matcher(); + } + + private final static int POSITION_R1 = 0; + + private final static int POSITION_E1 = 1; + + private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(EntryInRegion.Matcher.class); + + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + private Matcher() { + super(querySpecification()); + } + + /** + * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pR1 the fixed value of pattern parameter r1, or null if not bound. + * @param pE1 the fixed value of pattern parameter e1, or null if not bound. + * @return matches represented as a Match object. + * + */ + public Collection getAllMatches(final Region pR1, final Entry pE1) { + return rawStreamAllMatches(new Object[]{pR1, pE1}).collect(Collectors.toSet()); + } + + /** + * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * @param pR1 the fixed value of pattern parameter r1, or null if not bound. + * @param pE1 the fixed value of pattern parameter e1, or null if not bound. + * @return a stream of matches represented as a Match object. + * + */ + public Stream streamAllMatches(final Region pR1, final Entry pE1) { + return rawStreamAllMatches(new Object[]{pR1, pE1}); + } + + /** + * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pR1 the fixed value of pattern parameter r1, or null if not bound. + * @param pE1 the fixed value of pattern parameter e1, or null if not bound. + * @return a match represented as a Match object, or null if no match is found. + * + */ + public Optional getOneArbitraryMatch(final Region pR1, final Entry pE1) { + return rawGetOneArbitraryMatch(new Object[]{pR1, pE1}); + } + + /** + * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, + * under any possible substitution of the unspecified parameters (if any). + * @param pR1 the fixed value of pattern parameter r1, or null if not bound. + * @param pE1 the fixed value of pattern parameter e1, or null if not bound. + * @return true if the input is a valid (partial) match of the pattern. + * + */ + public boolean hasMatch(final Region pR1, final Entry pE1) { + return rawHasMatch(new Object[]{pR1, pE1}); + } + + /** + * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pR1 the fixed value of pattern parameter r1, or null if not bound. + * @param pE1 the fixed value of pattern parameter e1, or null if not bound. + * @return the number of pattern matches found. + * + */ + public int countMatches(final Region pR1, final Entry pE1) { + return rawCountMatches(new Object[]{pR1, pE1}); + } + + /** + * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pR1 the fixed value of pattern parameter r1, or null if not bound. + * @param pE1 the fixed value of pattern parameter e1, or null if not bound. + * @param processor the action that will process the selected match. + * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked + * + */ + public boolean forOneArbitraryMatch(final Region pR1, final Entry pE1, final Consumer processor) { + return rawForOneArbitraryMatch(new Object[]{pR1, pE1}, processor); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pR1 the fixed value of pattern parameter r1, or null if not bound. + * @param pE1 the fixed value of pattern parameter e1, or null if not bound. + * @return the (partial) match object. + * + */ + public EntryInRegion.Match newMatch(final Region pR1, final Entry pE1) { + return EntryInRegion.Match.newMatch(pR1, pE1); + } + + /** + * Retrieve the set of values that occur in matches for r1. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfr1(final Object[] parameters) { + return rawStreamAllValues(POSITION_R1, parameters).map(Region.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for r1. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfr1() { + return rawStreamAllValuesOfr1(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for r1. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfr1() { + return rawStreamAllValuesOfr1(emptyArray()); + } + + /** + * Retrieve the set of values that occur in matches for r1. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfr1(final EntryInRegion.Match partialMatch) { + return rawStreamAllValuesOfr1(partialMatch.toArray()); + } + + /** + * Retrieve the set of values that occur in matches for r1. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfr1(final Entry pE1) { + return rawStreamAllValuesOfr1(new Object[]{null, pE1}); + } + + /** + * Retrieve the set of values that occur in matches for r1. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfr1(final EntryInRegion.Match partialMatch) { + return rawStreamAllValuesOfr1(partialMatch.toArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for r1. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfr1(final Entry pE1) { + return rawStreamAllValuesOfr1(new Object[]{null, pE1}).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for e1. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfe1(final Object[] parameters) { + return rawStreamAllValues(POSITION_E1, parameters).map(Entry.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for e1. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfe1() { + return rawStreamAllValuesOfe1(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for e1. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfe1() { + return rawStreamAllValuesOfe1(emptyArray()); + } + + /** + * Retrieve the set of values that occur in matches for e1. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfe1(final EntryInRegion.Match partialMatch) { + return rawStreamAllValuesOfe1(partialMatch.toArray()); + } + + /** + * Retrieve the set of values that occur in matches for e1. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfe1(final Region pR1) { + return rawStreamAllValuesOfe1(new Object[]{pR1, null}); + } + + /** + * Retrieve the set of values that occur in matches for e1. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfe1(final EntryInRegion.Match partialMatch) { + return rawStreamAllValuesOfe1(partialMatch.toArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for e1. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfe1(final Region pR1) { + return rawStreamAllValuesOfe1(new Object[]{pR1, null}).collect(Collectors.toSet()); + } + + @Override + protected EntryInRegion.Match tupleToMatch(final Tuple t) { + try { + return EntryInRegion.Match.newMatch((Region) t.get(POSITION_R1), (Entry) t.get(POSITION_E1)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected EntryInRegion.Match arrayToMatch(final Object[] match) { + try { + return EntryInRegion.Match.newMatch((Region) match[POSITION_R1], (Entry) match[POSITION_E1]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected EntryInRegion.Match arrayToMatchMutable(final Object[] match) { + try { + return EntryInRegion.Match.newMutableMatch((Region) match[POSITION_R1], (Entry) match[POSITION_E1]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + /** + * @return the singleton instance of the query specification of this pattern + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static IQuerySpecification querySpecification() { + return EntryInRegion.instance(); + } + } + + private EntryInRegion() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static EntryInRegion instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected EntryInRegion.Matcher instantiate(final ViatraQueryEngine engine) { + return EntryInRegion.Matcher.on(engine); + } + + @Override + public EntryInRegion.Matcher instantiate() { + return EntryInRegion.Matcher.create(); + } + + @Override + public EntryInRegion.Match newEmptyMatch() { + return EntryInRegion.Match.newEmptyMatch(); + } + + @Override + public EntryInRegion.Match newMatch(final Object... parameters) { + return EntryInRegion.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Region) parameters[0], (ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Entry) parameters[1]); + } + + /** + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created + * not at the class load time of the outer class, + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private final static EntryInRegion INSTANCE = new EntryInRegion(); + + /** + * Statically initializes the query specification after the field {@link #INSTANCE} is assigned. + * This initialization order is required to support indirect recursion. + * + *

The static initializer is defined using a helper field to work around limitations of the code generator. + * + */ + private final static Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private final static EntryInRegion.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_r1 = new PParameter("r1", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Region", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Region")), PParameterDirection.INOUT); + + private final PParameter parameter_e1 = new PParameter("e1", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Entry", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Entry")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_r1, parameter_e1); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.entryInRegion"; + } + + @Override + public List getParameterNames() { + return Arrays.asList("r1","e1"); + } + + @Override + public List getParameters() { + return parameters; + } + + @Override + public Set doGetContainedBodies() { + setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); + Set bodies = new LinkedHashSet<>(); + { + PBody body = new PBody(this); + PVariable var_r1 = body.getOrCreateVariableByName("r1"); + PVariable var_e1 = body.getOrCreateVariableByName("e1"); + new TypeConstraint(body, Tuples.flatTupleOf(var_r1), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Region"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_e1), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Entry"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_r1, parameter_r1), + new ExportedParameter(body, var_e1, parameter_e1) + )); + // Region.vertices(r1, e1) + new TypeConstraint(body, Tuples.flatTupleOf(var_r1), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Region"))); + PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_r1, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Region", "vertices"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); + new Equality(body, var__virtual_0_, var_e1); + bodies.add(body); + } + return bodies; + } + } +} 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 @@ +/** + * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql + */ +package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; + +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization; +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.Transition; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.log4j.Logger; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.viatra.query.runtime.api.IPatternMatch; +import org.eclipse.viatra.query.runtime.api.IQuerySpecification; +import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; +import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; +import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; +import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; +import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; +import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; +import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Inequality; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; +import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; + +/** + * A pattern-specific query specification that can instantiate Matcher in a type-safe way. + * + *

Original source: + *

+ *         pattern hasMultipleIncomingTrainsition(v : Synchronization) {
+ *         	find transition(_, src1, v);
+ *         	find transition(_, src2, v);
+ *         	src1 != src2;
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class HasMultipleIncomingTrainsition extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.hasMultipleIncomingTrainsition pattern, + * to be used in conjunction with {@link Matcher}. + * + *

Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. + * Each instance is a (possibly partial) substitution of pattern parameters, + * usable to represent a match of the pattern in the result of a query, + * or to specify the bound (fixed) input parameters when issuing a query. + * + * @see Matcher + * + */ + public static abstract class Match extends BasePatternMatch { + private Synchronization fV; + + private static List parameterNames = makeImmutableList("v"); + + private Match(final Synchronization pV) { + this.fV = pV; + } + + @Override + public Object get(final String parameterName) { + if ("v".equals(parameterName)) return this.fV; + return null; + } + + public Synchronization getV() { + return this.fV; + } + + @Override + public boolean set(final String parameterName, final Object newValue) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + if ("v".equals(parameterName) ) { + this.fV = (Synchronization) newValue; + return true; + } + return false; + } + + public void setV(final Synchronization pV) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fV = pV; + } + + @Override + public String patternName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.hasMultipleIncomingTrainsition"; + } + + @Override + public List parameterNames() { + return HasMultipleIncomingTrainsition.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fV}; + } + + @Override + public HasMultipleIncomingTrainsition.Match toImmutable() { + return isMutable() ? newMatch(fV) : this; + } + + @Override + public String prettyPrint() { + StringBuilder result = new StringBuilder(); + result.append("\"v\"=" + prettyPrintValue(fV)); + return result.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(fV); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) { + return false; + } + if ((obj instanceof HasMultipleIncomingTrainsition.Match)) { + HasMultipleIncomingTrainsition.Match other = (HasMultipleIncomingTrainsition.Match) obj; + return Objects.equals(fV, other.fV); + } else { + // this should be infrequent + if (!(obj instanceof IPatternMatch)) { + return false; + } + IPatternMatch otherSig = (IPatternMatch) obj; + return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); + } + } + + @Override + public HasMultipleIncomingTrainsition specification() { + return HasMultipleIncomingTrainsition.instance(); + } + + /** + * Returns an empty, mutable match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @return the empty match. + * + */ + public static HasMultipleIncomingTrainsition.Match newEmptyMatch() { + return new Mutable(null); + } + + /** + * Returns a mutable (partial) match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @param pV the fixed value of pattern parameter v, or null if not bound. + * @return the new, mutable (partial) match object. + * + */ + public static HasMultipleIncomingTrainsition.Match newMutableMatch(final Synchronization pV) { + return new Mutable(pV); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pV the fixed value of pattern parameter v, or null if not bound. + * @return the (partial) match object. + * + */ + public static HasMultipleIncomingTrainsition.Match newMatch(final Synchronization pV) { + return new Immutable(pV); + } + + private static final class Mutable extends HasMultipleIncomingTrainsition.Match { + Mutable(final Synchronization pV) { + super(pV); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends HasMultipleIncomingTrainsition.Match { + Immutable(final Synchronization pV) { + super(pV); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.hasMultipleIncomingTrainsition pattern, + * providing pattern-specific query methods. + * + *

Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, + * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. + * + *

Matches of the pattern will be represented as {@link Match}. + * + *

Original source: + *

+   * pattern hasMultipleIncomingTrainsition(v : Synchronization) {
+   * 	find transition(_, src1, v);
+   * 	find transition(_, src2, v);
+   * 	src1 != src2;
+   * }
+   * 
+ * + * @see Match + * @see HasMultipleIncomingTrainsition + * + */ + public static class Matcher extends BaseMatcher { + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + public static HasMultipleIncomingTrainsition.Matcher on(final ViatraQueryEngine engine) { + // check if matcher already exists + Matcher matcher = engine.getExistingMatcher(querySpecification()); + if (matcher == null) { + matcher = (Matcher)engine.getMatcher(querySpecification()); + } + return matcher; + } + + /** + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * @return an initialized matcher + * @noreference This method is for internal matcher initialization by the framework, do not call it manually. + * + */ + public static HasMultipleIncomingTrainsition.Matcher create() { + return new Matcher(); + } + + private final static int POSITION_V = 0; + + private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(HasMultipleIncomingTrainsition.Matcher.class); + + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + private Matcher() { + super(querySpecification()); + } + + /** + * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pV the fixed value of pattern parameter v, or null if not bound. + * @return matches represented as a Match object. + * + */ + public Collection getAllMatches(final Synchronization pV) { + return rawStreamAllMatches(new Object[]{pV}).collect(Collectors.toSet()); + } + + /** + * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * @param pV the fixed value of pattern parameter v, or null if not bound. + * @return a stream of matches represented as a Match object. + * + */ + public Stream streamAllMatches(final Synchronization pV) { + return rawStreamAllMatches(new Object[]{pV}); + } + + /** + * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pV the fixed value of pattern parameter v, or null if not bound. + * @return a match represented as a Match object, or null if no match is found. + * + */ + public Optional getOneArbitraryMatch(final Synchronization pV) { + return rawGetOneArbitraryMatch(new Object[]{pV}); + } + + /** + * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, + * under any possible substitution of the unspecified parameters (if any). + * @param pV the fixed value of pattern parameter v, or null if not bound. + * @return true if the input is a valid (partial) match of the pattern. + * + */ + public boolean hasMatch(final Synchronization pV) { + return rawHasMatch(new Object[]{pV}); + } + + /** + * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pV the fixed value of pattern parameter v, or null if not bound. + * @return the number of pattern matches found. + * + */ + public int countMatches(final Synchronization pV) { + return rawCountMatches(new Object[]{pV}); + } + + /** + * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pV the fixed value of pattern parameter v, or null if not bound. + * @param processor the action that will process the selected match. + * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked + * + */ + public boolean forOneArbitraryMatch(final Synchronization pV, final Consumer processor) { + return rawForOneArbitraryMatch(new Object[]{pV}, processor); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pV the fixed value of pattern parameter v, or null if not bound. + * @return the (partial) match object. + * + */ + public HasMultipleIncomingTrainsition.Match newMatch(final Synchronization pV) { + return HasMultipleIncomingTrainsition.Match.newMatch(pV); + } + + /** + * Retrieve the set of values that occur in matches for v. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfv(final Object[] parameters) { + return rawStreamAllValues(POSITION_V, parameters).map(Synchronization.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for v. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfv() { + return rawStreamAllValuesOfv(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for v. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfv() { + return rawStreamAllValuesOfv(emptyArray()); + } + + @Override + protected HasMultipleIncomingTrainsition.Match tupleToMatch(final Tuple t) { + try { + return HasMultipleIncomingTrainsition.Match.newMatch((Synchronization) t.get(POSITION_V)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected HasMultipleIncomingTrainsition.Match arrayToMatch(final Object[] match) { + try { + return HasMultipleIncomingTrainsition.Match.newMatch((Synchronization) match[POSITION_V]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected HasMultipleIncomingTrainsition.Match arrayToMatchMutable(final Object[] match) { + try { + return HasMultipleIncomingTrainsition.Match.newMutableMatch((Synchronization) match[POSITION_V]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + /** + * @return the singleton instance of the query specification of this pattern + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static IQuerySpecification querySpecification() { + return HasMultipleIncomingTrainsition.instance(); + } + } + + private HasMultipleIncomingTrainsition() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static HasMultipleIncomingTrainsition instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected HasMultipleIncomingTrainsition.Matcher instantiate(final ViatraQueryEngine engine) { + return HasMultipleIncomingTrainsition.Matcher.on(engine); + } + + @Override + public HasMultipleIncomingTrainsition.Matcher instantiate() { + return HasMultipleIncomingTrainsition.Matcher.create(); + } + + @Override + public HasMultipleIncomingTrainsition.Match newEmptyMatch() { + return HasMultipleIncomingTrainsition.Match.newEmptyMatch(); + } + + @Override + public HasMultipleIncomingTrainsition.Match newMatch(final Object... parameters) { + return HasMultipleIncomingTrainsition.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization) parameters[0]); + } + + /** + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created + * not at the class load time of the outer class, + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private final static HasMultipleIncomingTrainsition INSTANCE = new HasMultipleIncomingTrainsition(); + + /** + * Statically initializes the query specification after the field {@link #INSTANCE} is assigned. + * This initialization order is required to support indirect recursion. + * + *

The static initializer is defined using a helper field to work around limitations of the code generator. + * + */ + private final static Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private final static HasMultipleIncomingTrainsition.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_v = new PParameter("v", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Synchronization")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_v); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.hasMultipleIncomingTrainsition"; + } + + @Override + public List getParameterNames() { + return Arrays.asList("v"); + } + + @Override + public List getParameters() { + return parameters; + } + + @Override + public Set doGetContainedBodies() { + setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); + Set bodies = new LinkedHashSet<>(); + { + PBody body = new PBody(this); + PVariable var_v = body.getOrCreateVariableByName("v"); + PVariable var___0_ = body.getOrCreateVariableByName("_<0>"); + PVariable var_src1 = body.getOrCreateVariableByName("src1"); + PVariable var___1_ = body.getOrCreateVariableByName("_<1>"); + PVariable var_src2 = body.getOrCreateVariableByName("src2"); + new TypeConstraint(body, Tuples.flatTupleOf(var_v), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Synchronization"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_v, parameter_v) + )); + // find transition(_, src1, v) + new PositivePatternCall(body, Tuples.flatTupleOf(var___0_, var_src1, var_v), Transition.instance().getInternalQueryRepresentation()); + // find transition(_, src2, v) + new PositivePatternCall(body, Tuples.flatTupleOf(var___1_, var_src2, var_v), Transition.instance().getInternalQueryRepresentation()); + // src1 != src2 + new Inequality(body, var_src1, var_src2); + bodies.add(body); + } + return bodies; + } + } +} 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 @@ +/** + * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql + */ +package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; + +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization; +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.Transition; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.log4j.Logger; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.viatra.query.runtime.api.IPatternMatch; +import org.eclipse.viatra.query.runtime.api.IQuerySpecification; +import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; +import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; +import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; +import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; +import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; +import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; +import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Inequality; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; +import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; + +/** + * A pattern-specific query specification that can instantiate Matcher in a type-safe way. + * + *

Original source: + *

+ *         pattern hasMultipleOutgoingTrainsition(v : Synchronization) {
+ *         	find transition(_, v, trg1);
+ *         	find transition(_, v, trg2);
+ *         	trg1 != trg2;
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class HasMultipleOutgoingTrainsition extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.hasMultipleOutgoingTrainsition pattern, + * to be used in conjunction with {@link Matcher}. + * + *

Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. + * Each instance is a (possibly partial) substitution of pattern parameters, + * usable to represent a match of the pattern in the result of a query, + * or to specify the bound (fixed) input parameters when issuing a query. + * + * @see Matcher + * + */ + public static abstract class Match extends BasePatternMatch { + private Synchronization fV; + + private static List parameterNames = makeImmutableList("v"); + + private Match(final Synchronization pV) { + this.fV = pV; + } + + @Override + public Object get(final String parameterName) { + if ("v".equals(parameterName)) return this.fV; + return null; + } + + public Synchronization getV() { + return this.fV; + } + + @Override + public boolean set(final String parameterName, final Object newValue) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + if ("v".equals(parameterName) ) { + this.fV = (Synchronization) newValue; + return true; + } + return false; + } + + public void setV(final Synchronization pV) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fV = pV; + } + + @Override + public String patternName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.hasMultipleOutgoingTrainsition"; + } + + @Override + public List parameterNames() { + return HasMultipleOutgoingTrainsition.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fV}; + } + + @Override + public HasMultipleOutgoingTrainsition.Match toImmutable() { + return isMutable() ? newMatch(fV) : this; + } + + @Override + public String prettyPrint() { + StringBuilder result = new StringBuilder(); + result.append("\"v\"=" + prettyPrintValue(fV)); + return result.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(fV); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) { + return false; + } + if ((obj instanceof HasMultipleOutgoingTrainsition.Match)) { + HasMultipleOutgoingTrainsition.Match other = (HasMultipleOutgoingTrainsition.Match) obj; + return Objects.equals(fV, other.fV); + } else { + // this should be infrequent + if (!(obj instanceof IPatternMatch)) { + return false; + } + IPatternMatch otherSig = (IPatternMatch) obj; + return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); + } + } + + @Override + public HasMultipleOutgoingTrainsition specification() { + return HasMultipleOutgoingTrainsition.instance(); + } + + /** + * Returns an empty, mutable match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @return the empty match. + * + */ + public static HasMultipleOutgoingTrainsition.Match newEmptyMatch() { + return new Mutable(null); + } + + /** + * Returns a mutable (partial) match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @param pV the fixed value of pattern parameter v, or null if not bound. + * @return the new, mutable (partial) match object. + * + */ + public static HasMultipleOutgoingTrainsition.Match newMutableMatch(final Synchronization pV) { + return new Mutable(pV); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pV the fixed value of pattern parameter v, or null if not bound. + * @return the (partial) match object. + * + */ + public static HasMultipleOutgoingTrainsition.Match newMatch(final Synchronization pV) { + return new Immutable(pV); + } + + private static final class Mutable extends HasMultipleOutgoingTrainsition.Match { + Mutable(final Synchronization pV) { + super(pV); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends HasMultipleOutgoingTrainsition.Match { + Immutable(final Synchronization pV) { + super(pV); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.hasMultipleOutgoingTrainsition pattern, + * providing pattern-specific query methods. + * + *

Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, + * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. + * + *

Matches of the pattern will be represented as {@link Match}. + * + *

Original source: + *

+   * pattern hasMultipleOutgoingTrainsition(v : Synchronization) {
+   * 	find transition(_, v, trg1);
+   * 	find transition(_, v, trg2);
+   * 	trg1 != trg2;
+   * }
+   * 
+ * + * @see Match + * @see HasMultipleOutgoingTrainsition + * + */ + public static class Matcher extends BaseMatcher { + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + public static HasMultipleOutgoingTrainsition.Matcher on(final ViatraQueryEngine engine) { + // check if matcher already exists + Matcher matcher = engine.getExistingMatcher(querySpecification()); + if (matcher == null) { + matcher = (Matcher)engine.getMatcher(querySpecification()); + } + return matcher; + } + + /** + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * @return an initialized matcher + * @noreference This method is for internal matcher initialization by the framework, do not call it manually. + * + */ + public static HasMultipleOutgoingTrainsition.Matcher create() { + return new Matcher(); + } + + private final static int POSITION_V = 0; + + private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(HasMultipleOutgoingTrainsition.Matcher.class); + + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + private Matcher() { + super(querySpecification()); + } + + /** + * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pV the fixed value of pattern parameter v, or null if not bound. + * @return matches represented as a Match object. + * + */ + public Collection getAllMatches(final Synchronization pV) { + return rawStreamAllMatches(new Object[]{pV}).collect(Collectors.toSet()); + } + + /** + * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * @param pV the fixed value of pattern parameter v, or null if not bound. + * @return a stream of matches represented as a Match object. + * + */ + public Stream streamAllMatches(final Synchronization pV) { + return rawStreamAllMatches(new Object[]{pV}); + } + + /** + * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pV the fixed value of pattern parameter v, or null if not bound. + * @return a match represented as a Match object, or null if no match is found. + * + */ + public Optional getOneArbitraryMatch(final Synchronization pV) { + return rawGetOneArbitraryMatch(new Object[]{pV}); + } + + /** + * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, + * under any possible substitution of the unspecified parameters (if any). + * @param pV the fixed value of pattern parameter v, or null if not bound. + * @return true if the input is a valid (partial) match of the pattern. + * + */ + public boolean hasMatch(final Synchronization pV) { + return rawHasMatch(new Object[]{pV}); + } + + /** + * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pV the fixed value of pattern parameter v, or null if not bound. + * @return the number of pattern matches found. + * + */ + public int countMatches(final Synchronization pV) { + return rawCountMatches(new Object[]{pV}); + } + + /** + * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pV the fixed value of pattern parameter v, or null if not bound. + * @param processor the action that will process the selected match. + * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked + * + */ + public boolean forOneArbitraryMatch(final Synchronization pV, final Consumer processor) { + return rawForOneArbitraryMatch(new Object[]{pV}, processor); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pV the fixed value of pattern parameter v, or null if not bound. + * @return the (partial) match object. + * + */ + public HasMultipleOutgoingTrainsition.Match newMatch(final Synchronization pV) { + return HasMultipleOutgoingTrainsition.Match.newMatch(pV); + } + + /** + * Retrieve the set of values that occur in matches for v. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfv(final Object[] parameters) { + return rawStreamAllValues(POSITION_V, parameters).map(Synchronization.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for v. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfv() { + return rawStreamAllValuesOfv(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for v. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfv() { + return rawStreamAllValuesOfv(emptyArray()); + } + + @Override + protected HasMultipleOutgoingTrainsition.Match tupleToMatch(final Tuple t) { + try { + return HasMultipleOutgoingTrainsition.Match.newMatch((Synchronization) t.get(POSITION_V)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected HasMultipleOutgoingTrainsition.Match arrayToMatch(final Object[] match) { + try { + return HasMultipleOutgoingTrainsition.Match.newMatch((Synchronization) match[POSITION_V]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected HasMultipleOutgoingTrainsition.Match arrayToMatchMutable(final Object[] match) { + try { + return HasMultipleOutgoingTrainsition.Match.newMutableMatch((Synchronization) match[POSITION_V]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + /** + * @return the singleton instance of the query specification of this pattern + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static IQuerySpecification querySpecification() { + return HasMultipleOutgoingTrainsition.instance(); + } + } + + private HasMultipleOutgoingTrainsition() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static HasMultipleOutgoingTrainsition instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected HasMultipleOutgoingTrainsition.Matcher instantiate(final ViatraQueryEngine engine) { + return HasMultipleOutgoingTrainsition.Matcher.on(engine); + } + + @Override + public HasMultipleOutgoingTrainsition.Matcher instantiate() { + return HasMultipleOutgoingTrainsition.Matcher.create(); + } + + @Override + public HasMultipleOutgoingTrainsition.Match newEmptyMatch() { + return HasMultipleOutgoingTrainsition.Match.newEmptyMatch(); + } + + @Override + public HasMultipleOutgoingTrainsition.Match newMatch(final Object... parameters) { + return HasMultipleOutgoingTrainsition.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization) parameters[0]); + } + + /** + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created + * not at the class load time of the outer class, + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private final static HasMultipleOutgoingTrainsition INSTANCE = new HasMultipleOutgoingTrainsition(); + + /** + * Statically initializes the query specification after the field {@link #INSTANCE} is assigned. + * This initialization order is required to support indirect recursion. + * + *

The static initializer is defined using a helper field to work around limitations of the code generator. + * + */ + private final static Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private final static HasMultipleOutgoingTrainsition.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_v = new PParameter("v", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Synchronization")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_v); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.hasMultipleOutgoingTrainsition"; + } + + @Override + public List getParameterNames() { + return Arrays.asList("v"); + } + + @Override + public List getParameters() { + return parameters; + } + + @Override + public Set doGetContainedBodies() { + setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); + Set bodies = new LinkedHashSet<>(); + { + PBody body = new PBody(this); + PVariable var_v = body.getOrCreateVariableByName("v"); + PVariable var___0_ = body.getOrCreateVariableByName("_<0>"); + PVariable var_trg1 = body.getOrCreateVariableByName("trg1"); + PVariable var___1_ = body.getOrCreateVariableByName("_<1>"); + PVariable var_trg2 = body.getOrCreateVariableByName("trg2"); + new TypeConstraint(body, Tuples.flatTupleOf(var_v), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Synchronization"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_v, parameter_v) + )); + // find transition(_, v, trg1) + new PositivePatternCall(body, Tuples.flatTupleOf(var___0_, var_v, var_trg1), Transition.instance().getInternalQueryRepresentation()); + // find transition(_, v, trg2) + new PositivePatternCall(body, Tuples.flatTupleOf(var___1_, var_v, var_trg2), Transition.instance().getInternalQueryRepresentation()); + // trg1 != trg2 + new Inequality(body, var_trg1, var_trg2); + bodies.add(body); + } + return bodies; + } + } +} 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 @@ +/** + * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql + */ +package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; + +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.CompositeElement; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.log4j.Logger; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.viatra.query.runtime.api.IPatternMatch; +import org.eclipse.viatra.query.runtime.api.IQuerySpecification; +import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; +import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; +import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; +import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; +import org.eclipse.viatra.query.runtime.emf.types.EStructuralFeatureInstancesKey; +import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; +import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; +import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Inequality; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; +import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; + +/** + * A pattern-specific query specification that can instantiate Matcher in a type-safe way. + * + *

Original source: + *

+ *         pattern hasMultipleRegions(composite: CompositeElement) {
+ *         	CompositeElement.regions(composite,region1);
+ *         	CompositeElement.regions(composite,region2);
+ *         	region1 != region2;
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class HasMultipleRegions extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.hasMultipleRegions pattern, + * to be used in conjunction with {@link Matcher}. + * + *

Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. + * Each instance is a (possibly partial) substitution of pattern parameters, + * usable to represent a match of the pattern in the result of a query, + * or to specify the bound (fixed) input parameters when issuing a query. + * + * @see Matcher + * + */ + public static abstract class Match extends BasePatternMatch { + private CompositeElement fComposite; + + private static List parameterNames = makeImmutableList("composite"); + + private Match(final CompositeElement pComposite) { + this.fComposite = pComposite; + } + + @Override + public Object get(final String parameterName) { + if ("composite".equals(parameterName)) return this.fComposite; + return null; + } + + public CompositeElement getComposite() { + return this.fComposite; + } + + @Override + public boolean set(final String parameterName, final Object newValue) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + if ("composite".equals(parameterName) ) { + this.fComposite = (CompositeElement) newValue; + return true; + } + return false; + } + + public void setComposite(final CompositeElement pComposite) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fComposite = pComposite; + } + + @Override + public String patternName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.hasMultipleRegions"; + } + + @Override + public List parameterNames() { + return HasMultipleRegions.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fComposite}; + } + + @Override + public HasMultipleRegions.Match toImmutable() { + return isMutable() ? newMatch(fComposite) : this; + } + + @Override + public String prettyPrint() { + StringBuilder result = new StringBuilder(); + result.append("\"composite\"=" + prettyPrintValue(fComposite)); + return result.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(fComposite); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) { + return false; + } + if ((obj instanceof HasMultipleRegions.Match)) { + HasMultipleRegions.Match other = (HasMultipleRegions.Match) obj; + return Objects.equals(fComposite, other.fComposite); + } else { + // this should be infrequent + if (!(obj instanceof IPatternMatch)) { + return false; + } + IPatternMatch otherSig = (IPatternMatch) obj; + return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); + } + } + + @Override + public HasMultipleRegions specification() { + return HasMultipleRegions.instance(); + } + + /** + * Returns an empty, mutable match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @return the empty match. + * + */ + public static HasMultipleRegions.Match newEmptyMatch() { + return new Mutable(null); + } + + /** + * Returns a mutable (partial) match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @param pComposite the fixed value of pattern parameter composite, or null if not bound. + * @return the new, mutable (partial) match object. + * + */ + public static HasMultipleRegions.Match newMutableMatch(final CompositeElement pComposite) { + return new Mutable(pComposite); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pComposite the fixed value of pattern parameter composite, or null if not bound. + * @return the (partial) match object. + * + */ + public static HasMultipleRegions.Match newMatch(final CompositeElement pComposite) { + return new Immutable(pComposite); + } + + private static final class Mutable extends HasMultipleRegions.Match { + Mutable(final CompositeElement pComposite) { + super(pComposite); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends HasMultipleRegions.Match { + Immutable(final CompositeElement pComposite) { + super(pComposite); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.hasMultipleRegions pattern, + * providing pattern-specific query methods. + * + *

Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, + * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. + * + *

Matches of the pattern will be represented as {@link Match}. + * + *

Original source: + *

+   * pattern hasMultipleRegions(composite: CompositeElement) {
+   * 	CompositeElement.regions(composite,region1);
+   * 	CompositeElement.regions(composite,region2);
+   * 	region1 != region2;
+   * }
+   * 
+ * + * @see Match + * @see HasMultipleRegions + * + */ + public static class Matcher extends BaseMatcher { + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + public static HasMultipleRegions.Matcher on(final ViatraQueryEngine engine) { + // check if matcher already exists + Matcher matcher = engine.getExistingMatcher(querySpecification()); + if (matcher == null) { + matcher = (Matcher)engine.getMatcher(querySpecification()); + } + return matcher; + } + + /** + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * @return an initialized matcher + * @noreference This method is for internal matcher initialization by the framework, do not call it manually. + * + */ + public static HasMultipleRegions.Matcher create() { + return new Matcher(); + } + + private final static int POSITION_COMPOSITE = 0; + + private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(HasMultipleRegions.Matcher.class); + + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + private Matcher() { + super(querySpecification()); + } + + /** + * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pComposite the fixed value of pattern parameter composite, or null if not bound. + * @return matches represented as a Match object. + * + */ + public Collection getAllMatches(final CompositeElement pComposite) { + return rawStreamAllMatches(new Object[]{pComposite}).collect(Collectors.toSet()); + } + + /** + * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * @param pComposite the fixed value of pattern parameter composite, or null if not bound. + * @return a stream of matches represented as a Match object. + * + */ + public Stream streamAllMatches(final CompositeElement pComposite) { + return rawStreamAllMatches(new Object[]{pComposite}); + } + + /** + * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pComposite the fixed value of pattern parameter composite, or null if not bound. + * @return a match represented as a Match object, or null if no match is found. + * + */ + public Optional getOneArbitraryMatch(final CompositeElement pComposite) { + return rawGetOneArbitraryMatch(new Object[]{pComposite}); + } + + /** + * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, + * under any possible substitution of the unspecified parameters (if any). + * @param pComposite the fixed value of pattern parameter composite, or null if not bound. + * @return true if the input is a valid (partial) match of the pattern. + * + */ + public boolean hasMatch(final CompositeElement pComposite) { + return rawHasMatch(new Object[]{pComposite}); + } + + /** + * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pComposite the fixed value of pattern parameter composite, or null if not bound. + * @return the number of pattern matches found. + * + */ + public int countMatches(final CompositeElement pComposite) { + return rawCountMatches(new Object[]{pComposite}); + } + + /** + * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pComposite the fixed value of pattern parameter composite, or null if not bound. + * @param processor the action that will process the selected match. + * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked + * + */ + public boolean forOneArbitraryMatch(final CompositeElement pComposite, final Consumer processor) { + return rawForOneArbitraryMatch(new Object[]{pComposite}, processor); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pComposite the fixed value of pattern parameter composite, or null if not bound. + * @return the (partial) match object. + * + */ + public HasMultipleRegions.Match newMatch(final CompositeElement pComposite) { + return HasMultipleRegions.Match.newMatch(pComposite); + } + + /** + * Retrieve the set of values that occur in matches for composite. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfcomposite(final Object[] parameters) { + return rawStreamAllValues(POSITION_COMPOSITE, parameters).map(CompositeElement.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for composite. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfcomposite() { + return rawStreamAllValuesOfcomposite(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for composite. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfcomposite() { + return rawStreamAllValuesOfcomposite(emptyArray()); + } + + @Override + protected HasMultipleRegions.Match tupleToMatch(final Tuple t) { + try { + return HasMultipleRegions.Match.newMatch((CompositeElement) t.get(POSITION_COMPOSITE)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected HasMultipleRegions.Match arrayToMatch(final Object[] match) { + try { + return HasMultipleRegions.Match.newMatch((CompositeElement) match[POSITION_COMPOSITE]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected HasMultipleRegions.Match arrayToMatchMutable(final Object[] match) { + try { + return HasMultipleRegions.Match.newMutableMatch((CompositeElement) match[POSITION_COMPOSITE]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + /** + * @return the singleton instance of the query specification of this pattern + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static IQuerySpecification querySpecification() { + return HasMultipleRegions.instance(); + } + } + + private HasMultipleRegions() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static HasMultipleRegions instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected HasMultipleRegions.Matcher instantiate(final ViatraQueryEngine engine) { + return HasMultipleRegions.Matcher.on(engine); + } + + @Override + public HasMultipleRegions.Matcher instantiate() { + return HasMultipleRegions.Matcher.create(); + } + + @Override + public HasMultipleRegions.Match newEmptyMatch() { + return HasMultipleRegions.Match.newEmptyMatch(); + } + + @Override + public HasMultipleRegions.Match newMatch(final Object... parameters) { + return HasMultipleRegions.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.CompositeElement) parameters[0]); + } + + /** + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created + * not at the class load time of the outer class, + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private final static HasMultipleRegions INSTANCE = new HasMultipleRegions(); + + /** + * Statically initializes the query specification after the field {@link #INSTANCE} is assigned. + * This initialization order is required to support indirect recursion. + * + *

The static initializer is defined using a helper field to work around limitations of the code generator. + * + */ + private final static Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private final static HasMultipleRegions.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_composite = new PParameter("composite", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.CompositeElement", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "CompositeElement")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_composite); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.hasMultipleRegions"; + } + + @Override + public List getParameterNames() { + return Arrays.asList("composite"); + } + + @Override + public List getParameters() { + return parameters; + } + + @Override + public Set doGetContainedBodies() { + setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); + Set bodies = new LinkedHashSet<>(); + { + PBody body = new PBody(this); + PVariable var_composite = body.getOrCreateVariableByName("composite"); + PVariable var_region1 = body.getOrCreateVariableByName("region1"); + PVariable var_region2 = body.getOrCreateVariableByName("region2"); + new TypeConstraint(body, Tuples.flatTupleOf(var_composite), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "CompositeElement"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_composite, parameter_composite) + )); + // CompositeElement.regions(composite,region1) + new TypeConstraint(body, Tuples.flatTupleOf(var_composite), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "CompositeElement"))); + PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_composite, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "CompositeElement", "regions"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Region"))); + new Equality(body, var__virtual_0_, var_region1); + // CompositeElement.regions(composite,region2) + new TypeConstraint(body, Tuples.flatTupleOf(var_composite), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "CompositeElement"))); + PVariable var__virtual_1_ = body.getOrCreateVariableByName(".virtual{1}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_composite, var__virtual_1_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "CompositeElement", "regions"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_1_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Region"))); + new Equality(body, var__virtual_1_, var_region2); + // region1 != region2 + new Inequality(body, var_region1, var_region2); + bodies.add(body); + } + return bodies; + } + } +} 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 @@ +/** + * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql + */ +package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; + +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Entry; +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.log4j.Logger; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.viatra.query.runtime.api.IPatternMatch; +import org.eclipse.viatra.query.runtime.api.IQuerySpecification; +import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; +import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; +import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; +import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; +import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; +import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; +import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; +import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; + +/** + * A pattern-specific query specification that can instantiate Matcher in a type-safe way. + * + *

Original source: + *

+ *         {@literal @}Constraint(severity="error", message="error", key = {e})
+ *         pattern incomingToEntry(t : Transition, e : Entry) {
+ *         	find transition(t, _, e);
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class IncomingToEntry extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.incomingToEntry pattern, + * to be used in conjunction with {@link Matcher}. + * + *

Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. + * Each instance is a (possibly partial) substitution of pattern parameters, + * usable to represent a match of the pattern in the result of a query, + * or to specify the bound (fixed) input parameters when issuing a query. + * + * @see Matcher + * + */ + public static abstract class Match extends BasePatternMatch { + private Transition fT; + + private Entry fE; + + private static List parameterNames = makeImmutableList("t", "e"); + + private Match(final Transition pT, final Entry pE) { + this.fT = pT; + this.fE = pE; + } + + @Override + public Object get(final String parameterName) { + if ("t".equals(parameterName)) return this.fT; + if ("e".equals(parameterName)) return this.fE; + return null; + } + + public Transition getT() { + return this.fT; + } + + public Entry getE() { + return this.fE; + } + + @Override + public boolean set(final String parameterName, final Object newValue) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + if ("t".equals(parameterName) ) { + this.fT = (Transition) newValue; + return true; + } + if ("e".equals(parameterName) ) { + this.fE = (Entry) newValue; + return true; + } + return false; + } + + public void setT(final Transition pT) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fT = pT; + } + + public void setE(final Entry pE) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fE = pE; + } + + @Override + public String patternName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.incomingToEntry"; + } + + @Override + public List parameterNames() { + return IncomingToEntry.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fT, fE}; + } + + @Override + public IncomingToEntry.Match toImmutable() { + return isMutable() ? newMatch(fT, fE) : this; + } + + @Override + public String prettyPrint() { + StringBuilder result = new StringBuilder(); + result.append("\"t\"=" + prettyPrintValue(fT) + ", "); + result.append("\"e\"=" + prettyPrintValue(fE)); + return result.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(fT, fE); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) { + return false; + } + if ((obj instanceof IncomingToEntry.Match)) { + IncomingToEntry.Match other = (IncomingToEntry.Match) obj; + return Objects.equals(fT, other.fT) && Objects.equals(fE, other.fE); + } else { + // this should be infrequent + if (!(obj instanceof IPatternMatch)) { + return false; + } + IPatternMatch otherSig = (IPatternMatch) obj; + return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); + } + } + + @Override + public IncomingToEntry specification() { + return IncomingToEntry.instance(); + } + + /** + * Returns an empty, mutable match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @return the empty match. + * + */ + public static IncomingToEntry.Match newEmptyMatch() { + return new Mutable(null, null); + } + + /** + * Returns a mutable (partial) match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @return the new, mutable (partial) match object. + * + */ + public static IncomingToEntry.Match newMutableMatch(final Transition pT, final Entry pE) { + return new Mutable(pT, pE); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @return the (partial) match object. + * + */ + public static IncomingToEntry.Match newMatch(final Transition pT, final Entry pE) { + return new Immutable(pT, pE); + } + + private static final class Mutable extends IncomingToEntry.Match { + Mutable(final Transition pT, final Entry pE) { + super(pT, pE); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends IncomingToEntry.Match { + Immutable(final Transition pT, final Entry pE) { + super(pT, pE); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.incomingToEntry pattern, + * providing pattern-specific query methods. + * + *

Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, + * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. + * + *

Matches of the pattern will be represented as {@link Match}. + * + *

Original source: + *

+   * {@literal @}Constraint(severity="error", message="error", key = {e})
+   * pattern incomingToEntry(t : Transition, e : Entry) {
+   * 	find transition(t, _, e);
+   * }
+   * 
+ * + * @see Match + * @see IncomingToEntry + * + */ + public static class Matcher extends BaseMatcher { + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + public static IncomingToEntry.Matcher on(final ViatraQueryEngine engine) { + // check if matcher already exists + Matcher matcher = engine.getExistingMatcher(querySpecification()); + if (matcher == null) { + matcher = (Matcher)engine.getMatcher(querySpecification()); + } + return matcher; + } + + /** + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * @return an initialized matcher + * @noreference This method is for internal matcher initialization by the framework, do not call it manually. + * + */ + public static IncomingToEntry.Matcher create() { + return new Matcher(); + } + + private final static int POSITION_T = 0; + + private final static int POSITION_E = 1; + + private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(IncomingToEntry.Matcher.class); + + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + private Matcher() { + super(querySpecification()); + } + + /** + * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @return matches represented as a Match object. + * + */ + public Collection getAllMatches(final Transition pT, final Entry pE) { + return rawStreamAllMatches(new Object[]{pT, pE}).collect(Collectors.toSet()); + } + + /** + * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @return a stream of matches represented as a Match object. + * + */ + public Stream streamAllMatches(final Transition pT, final Entry pE) { + return rawStreamAllMatches(new Object[]{pT, pE}); + } + + /** + * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @return a match represented as a Match object, or null if no match is found. + * + */ + public Optional getOneArbitraryMatch(final Transition pT, final Entry pE) { + return rawGetOneArbitraryMatch(new Object[]{pT, pE}); + } + + /** + * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, + * under any possible substitution of the unspecified parameters (if any). + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @return true if the input is a valid (partial) match of the pattern. + * + */ + public boolean hasMatch(final Transition pT, final Entry pE) { + return rawHasMatch(new Object[]{pT, pE}); + } + + /** + * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @return the number of pattern matches found. + * + */ + public int countMatches(final Transition pT, final Entry pE) { + return rawCountMatches(new Object[]{pT, pE}); + } + + /** + * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @param processor the action that will process the selected match. + * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked + * + */ + public boolean forOneArbitraryMatch(final Transition pT, final Entry pE, final Consumer processor) { + return rawForOneArbitraryMatch(new Object[]{pT, pE}, processor); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @return the (partial) match object. + * + */ + public IncomingToEntry.Match newMatch(final Transition pT, final Entry pE) { + return IncomingToEntry.Match.newMatch(pT, pE); + } + + /** + * Retrieve the set of values that occur in matches for t. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOft(final Object[] parameters) { + return rawStreamAllValues(POSITION_T, parameters).map(Transition.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for t. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOft() { + return rawStreamAllValuesOft(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for t. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOft() { + return rawStreamAllValuesOft(emptyArray()); + } + + /** + * Retrieve the set of values that occur in matches for t. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOft(final IncomingToEntry.Match partialMatch) { + return rawStreamAllValuesOft(partialMatch.toArray()); + } + + /** + * Retrieve the set of values that occur in matches for t. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOft(final Entry pE) { + return rawStreamAllValuesOft(new Object[]{null, pE}); + } + + /** + * Retrieve the set of values that occur in matches for t. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOft(final IncomingToEntry.Match partialMatch) { + return rawStreamAllValuesOft(partialMatch.toArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for t. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOft(final Entry pE) { + return rawStreamAllValuesOft(new Object[]{null, pE}).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for e. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfe(final Object[] parameters) { + return rawStreamAllValues(POSITION_E, parameters).map(Entry.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for e. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfe() { + return rawStreamAllValuesOfe(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for e. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfe() { + return rawStreamAllValuesOfe(emptyArray()); + } + + /** + * Retrieve the set of values that occur in matches for e. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfe(final IncomingToEntry.Match partialMatch) { + return rawStreamAllValuesOfe(partialMatch.toArray()); + } + + /** + * Retrieve the set of values that occur in matches for e. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfe(final Transition pT) { + return rawStreamAllValuesOfe(new Object[]{pT, null}); + } + + /** + * Retrieve the set of values that occur in matches for e. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfe(final IncomingToEntry.Match partialMatch) { + return rawStreamAllValuesOfe(partialMatch.toArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for e. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfe(final Transition pT) { + return rawStreamAllValuesOfe(new Object[]{pT, null}).collect(Collectors.toSet()); + } + + @Override + protected IncomingToEntry.Match tupleToMatch(final Tuple t) { + try { + return IncomingToEntry.Match.newMatch((Transition) t.get(POSITION_T), (Entry) t.get(POSITION_E)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected IncomingToEntry.Match arrayToMatch(final Object[] match) { + try { + return IncomingToEntry.Match.newMatch((Transition) match[POSITION_T], (Entry) match[POSITION_E]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected IncomingToEntry.Match arrayToMatchMutable(final Object[] match) { + try { + return IncomingToEntry.Match.newMutableMatch((Transition) match[POSITION_T], (Entry) match[POSITION_E]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + /** + * @return the singleton instance of the query specification of this pattern + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static IQuerySpecification querySpecification() { + return IncomingToEntry.instance(); + } + } + + private IncomingToEntry() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static IncomingToEntry instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected IncomingToEntry.Matcher instantiate(final ViatraQueryEngine engine) { + return IncomingToEntry.Matcher.on(engine); + } + + @Override + public IncomingToEntry.Matcher instantiate() { + return IncomingToEntry.Matcher.create(); + } + + @Override + public IncomingToEntry.Match newEmptyMatch() { + return IncomingToEntry.Match.newEmptyMatch(); + } + + @Override + public IncomingToEntry.Match newMatch(final Object... parameters) { + return IncomingToEntry.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition) parameters[0], (ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Entry) parameters[1]); + } + + /** + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created + * not at the class load time of the outer class, + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private final static IncomingToEntry INSTANCE = new IncomingToEntry(); + + /** + * Statically initializes the query specification after the field {@link #INSTANCE} is assigned. + * This initialization order is required to support indirect recursion. + * + *

The static initializer is defined using a helper field to work around limitations of the code generator. + * + */ + private final static Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private final static IncomingToEntry.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_t = new PParameter("t", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Transition")), PParameterDirection.INOUT); + + private final PParameter parameter_e = new PParameter("e", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Entry", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Entry")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_t, parameter_e); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.incomingToEntry"; + } + + @Override + public List getParameterNames() { + return Arrays.asList("t","e"); + } + + @Override + public List getParameters() { + return parameters; + } + + @Override + public Set doGetContainedBodies() { + setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); + Set bodies = new LinkedHashSet<>(); + { + PBody body = new PBody(this); + PVariable var_t = body.getOrCreateVariableByName("t"); + PVariable var_e = body.getOrCreateVariableByName("e"); + PVariable var___0_ = body.getOrCreateVariableByName("_<0>"); + new TypeConstraint(body, Tuples.flatTupleOf(var_t), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_e), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Entry"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_t, parameter_t), + new ExportedParameter(body, var_e, parameter_e) + )); + // find transition(t, _, e) + new PositivePatternCall(body, Tuples.flatTupleOf(var_t, var___0_, var_e), ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.Transition.instance().getInternalQueryRepresentation()); + bodies.add(body); + } + { + PAnnotation annotation = new PAnnotation("Constraint"); + annotation.addAttribute("severity", "error"); + annotation.addAttribute("message", "error"); + annotation.addAttribute("key", Arrays.asList(new Object[] { + new ParameterReference("e") + })); + addAnnotation(annotation); + } + return bodies; + } + } +} 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 @@ +/** + * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql + */ +package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; + +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Entry; +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.log4j.Logger; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.viatra.query.runtime.api.IPatternMatch; +import org.eclipse.viatra.query.runtime.api.IQuerySpecification; +import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; +import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; +import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; +import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; +import org.eclipse.viatra.query.runtime.emf.types.EStructuralFeatureInstancesKey; +import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; +import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; +import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Inequality; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; +import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; + +/** + * A pattern-specific query specification that can instantiate Matcher in a type-safe way. + * + *

Original source: + *

+ *         {@literal @}Constraint(severity="error", message="error", key = {e})
+ *         pattern multipleTransitionFromEntry(e : Entry, t1 : Transition, t2: Transition) {
+ *         	Entry.outgoingTransitions(e,t1);
+ *         	Entry.outgoingTransitions(e,t2);
+ *         	t1!=t2;
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class MultipleTransitionFromEntry extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.multipleTransitionFromEntry pattern, + * to be used in conjunction with {@link Matcher}. + * + *

Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. + * Each instance is a (possibly partial) substitution of pattern parameters, + * usable to represent a match of the pattern in the result of a query, + * or to specify the bound (fixed) input parameters when issuing a query. + * + * @see Matcher + * + */ + public static abstract class Match extends BasePatternMatch { + private Entry fE; + + private Transition fT1; + + private Transition fT2; + + private static List parameterNames = makeImmutableList("e", "t1", "t2"); + + private Match(final Entry pE, final Transition pT1, final Transition pT2) { + this.fE = pE; + this.fT1 = pT1; + this.fT2 = pT2; + } + + @Override + public Object get(final String parameterName) { + if ("e".equals(parameterName)) return this.fE; + if ("t1".equals(parameterName)) return this.fT1; + if ("t2".equals(parameterName)) return this.fT2; + return null; + } + + public Entry getE() { + return this.fE; + } + + public Transition getT1() { + return this.fT1; + } + + public Transition getT2() { + return this.fT2; + } + + @Override + public boolean set(final String parameterName, final Object newValue) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + if ("e".equals(parameterName) ) { + this.fE = (Entry) newValue; + return true; + } + if ("t1".equals(parameterName) ) { + this.fT1 = (Transition) newValue; + return true; + } + if ("t2".equals(parameterName) ) { + this.fT2 = (Transition) newValue; + return true; + } + return false; + } + + public void setE(final Entry pE) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fE = pE; + } + + public void setT1(final Transition pT1) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fT1 = pT1; + } + + public void setT2(final Transition pT2) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fT2 = pT2; + } + + @Override + public String patternName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.multipleTransitionFromEntry"; + } + + @Override + public List parameterNames() { + return MultipleTransitionFromEntry.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fE, fT1, fT2}; + } + + @Override + public MultipleTransitionFromEntry.Match toImmutable() { + return isMutable() ? newMatch(fE, fT1, fT2) : this; + } + + @Override + public String prettyPrint() { + StringBuilder result = new StringBuilder(); + result.append("\"e\"=" + prettyPrintValue(fE) + ", "); + result.append("\"t1\"=" + prettyPrintValue(fT1) + ", "); + result.append("\"t2\"=" + prettyPrintValue(fT2)); + return result.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(fE, fT1, fT2); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) { + return false; + } + if ((obj instanceof MultipleTransitionFromEntry.Match)) { + MultipleTransitionFromEntry.Match other = (MultipleTransitionFromEntry.Match) obj; + return Objects.equals(fE, other.fE) && Objects.equals(fT1, other.fT1) && Objects.equals(fT2, other.fT2); + } else { + // this should be infrequent + if (!(obj instanceof IPatternMatch)) { + return false; + } + IPatternMatch otherSig = (IPatternMatch) obj; + return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); + } + } + + @Override + public MultipleTransitionFromEntry specification() { + return MultipleTransitionFromEntry.instance(); + } + + /** + * Returns an empty, mutable match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @return the empty match. + * + */ + public static MultipleTransitionFromEntry.Match newEmptyMatch() { + return new Mutable(null, null, null); + } + + /** + * Returns a mutable (partial) match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @param pT1 the fixed value of pattern parameter t1, or null if not bound. + * @param pT2 the fixed value of pattern parameter t2, or null if not bound. + * @return the new, mutable (partial) match object. + * + */ + public static MultipleTransitionFromEntry.Match newMutableMatch(final Entry pE, final Transition pT1, final Transition pT2) { + return new Mutable(pE, pT1, pT2); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @param pT1 the fixed value of pattern parameter t1, or null if not bound. + * @param pT2 the fixed value of pattern parameter t2, or null if not bound. + * @return the (partial) match object. + * + */ + public static MultipleTransitionFromEntry.Match newMatch(final Entry pE, final Transition pT1, final Transition pT2) { + return new Immutable(pE, pT1, pT2); + } + + private static final class Mutable extends MultipleTransitionFromEntry.Match { + Mutable(final Entry pE, final Transition pT1, final Transition pT2) { + super(pE, pT1, pT2); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends MultipleTransitionFromEntry.Match { + Immutable(final Entry pE, final Transition pT1, final Transition pT2) { + super(pE, pT1, pT2); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.multipleTransitionFromEntry pattern, + * providing pattern-specific query methods. + * + *

Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, + * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. + * + *

Matches of the pattern will be represented as {@link Match}. + * + *

Original source: + *

+   * {@literal @}Constraint(severity="error", message="error", key = {e})
+   * pattern multipleTransitionFromEntry(e : Entry, t1 : Transition, t2: Transition) {
+   * 	Entry.outgoingTransitions(e,t1);
+   * 	Entry.outgoingTransitions(e,t2);
+   * 	t1!=t2;
+   * }
+   * 
+ * + * @see Match + * @see MultipleTransitionFromEntry + * + */ + public static class Matcher extends BaseMatcher { + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + public static MultipleTransitionFromEntry.Matcher on(final ViatraQueryEngine engine) { + // check if matcher already exists + Matcher matcher = engine.getExistingMatcher(querySpecification()); + if (matcher == null) { + matcher = (Matcher)engine.getMatcher(querySpecification()); + } + return matcher; + } + + /** + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * @return an initialized matcher + * @noreference This method is for internal matcher initialization by the framework, do not call it manually. + * + */ + public static MultipleTransitionFromEntry.Matcher create() { + return new Matcher(); + } + + private final static int POSITION_E = 0; + + private final static int POSITION_T1 = 1; + + private final static int POSITION_T2 = 2; + + private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(MultipleTransitionFromEntry.Matcher.class); + + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + private Matcher() { + super(querySpecification()); + } + + /** + * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @param pT1 the fixed value of pattern parameter t1, or null if not bound. + * @param pT2 the fixed value of pattern parameter t2, or null if not bound. + * @return matches represented as a Match object. + * + */ + public Collection getAllMatches(final Entry pE, final Transition pT1, final Transition pT2) { + return rawStreamAllMatches(new Object[]{pE, pT1, pT2}).collect(Collectors.toSet()); + } + + /** + * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @param pT1 the fixed value of pattern parameter t1, or null if not bound. + * @param pT2 the fixed value of pattern parameter t2, or null if not bound. + * @return a stream of matches represented as a Match object. + * + */ + public Stream streamAllMatches(final Entry pE, final Transition pT1, final Transition pT2) { + return rawStreamAllMatches(new Object[]{pE, pT1, pT2}); + } + + /** + * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @param pT1 the fixed value of pattern parameter t1, or null if not bound. + * @param pT2 the fixed value of pattern parameter t2, or null if not bound. + * @return a match represented as a Match object, or null if no match is found. + * + */ + public Optional getOneArbitraryMatch(final Entry pE, final Transition pT1, final Transition pT2) { + return rawGetOneArbitraryMatch(new Object[]{pE, pT1, pT2}); + } + + /** + * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, + * under any possible substitution of the unspecified parameters (if any). + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @param pT1 the fixed value of pattern parameter t1, or null if not bound. + * @param pT2 the fixed value of pattern parameter t2, or null if not bound. + * @return true if the input is a valid (partial) match of the pattern. + * + */ + public boolean hasMatch(final Entry pE, final Transition pT1, final Transition pT2) { + return rawHasMatch(new Object[]{pE, pT1, pT2}); + } + + /** + * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @param pT1 the fixed value of pattern parameter t1, or null if not bound. + * @param pT2 the fixed value of pattern parameter t2, or null if not bound. + * @return the number of pattern matches found. + * + */ + public int countMatches(final Entry pE, final Transition pT1, final Transition pT2) { + return rawCountMatches(new Object[]{pE, pT1, pT2}); + } + + /** + * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @param pT1 the fixed value of pattern parameter t1, or null if not bound. + * @param pT2 the fixed value of pattern parameter t2, or null if not bound. + * @param processor the action that will process the selected match. + * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked + * + */ + public boolean forOneArbitraryMatch(final Entry pE, final Transition pT1, final Transition pT2, final Consumer processor) { + return rawForOneArbitraryMatch(new Object[]{pE, pT1, pT2}, processor); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @param pT1 the fixed value of pattern parameter t1, or null if not bound. + * @param pT2 the fixed value of pattern parameter t2, or null if not bound. + * @return the (partial) match object. + * + */ + public MultipleTransitionFromEntry.Match newMatch(final Entry pE, final Transition pT1, final Transition pT2) { + return MultipleTransitionFromEntry.Match.newMatch(pE, pT1, pT2); + } + + /** + * Retrieve the set of values that occur in matches for e. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfe(final Object[] parameters) { + return rawStreamAllValues(POSITION_E, parameters).map(Entry.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for e. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfe() { + return rawStreamAllValuesOfe(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for e. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfe() { + return rawStreamAllValuesOfe(emptyArray()); + } + + /** + * Retrieve the set of values that occur in matches for e. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfe(final MultipleTransitionFromEntry.Match partialMatch) { + return rawStreamAllValuesOfe(partialMatch.toArray()); + } + + /** + * Retrieve the set of values that occur in matches for e. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfe(final Transition pT1, final Transition pT2) { + return rawStreamAllValuesOfe(new Object[]{null, pT1, pT2}); + } + + /** + * Retrieve the set of values that occur in matches for e. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfe(final MultipleTransitionFromEntry.Match partialMatch) { + return rawStreamAllValuesOfe(partialMatch.toArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for e. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfe(final Transition pT1, final Transition pT2) { + return rawStreamAllValuesOfe(new Object[]{null, pT1, pT2}).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for t1. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOft1(final Object[] parameters) { + return rawStreamAllValues(POSITION_T1, parameters).map(Transition.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for t1. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOft1() { + return rawStreamAllValuesOft1(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for t1. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOft1() { + return rawStreamAllValuesOft1(emptyArray()); + } + + /** + * Retrieve the set of values that occur in matches for t1. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOft1(final MultipleTransitionFromEntry.Match partialMatch) { + return rawStreamAllValuesOft1(partialMatch.toArray()); + } + + /** + * Retrieve the set of values that occur in matches for t1. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOft1(final Entry pE, final Transition pT2) { + return rawStreamAllValuesOft1(new Object[]{pE, null, pT2}); + } + + /** + * Retrieve the set of values that occur in matches for t1. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOft1(final MultipleTransitionFromEntry.Match partialMatch) { + return rawStreamAllValuesOft1(partialMatch.toArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for t1. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOft1(final Entry pE, final Transition pT2) { + return rawStreamAllValuesOft1(new Object[]{pE, null, pT2}).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for t2. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOft2(final Object[] parameters) { + return rawStreamAllValues(POSITION_T2, parameters).map(Transition.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for t2. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOft2() { + return rawStreamAllValuesOft2(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for t2. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOft2() { + return rawStreamAllValuesOft2(emptyArray()); + } + + /** + * Retrieve the set of values that occur in matches for t2. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOft2(final MultipleTransitionFromEntry.Match partialMatch) { + return rawStreamAllValuesOft2(partialMatch.toArray()); + } + + /** + * Retrieve the set of values that occur in matches for t2. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOft2(final Entry pE, final Transition pT1) { + return rawStreamAllValuesOft2(new Object[]{pE, pT1, null}); + } + + /** + * Retrieve the set of values that occur in matches for t2. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOft2(final MultipleTransitionFromEntry.Match partialMatch) { + return rawStreamAllValuesOft2(partialMatch.toArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for t2. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOft2(final Entry pE, final Transition pT1) { + return rawStreamAllValuesOft2(new Object[]{pE, pT1, null}).collect(Collectors.toSet()); + } + + @Override + protected MultipleTransitionFromEntry.Match tupleToMatch(final Tuple t) { + try { + return MultipleTransitionFromEntry.Match.newMatch((Entry) t.get(POSITION_E), (Transition) t.get(POSITION_T1), (Transition) t.get(POSITION_T2)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected MultipleTransitionFromEntry.Match arrayToMatch(final Object[] match) { + try { + return MultipleTransitionFromEntry.Match.newMatch((Entry) match[POSITION_E], (Transition) match[POSITION_T1], (Transition) match[POSITION_T2]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected MultipleTransitionFromEntry.Match arrayToMatchMutable(final Object[] match) { + try { + return MultipleTransitionFromEntry.Match.newMutableMatch((Entry) match[POSITION_E], (Transition) match[POSITION_T1], (Transition) match[POSITION_T2]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + /** + * @return the singleton instance of the query specification of this pattern + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static IQuerySpecification querySpecification() { + return MultipleTransitionFromEntry.instance(); + } + } + + private MultipleTransitionFromEntry() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static MultipleTransitionFromEntry instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected MultipleTransitionFromEntry.Matcher instantiate(final ViatraQueryEngine engine) { + return MultipleTransitionFromEntry.Matcher.on(engine); + } + + @Override + public MultipleTransitionFromEntry.Matcher instantiate() { + return MultipleTransitionFromEntry.Matcher.create(); + } + + @Override + public MultipleTransitionFromEntry.Match newEmptyMatch() { + return MultipleTransitionFromEntry.Match.newEmptyMatch(); + } + + @Override + public MultipleTransitionFromEntry.Match newMatch(final Object... parameters) { + 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]); + } + + /** + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created + * not at the class load time of the outer class, + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private final static MultipleTransitionFromEntry INSTANCE = new MultipleTransitionFromEntry(); + + /** + * Statically initializes the query specification after the field {@link #INSTANCE} is assigned. + * This initialization order is required to support indirect recursion. + * + *

The static initializer is defined using a helper field to work around limitations of the code generator. + * + */ + private final static Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private final static MultipleTransitionFromEntry.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_e = new PParameter("e", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Entry", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Entry")), PParameterDirection.INOUT); + + private final PParameter parameter_t1 = new PParameter("t1", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Transition")), PParameterDirection.INOUT); + + private final PParameter parameter_t2 = new PParameter("t2", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Transition")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_e, parameter_t1, parameter_t2); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.multipleTransitionFromEntry"; + } + + @Override + public List getParameterNames() { + return Arrays.asList("e","t1","t2"); + } + + @Override + public List getParameters() { + return parameters; + } + + @Override + public Set doGetContainedBodies() { + setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); + Set bodies = new LinkedHashSet<>(); + { + PBody body = new PBody(this); + PVariable var_e = body.getOrCreateVariableByName("e"); + PVariable var_t1 = body.getOrCreateVariableByName("t1"); + PVariable var_t2 = body.getOrCreateVariableByName("t2"); + new TypeConstraint(body, Tuples.flatTupleOf(var_e), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Entry"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_t1), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_t2), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_e, parameter_e), + new ExportedParameter(body, var_t1, parameter_t1), + new ExportedParameter(body, var_t2, parameter_t2) + )); + // Entry.outgoingTransitions(e,t1) + new TypeConstraint(body, Tuples.flatTupleOf(var_e), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Entry"))); + PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_e, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Vertex", "outgoingTransitions"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); + new Equality(body, var__virtual_0_, var_t1); + // Entry.outgoingTransitions(e,t2) + new TypeConstraint(body, Tuples.flatTupleOf(var_e), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Entry"))); + PVariable var__virtual_1_ = body.getOrCreateVariableByName(".virtual{1}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_e, var__virtual_1_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Vertex", "outgoingTransitions"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_1_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); + new Equality(body, var__virtual_1_, var_t2); + // t1!=t2 + new Inequality(body, var_t1, var_t2); + bodies.add(body); + } + { + PAnnotation annotation = new PAnnotation("Constraint"); + annotation.addAttribute("severity", "error"); + annotation.addAttribute("message", "error"); + annotation.addAttribute("key", Arrays.asList(new Object[] { + new ParameterReference("e") + })); + addAnnotation(annotation); + } + return bodies; + } + } +} 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 @@ +/** + * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql + */ +package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; + +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Region; +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.EntryInRegion; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.log4j.Logger; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.viatra.query.runtime.api.IPatternMatch; +import org.eclipse.viatra.query.runtime.api.IQuerySpecification; +import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; +import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; +import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; +import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; +import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; +import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; +import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.NegativePatternCall; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; +import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; + +/** + * A pattern-specific query specification that can instantiate Matcher in a type-safe way. + * + *

Original source: + *

+ *         {@literal @}Constraint(severity="error", message="error", key = {r1})
+ *         pattern noEntryInRegion(r1 : Region) {
+ *         	neg find entryInRegion(r1, _);
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class NoEntryInRegion extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.noEntryInRegion pattern, + * to be used in conjunction with {@link Matcher}. + * + *

Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. + * Each instance is a (possibly partial) substitution of pattern parameters, + * usable to represent a match of the pattern in the result of a query, + * or to specify the bound (fixed) input parameters when issuing a query. + * + * @see Matcher + * + */ + public static abstract class Match extends BasePatternMatch { + private Region fR1; + + private static List parameterNames = makeImmutableList("r1"); + + private Match(final Region pR1) { + this.fR1 = pR1; + } + + @Override + public Object get(final String parameterName) { + if ("r1".equals(parameterName)) return this.fR1; + return null; + } + + public Region getR1() { + return this.fR1; + } + + @Override + public boolean set(final String parameterName, final Object newValue) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + if ("r1".equals(parameterName) ) { + this.fR1 = (Region) newValue; + return true; + } + return false; + } + + public void setR1(final Region pR1) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fR1 = pR1; + } + + @Override + public String patternName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.noEntryInRegion"; + } + + @Override + public List parameterNames() { + return NoEntryInRegion.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fR1}; + } + + @Override + public NoEntryInRegion.Match toImmutable() { + return isMutable() ? newMatch(fR1) : this; + } + + @Override + public String prettyPrint() { + StringBuilder result = new StringBuilder(); + result.append("\"r1\"=" + prettyPrintValue(fR1)); + return result.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(fR1); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) { + return false; + } + if ((obj instanceof NoEntryInRegion.Match)) { + NoEntryInRegion.Match other = (NoEntryInRegion.Match) obj; + return Objects.equals(fR1, other.fR1); + } else { + // this should be infrequent + if (!(obj instanceof IPatternMatch)) { + return false; + } + IPatternMatch otherSig = (IPatternMatch) obj; + return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); + } + } + + @Override + public NoEntryInRegion specification() { + return NoEntryInRegion.instance(); + } + + /** + * Returns an empty, mutable match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @return the empty match. + * + */ + public static NoEntryInRegion.Match newEmptyMatch() { + return new Mutable(null); + } + + /** + * Returns a mutable (partial) match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @param pR1 the fixed value of pattern parameter r1, or null if not bound. + * @return the new, mutable (partial) match object. + * + */ + public static NoEntryInRegion.Match newMutableMatch(final Region pR1) { + return new Mutable(pR1); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pR1 the fixed value of pattern parameter r1, or null if not bound. + * @return the (partial) match object. + * + */ + public static NoEntryInRegion.Match newMatch(final Region pR1) { + return new Immutable(pR1); + } + + private static final class Mutable extends NoEntryInRegion.Match { + Mutable(final Region pR1) { + super(pR1); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends NoEntryInRegion.Match { + Immutable(final Region pR1) { + super(pR1); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.noEntryInRegion pattern, + * providing pattern-specific query methods. + * + *

Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, + * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. + * + *

Matches of the pattern will be represented as {@link Match}. + * + *

Original source: + *

+   * {@literal @}Constraint(severity="error", message="error", key = {r1})
+   * pattern noEntryInRegion(r1 : Region) {
+   * 	neg find entryInRegion(r1, _);
+   * }
+   * 
+ * + * @see Match + * @see NoEntryInRegion + * + */ + public static class Matcher extends BaseMatcher { + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + public static NoEntryInRegion.Matcher on(final ViatraQueryEngine engine) { + // check if matcher already exists + Matcher matcher = engine.getExistingMatcher(querySpecification()); + if (matcher == null) { + matcher = (Matcher)engine.getMatcher(querySpecification()); + } + return matcher; + } + + /** + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * @return an initialized matcher + * @noreference This method is for internal matcher initialization by the framework, do not call it manually. + * + */ + public static NoEntryInRegion.Matcher create() { + return new Matcher(); + } + + private final static int POSITION_R1 = 0; + + private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(NoEntryInRegion.Matcher.class); + + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + private Matcher() { + super(querySpecification()); + } + + /** + * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pR1 the fixed value of pattern parameter r1, or null if not bound. + * @return matches represented as a Match object. + * + */ + public Collection getAllMatches(final Region pR1) { + return rawStreamAllMatches(new Object[]{pR1}).collect(Collectors.toSet()); + } + + /** + * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * @param pR1 the fixed value of pattern parameter r1, or null if not bound. + * @return a stream of matches represented as a Match object. + * + */ + public Stream streamAllMatches(final Region pR1) { + return rawStreamAllMatches(new Object[]{pR1}); + } + + /** + * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pR1 the fixed value of pattern parameter r1, or null if not bound. + * @return a match represented as a Match object, or null if no match is found. + * + */ + public Optional getOneArbitraryMatch(final Region pR1) { + return rawGetOneArbitraryMatch(new Object[]{pR1}); + } + + /** + * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, + * under any possible substitution of the unspecified parameters (if any). + * @param pR1 the fixed value of pattern parameter r1, or null if not bound. + * @return true if the input is a valid (partial) match of the pattern. + * + */ + public boolean hasMatch(final Region pR1) { + return rawHasMatch(new Object[]{pR1}); + } + + /** + * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pR1 the fixed value of pattern parameter r1, or null if not bound. + * @return the number of pattern matches found. + * + */ + public int countMatches(final Region pR1) { + return rawCountMatches(new Object[]{pR1}); + } + + /** + * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pR1 the fixed value of pattern parameter r1, or null if not bound. + * @param processor the action that will process the selected match. + * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked + * + */ + public boolean forOneArbitraryMatch(final Region pR1, final Consumer processor) { + return rawForOneArbitraryMatch(new Object[]{pR1}, processor); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pR1 the fixed value of pattern parameter r1, or null if not bound. + * @return the (partial) match object. + * + */ + public NoEntryInRegion.Match newMatch(final Region pR1) { + return NoEntryInRegion.Match.newMatch(pR1); + } + + /** + * Retrieve the set of values that occur in matches for r1. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfr1(final Object[] parameters) { + return rawStreamAllValues(POSITION_R1, parameters).map(Region.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for r1. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfr1() { + return rawStreamAllValuesOfr1(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for r1. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfr1() { + return rawStreamAllValuesOfr1(emptyArray()); + } + + @Override + protected NoEntryInRegion.Match tupleToMatch(final Tuple t) { + try { + return NoEntryInRegion.Match.newMatch((Region) t.get(POSITION_R1)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected NoEntryInRegion.Match arrayToMatch(final Object[] match) { + try { + return NoEntryInRegion.Match.newMatch((Region) match[POSITION_R1]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected NoEntryInRegion.Match arrayToMatchMutable(final Object[] match) { + try { + return NoEntryInRegion.Match.newMutableMatch((Region) match[POSITION_R1]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + /** + * @return the singleton instance of the query specification of this pattern + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static IQuerySpecification querySpecification() { + return NoEntryInRegion.instance(); + } + } + + private NoEntryInRegion() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static NoEntryInRegion instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected NoEntryInRegion.Matcher instantiate(final ViatraQueryEngine engine) { + return NoEntryInRegion.Matcher.on(engine); + } + + @Override + public NoEntryInRegion.Matcher instantiate() { + return NoEntryInRegion.Matcher.create(); + } + + @Override + public NoEntryInRegion.Match newEmptyMatch() { + return NoEntryInRegion.Match.newEmptyMatch(); + } + + @Override + public NoEntryInRegion.Match newMatch(final Object... parameters) { + return NoEntryInRegion.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Region) parameters[0]); + } + + /** + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created + * not at the class load time of the outer class, + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private final static NoEntryInRegion INSTANCE = new NoEntryInRegion(); + + /** + * Statically initializes the query specification after the field {@link #INSTANCE} is assigned. + * This initialization order is required to support indirect recursion. + * + *

The static initializer is defined using a helper field to work around limitations of the code generator. + * + */ + private final static Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private final static NoEntryInRegion.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_r1 = new PParameter("r1", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Region", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Region")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_r1); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.noEntryInRegion"; + } + + @Override + public List getParameterNames() { + return Arrays.asList("r1"); + } + + @Override + public List getParameters() { + return parameters; + } + + @Override + public Set doGetContainedBodies() { + setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); + Set bodies = new LinkedHashSet<>(); + { + PBody body = new PBody(this); + PVariable var_r1 = body.getOrCreateVariableByName("r1"); + PVariable var___0_ = body.getOrCreateVariableByName("_<0>"); + new TypeConstraint(body, Tuples.flatTupleOf(var_r1), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Region"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_r1, parameter_r1) + )); + // neg find entryInRegion(r1, _) + new NegativePatternCall(body, Tuples.flatTupleOf(var_r1, var___0_), EntryInRegion.instance().getInternalQueryRepresentation()); + bodies.add(body); + } + { + PAnnotation annotation = new PAnnotation("Constraint"); + annotation.addAttribute("severity", "error"); + annotation.addAttribute("message", "error"); + annotation.addAttribute("key", Arrays.asList(new Object[] { + new ParameterReference("r1") + })); + addAnnotation(annotation); + } + return bodies; + } + } +} 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 @@ +/** + * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql + */ +package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; + +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Entry; +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.Transition; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.log4j.Logger; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.viatra.query.runtime.api.IPatternMatch; +import org.eclipse.viatra.query.runtime.api.IQuerySpecification; +import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; +import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; +import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; +import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; +import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; +import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; +import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.NegativePatternCall; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; +import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; + +/** + * A pattern-specific query specification that can instantiate Matcher in a type-safe way. + * + *

Original source: + *

+ *         {@literal @}Constraint(severity="error", message="error", key = {e})
+ *         pattern noOutgoingTransitionFromEntry(e : Entry) {
+ *         	neg find transition(_, e, _);
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class NoOutgoingTransitionFromEntry extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.noOutgoingTransitionFromEntry pattern, + * to be used in conjunction with {@link Matcher}. + * + *

Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. + * Each instance is a (possibly partial) substitution of pattern parameters, + * usable to represent a match of the pattern in the result of a query, + * or to specify the bound (fixed) input parameters when issuing a query. + * + * @see Matcher + * + */ + public static abstract class Match extends BasePatternMatch { + private Entry fE; + + private static List parameterNames = makeImmutableList("e"); + + private Match(final Entry pE) { + this.fE = pE; + } + + @Override + public Object get(final String parameterName) { + if ("e".equals(parameterName)) return this.fE; + return null; + } + + public Entry getE() { + return this.fE; + } + + @Override + public boolean set(final String parameterName, final Object newValue) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + if ("e".equals(parameterName) ) { + this.fE = (Entry) newValue; + return true; + } + return false; + } + + public void setE(final Entry pE) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fE = pE; + } + + @Override + public String patternName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.noOutgoingTransitionFromEntry"; + } + + @Override + public List parameterNames() { + return NoOutgoingTransitionFromEntry.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fE}; + } + + @Override + public NoOutgoingTransitionFromEntry.Match toImmutable() { + return isMutable() ? newMatch(fE) : this; + } + + @Override + public String prettyPrint() { + StringBuilder result = new StringBuilder(); + result.append("\"e\"=" + prettyPrintValue(fE)); + return result.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(fE); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) { + return false; + } + if ((obj instanceof NoOutgoingTransitionFromEntry.Match)) { + NoOutgoingTransitionFromEntry.Match other = (NoOutgoingTransitionFromEntry.Match) obj; + return Objects.equals(fE, other.fE); + } else { + // this should be infrequent + if (!(obj instanceof IPatternMatch)) { + return false; + } + IPatternMatch otherSig = (IPatternMatch) obj; + return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); + } + } + + @Override + public NoOutgoingTransitionFromEntry specification() { + return NoOutgoingTransitionFromEntry.instance(); + } + + /** + * Returns an empty, mutable match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @return the empty match. + * + */ + public static NoOutgoingTransitionFromEntry.Match newEmptyMatch() { + return new Mutable(null); + } + + /** + * Returns a mutable (partial) match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @return the new, mutable (partial) match object. + * + */ + public static NoOutgoingTransitionFromEntry.Match newMutableMatch(final Entry pE) { + return new Mutable(pE); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @return the (partial) match object. + * + */ + public static NoOutgoingTransitionFromEntry.Match newMatch(final Entry pE) { + return new Immutable(pE); + } + + private static final class Mutable extends NoOutgoingTransitionFromEntry.Match { + Mutable(final Entry pE) { + super(pE); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends NoOutgoingTransitionFromEntry.Match { + Immutable(final Entry pE) { + super(pE); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.noOutgoingTransitionFromEntry pattern, + * providing pattern-specific query methods. + * + *

Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, + * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. + * + *

Matches of the pattern will be represented as {@link Match}. + * + *

Original source: + *

+   * {@literal @}Constraint(severity="error", message="error", key = {e})
+   * pattern noOutgoingTransitionFromEntry(e : Entry) {
+   * 	neg find transition(_, e, _);
+   * }
+   * 
+ * + * @see Match + * @see NoOutgoingTransitionFromEntry + * + */ + public static class Matcher extends BaseMatcher { + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + public static NoOutgoingTransitionFromEntry.Matcher on(final ViatraQueryEngine engine) { + // check if matcher already exists + Matcher matcher = engine.getExistingMatcher(querySpecification()); + if (matcher == null) { + matcher = (Matcher)engine.getMatcher(querySpecification()); + } + return matcher; + } + + /** + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * @return an initialized matcher + * @noreference This method is for internal matcher initialization by the framework, do not call it manually. + * + */ + public static NoOutgoingTransitionFromEntry.Matcher create() { + return new Matcher(); + } + + private final static int POSITION_E = 0; + + private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(NoOutgoingTransitionFromEntry.Matcher.class); + + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + private Matcher() { + super(querySpecification()); + } + + /** + * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @return matches represented as a Match object. + * + */ + public Collection getAllMatches(final Entry pE) { + return rawStreamAllMatches(new Object[]{pE}).collect(Collectors.toSet()); + } + + /** + * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @return a stream of matches represented as a Match object. + * + */ + public Stream streamAllMatches(final Entry pE) { + return rawStreamAllMatches(new Object[]{pE}); + } + + /** + * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @return a match represented as a Match object, or null if no match is found. + * + */ + public Optional getOneArbitraryMatch(final Entry pE) { + return rawGetOneArbitraryMatch(new Object[]{pE}); + } + + /** + * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, + * under any possible substitution of the unspecified parameters (if any). + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @return true if the input is a valid (partial) match of the pattern. + * + */ + public boolean hasMatch(final Entry pE) { + return rawHasMatch(new Object[]{pE}); + } + + /** + * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @return the number of pattern matches found. + * + */ + public int countMatches(final Entry pE) { + return rawCountMatches(new Object[]{pE}); + } + + /** + * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @param processor the action that will process the selected match. + * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked + * + */ + public boolean forOneArbitraryMatch(final Entry pE, final Consumer processor) { + return rawForOneArbitraryMatch(new Object[]{pE}, processor); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @return the (partial) match object. + * + */ + public NoOutgoingTransitionFromEntry.Match newMatch(final Entry pE) { + return NoOutgoingTransitionFromEntry.Match.newMatch(pE); + } + + /** + * Retrieve the set of values that occur in matches for e. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfe(final Object[] parameters) { + return rawStreamAllValues(POSITION_E, parameters).map(Entry.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for e. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfe() { + return rawStreamAllValuesOfe(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for e. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfe() { + return rawStreamAllValuesOfe(emptyArray()); + } + + @Override + protected NoOutgoingTransitionFromEntry.Match tupleToMatch(final Tuple t) { + try { + return NoOutgoingTransitionFromEntry.Match.newMatch((Entry) t.get(POSITION_E)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected NoOutgoingTransitionFromEntry.Match arrayToMatch(final Object[] match) { + try { + return NoOutgoingTransitionFromEntry.Match.newMatch((Entry) match[POSITION_E]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected NoOutgoingTransitionFromEntry.Match arrayToMatchMutable(final Object[] match) { + try { + return NoOutgoingTransitionFromEntry.Match.newMutableMatch((Entry) match[POSITION_E]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + /** + * @return the singleton instance of the query specification of this pattern + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static IQuerySpecification querySpecification() { + return NoOutgoingTransitionFromEntry.instance(); + } + } + + private NoOutgoingTransitionFromEntry() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static NoOutgoingTransitionFromEntry instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected NoOutgoingTransitionFromEntry.Matcher instantiate(final ViatraQueryEngine engine) { + return NoOutgoingTransitionFromEntry.Matcher.on(engine); + } + + @Override + public NoOutgoingTransitionFromEntry.Matcher instantiate() { + return NoOutgoingTransitionFromEntry.Matcher.create(); + } + + @Override + public NoOutgoingTransitionFromEntry.Match newEmptyMatch() { + return NoOutgoingTransitionFromEntry.Match.newEmptyMatch(); + } + + @Override + public NoOutgoingTransitionFromEntry.Match newMatch(final Object... parameters) { + return NoOutgoingTransitionFromEntry.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Entry) parameters[0]); + } + + /** + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created + * not at the class load time of the outer class, + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private final static NoOutgoingTransitionFromEntry INSTANCE = new NoOutgoingTransitionFromEntry(); + + /** + * Statically initializes the query specification after the field {@link #INSTANCE} is assigned. + * This initialization order is required to support indirect recursion. + * + *

The static initializer is defined using a helper field to work around limitations of the code generator. + * + */ + private final static Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private final static NoOutgoingTransitionFromEntry.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_e = new PParameter("e", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Entry", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Entry")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_e); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.noOutgoingTransitionFromEntry"; + } + + @Override + public List getParameterNames() { + return Arrays.asList("e"); + } + + @Override + public List getParameters() { + return parameters; + } + + @Override + public Set doGetContainedBodies() { + setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); + Set bodies = new LinkedHashSet<>(); + { + PBody body = new PBody(this); + PVariable var_e = body.getOrCreateVariableByName("e"); + PVariable var___0_ = body.getOrCreateVariableByName("_<0>"); + PVariable var___1_ = body.getOrCreateVariableByName("_<1>"); + new TypeConstraint(body, Tuples.flatTupleOf(var_e), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Entry"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_e, parameter_e) + )); + // neg find transition(_, e, _) + new NegativePatternCall(body, Tuples.flatTupleOf(var___0_, var_e, var___1_), Transition.instance().getInternalQueryRepresentation()); + bodies.add(body); + } + { + PAnnotation annotation = new PAnnotation("Constraint"); + annotation.addAttribute("severity", "error"); + annotation.addAttribute("message", "error"); + annotation.addAttribute("key", Arrays.asList(new Object[] { + new ParameterReference("e") + })); + addAnnotation(annotation); + } + return bodies; + } + } +} 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 @@ +/** + * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql + */ +package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; + +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Region; +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.StateInRegion; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.log4j.Logger; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.viatra.query.runtime.api.IPatternMatch; +import org.eclipse.viatra.query.runtime.api.IQuerySpecification; +import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; +import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; +import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; +import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; +import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; +import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; +import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.NegativePatternCall; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; +import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; + +/** + * A pattern-specific query specification that can instantiate Matcher in a type-safe way. + * + *

Original source: + *

+ *         /////////
+ *         // State vs Region
+ *         /////////
+ *         
+ *         {@literal @}Constraint(severity="error", message="error", key = {region})
+ *         pattern noStateInRegion(region: Region) {
+ *         	neg find StateInRegion(region,_);
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class NoStateInRegion extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.noStateInRegion pattern, + * to be used in conjunction with {@link Matcher}. + * + *

Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. + * Each instance is a (possibly partial) substitution of pattern parameters, + * usable to represent a match of the pattern in the result of a query, + * or to specify the bound (fixed) input parameters when issuing a query. + * + * @see Matcher + * + */ + public static abstract class Match extends BasePatternMatch { + private Region fRegion; + + private static List parameterNames = makeImmutableList("region"); + + private Match(final Region pRegion) { + this.fRegion = pRegion; + } + + @Override + public Object get(final String parameterName) { + if ("region".equals(parameterName)) return this.fRegion; + return null; + } + + public Region getRegion() { + return this.fRegion; + } + + @Override + public boolean set(final String parameterName, final Object newValue) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + if ("region".equals(parameterName) ) { + this.fRegion = (Region) newValue; + return true; + } + return false; + } + + public void setRegion(final Region pRegion) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fRegion = pRegion; + } + + @Override + public String patternName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.noStateInRegion"; + } + + @Override + public List parameterNames() { + return NoStateInRegion.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fRegion}; + } + + @Override + public NoStateInRegion.Match toImmutable() { + return isMutable() ? newMatch(fRegion) : this; + } + + @Override + public String prettyPrint() { + StringBuilder result = new StringBuilder(); + result.append("\"region\"=" + prettyPrintValue(fRegion)); + return result.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(fRegion); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) { + return false; + } + if ((obj instanceof NoStateInRegion.Match)) { + NoStateInRegion.Match other = (NoStateInRegion.Match) obj; + return Objects.equals(fRegion, other.fRegion); + } else { + // this should be infrequent + if (!(obj instanceof IPatternMatch)) { + return false; + } + IPatternMatch otherSig = (IPatternMatch) obj; + return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); + } + } + + @Override + public NoStateInRegion specification() { + return NoStateInRegion.instance(); + } + + /** + * Returns an empty, mutable match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @return the empty match. + * + */ + public static NoStateInRegion.Match newEmptyMatch() { + return new Mutable(null); + } + + /** + * Returns a mutable (partial) match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @param pRegion the fixed value of pattern parameter region, or null if not bound. + * @return the new, mutable (partial) match object. + * + */ + public static NoStateInRegion.Match newMutableMatch(final Region pRegion) { + return new Mutable(pRegion); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pRegion the fixed value of pattern parameter region, or null if not bound. + * @return the (partial) match object. + * + */ + public static NoStateInRegion.Match newMatch(final Region pRegion) { + return new Immutable(pRegion); + } + + private static final class Mutable extends NoStateInRegion.Match { + Mutable(final Region pRegion) { + super(pRegion); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends NoStateInRegion.Match { + Immutable(final Region pRegion) { + super(pRegion); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.noStateInRegion pattern, + * providing pattern-specific query methods. + * + *

Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, + * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. + * + *

Matches of the pattern will be represented as {@link Match}. + * + *

Original source: + *

+   * /////////
+   * // State vs Region
+   * /////////
+   * 
+   * {@literal @}Constraint(severity="error", message="error", key = {region})
+   * pattern noStateInRegion(region: Region) {
+   * 	neg find StateInRegion(region,_);
+   * }
+   * 
+ * + * @see Match + * @see NoStateInRegion + * + */ + public static class Matcher extends BaseMatcher { + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + public static NoStateInRegion.Matcher on(final ViatraQueryEngine engine) { + // check if matcher already exists + Matcher matcher = engine.getExistingMatcher(querySpecification()); + if (matcher == null) { + matcher = (Matcher)engine.getMatcher(querySpecification()); + } + return matcher; + } + + /** + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * @return an initialized matcher + * @noreference This method is for internal matcher initialization by the framework, do not call it manually. + * + */ + public static NoStateInRegion.Matcher create() { + return new Matcher(); + } + + private final static int POSITION_REGION = 0; + + private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(NoStateInRegion.Matcher.class); + + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + private Matcher() { + super(querySpecification()); + } + + /** + * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pRegion the fixed value of pattern parameter region, or null if not bound. + * @return matches represented as a Match object. + * + */ + public Collection getAllMatches(final Region pRegion) { + return rawStreamAllMatches(new Object[]{pRegion}).collect(Collectors.toSet()); + } + + /** + * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * @param pRegion the fixed value of pattern parameter region, or null if not bound. + * @return a stream of matches represented as a Match object. + * + */ + public Stream streamAllMatches(final Region pRegion) { + return rawStreamAllMatches(new Object[]{pRegion}); + } + + /** + * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pRegion the fixed value of pattern parameter region, or null if not bound. + * @return a match represented as a Match object, or null if no match is found. + * + */ + public Optional getOneArbitraryMatch(final Region pRegion) { + return rawGetOneArbitraryMatch(new Object[]{pRegion}); + } + + /** + * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, + * under any possible substitution of the unspecified parameters (if any). + * @param pRegion the fixed value of pattern parameter region, or null if not bound. + * @return true if the input is a valid (partial) match of the pattern. + * + */ + public boolean hasMatch(final Region pRegion) { + return rawHasMatch(new Object[]{pRegion}); + } + + /** + * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pRegion the fixed value of pattern parameter region, or null if not bound. + * @return the number of pattern matches found. + * + */ + public int countMatches(final Region pRegion) { + return rawCountMatches(new Object[]{pRegion}); + } + + /** + * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pRegion the fixed value of pattern parameter region, or null if not bound. + * @param processor the action that will process the selected match. + * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked + * + */ + public boolean forOneArbitraryMatch(final Region pRegion, final Consumer processor) { + return rawForOneArbitraryMatch(new Object[]{pRegion}, processor); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pRegion the fixed value of pattern parameter region, or null if not bound. + * @return the (partial) match object. + * + */ + public NoStateInRegion.Match newMatch(final Region pRegion) { + return NoStateInRegion.Match.newMatch(pRegion); + } + + /** + * Retrieve the set of values that occur in matches for region. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfregion(final Object[] parameters) { + return rawStreamAllValues(POSITION_REGION, parameters).map(Region.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for region. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfregion() { + return rawStreamAllValuesOfregion(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for region. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfregion() { + return rawStreamAllValuesOfregion(emptyArray()); + } + + @Override + protected NoStateInRegion.Match tupleToMatch(final Tuple t) { + try { + return NoStateInRegion.Match.newMatch((Region) t.get(POSITION_REGION)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected NoStateInRegion.Match arrayToMatch(final Object[] match) { + try { + return NoStateInRegion.Match.newMatch((Region) match[POSITION_REGION]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected NoStateInRegion.Match arrayToMatchMutable(final Object[] match) { + try { + return NoStateInRegion.Match.newMutableMatch((Region) match[POSITION_REGION]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + /** + * @return the singleton instance of the query specification of this pattern + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static IQuerySpecification querySpecification() { + return NoStateInRegion.instance(); + } + } + + private NoStateInRegion() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static NoStateInRegion instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected NoStateInRegion.Matcher instantiate(final ViatraQueryEngine engine) { + return NoStateInRegion.Matcher.on(engine); + } + + @Override + public NoStateInRegion.Matcher instantiate() { + return NoStateInRegion.Matcher.create(); + } + + @Override + public NoStateInRegion.Match newEmptyMatch() { + return NoStateInRegion.Match.newEmptyMatch(); + } + + @Override + public NoStateInRegion.Match newMatch(final Object... parameters) { + return NoStateInRegion.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Region) parameters[0]); + } + + /** + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created + * not at the class load time of the outer class, + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private final static NoStateInRegion INSTANCE = new NoStateInRegion(); + + /** + * Statically initializes the query specification after the field {@link #INSTANCE} is assigned. + * This initialization order is required to support indirect recursion. + * + *

The static initializer is defined using a helper field to work around limitations of the code generator. + * + */ + private final static Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private final static NoStateInRegion.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_region = new PParameter("region", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Region", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Region")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_region); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.noStateInRegion"; + } + + @Override + public List getParameterNames() { + return Arrays.asList("region"); + } + + @Override + public List getParameters() { + return parameters; + } + + @Override + public Set doGetContainedBodies() { + setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); + Set bodies = new LinkedHashSet<>(); + { + PBody body = new PBody(this); + PVariable var_region = body.getOrCreateVariableByName("region"); + PVariable var___0_ = body.getOrCreateVariableByName("_<0>"); + new TypeConstraint(body, Tuples.flatTupleOf(var_region), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Region"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_region, parameter_region) + )); + // neg find StateInRegion(region,_) + new NegativePatternCall(body, Tuples.flatTupleOf(var_region, var___0_), StateInRegion.instance().getInternalQueryRepresentation()); + bodies.add(body); + } + { + PAnnotation annotation = new PAnnotation("Constraint"); + annotation.addAttribute("severity", "error"); + annotation.addAttribute("message", "error"); + annotation.addAttribute("key", Arrays.asList(new Object[] { + new ParameterReference("region") + })); + addAnnotation(annotation); + } + return bodies; + } + } +} 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 @@ +/** + * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql + */ +package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; + +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization; +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.HasMultipleIncomingTrainsition; +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.HasMultipleOutgoingTrainsition; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.log4j.Logger; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.viatra.query.runtime.api.IPatternMatch; +import org.eclipse.viatra.query.runtime.api.IQuerySpecification; +import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; +import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; +import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; +import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; +import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; +import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; +import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.NegativePatternCall; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; +import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; + +/** + * A pattern-specific query specification that can instantiate Matcher in a type-safe way. + * + *

Original source: + *

+ *         {@literal @}Constraint(severity="error", message="error", key = {s})
+ *         pattern notSynchronizingStates(s : Synchronization) {
+ *         	neg find hasMultipleOutgoingTrainsition(s);
+ *         	neg find hasMultipleIncomingTrainsition(s);
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class NotSynchronizingStates extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.notSynchronizingStates pattern, + * to be used in conjunction with {@link Matcher}. + * + *

Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. + * Each instance is a (possibly partial) substitution of pattern parameters, + * usable to represent a match of the pattern in the result of a query, + * or to specify the bound (fixed) input parameters when issuing a query. + * + * @see Matcher + * + */ + public static abstract class Match extends BasePatternMatch { + private Synchronization fS; + + private static List parameterNames = makeImmutableList("s"); + + private Match(final Synchronization pS) { + this.fS = pS; + } + + @Override + public Object get(final String parameterName) { + if ("s".equals(parameterName)) return this.fS; + return null; + } + + public Synchronization getS() { + return this.fS; + } + + @Override + public boolean set(final String parameterName, final Object newValue) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + if ("s".equals(parameterName) ) { + this.fS = (Synchronization) newValue; + return true; + } + return false; + } + + public void setS(final Synchronization pS) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fS = pS; + } + + @Override + public String patternName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.notSynchronizingStates"; + } + + @Override + public List parameterNames() { + return NotSynchronizingStates.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fS}; + } + + @Override + public NotSynchronizingStates.Match toImmutable() { + return isMutable() ? newMatch(fS) : this; + } + + @Override + public String prettyPrint() { + StringBuilder result = new StringBuilder(); + result.append("\"s\"=" + prettyPrintValue(fS)); + return result.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(fS); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) { + return false; + } + if ((obj instanceof NotSynchronizingStates.Match)) { + NotSynchronizingStates.Match other = (NotSynchronizingStates.Match) obj; + return Objects.equals(fS, other.fS); + } else { + // this should be infrequent + if (!(obj instanceof IPatternMatch)) { + return false; + } + IPatternMatch otherSig = (IPatternMatch) obj; + return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); + } + } + + @Override + public NotSynchronizingStates specification() { + return NotSynchronizingStates.instance(); + } + + /** + * Returns an empty, mutable match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @return the empty match. + * + */ + public static NotSynchronizingStates.Match newEmptyMatch() { + return new Mutable(null); + } + + /** + * Returns a mutable (partial) match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @return the new, mutable (partial) match object. + * + */ + public static NotSynchronizingStates.Match newMutableMatch(final Synchronization pS) { + return new Mutable(pS); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @return the (partial) match object. + * + */ + public static NotSynchronizingStates.Match newMatch(final Synchronization pS) { + return new Immutable(pS); + } + + private static final class Mutable extends NotSynchronizingStates.Match { + Mutable(final Synchronization pS) { + super(pS); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends NotSynchronizingStates.Match { + Immutable(final Synchronization pS) { + super(pS); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.notSynchronizingStates pattern, + * providing pattern-specific query methods. + * + *

Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, + * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. + * + *

Matches of the pattern will be represented as {@link Match}. + * + *

Original source: + *

+   * {@literal @}Constraint(severity="error", message="error", key = {s})
+   * pattern notSynchronizingStates(s : Synchronization) {
+   * 	neg find hasMultipleOutgoingTrainsition(s);
+   * 	neg find hasMultipleIncomingTrainsition(s);
+   * }
+   * 
+ * + * @see Match + * @see NotSynchronizingStates + * + */ + public static class Matcher extends BaseMatcher { + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + public static NotSynchronizingStates.Matcher on(final ViatraQueryEngine engine) { + // check if matcher already exists + Matcher matcher = engine.getExistingMatcher(querySpecification()); + if (matcher == null) { + matcher = (Matcher)engine.getMatcher(querySpecification()); + } + return matcher; + } + + /** + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * @return an initialized matcher + * @noreference This method is for internal matcher initialization by the framework, do not call it manually. + * + */ + public static NotSynchronizingStates.Matcher create() { + return new Matcher(); + } + + private final static int POSITION_S = 0; + + private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(NotSynchronizingStates.Matcher.class); + + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + private Matcher() { + super(querySpecification()); + } + + /** + * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @return matches represented as a Match object. + * + */ + public Collection getAllMatches(final Synchronization pS) { + return rawStreamAllMatches(new Object[]{pS}).collect(Collectors.toSet()); + } + + /** + * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @return a stream of matches represented as a Match object. + * + */ + public Stream streamAllMatches(final Synchronization pS) { + return rawStreamAllMatches(new Object[]{pS}); + } + + /** + * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @return a match represented as a Match object, or null if no match is found. + * + */ + public Optional getOneArbitraryMatch(final Synchronization pS) { + return rawGetOneArbitraryMatch(new Object[]{pS}); + } + + /** + * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, + * under any possible substitution of the unspecified parameters (if any). + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @return true if the input is a valid (partial) match of the pattern. + * + */ + public boolean hasMatch(final Synchronization pS) { + return rawHasMatch(new Object[]{pS}); + } + + /** + * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @return the number of pattern matches found. + * + */ + public int countMatches(final Synchronization pS) { + return rawCountMatches(new Object[]{pS}); + } + + /** + * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @param processor the action that will process the selected match. + * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked + * + */ + public boolean forOneArbitraryMatch(final Synchronization pS, final Consumer processor) { + return rawForOneArbitraryMatch(new Object[]{pS}, processor); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @return the (partial) match object. + * + */ + public NotSynchronizingStates.Match newMatch(final Synchronization pS) { + return NotSynchronizingStates.Match.newMatch(pS); + } + + /** + * Retrieve the set of values that occur in matches for s. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfs(final Object[] parameters) { + return rawStreamAllValues(POSITION_S, parameters).map(Synchronization.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for s. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfs() { + return rawStreamAllValuesOfs(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for s. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfs() { + return rawStreamAllValuesOfs(emptyArray()); + } + + @Override + protected NotSynchronizingStates.Match tupleToMatch(final Tuple t) { + try { + return NotSynchronizingStates.Match.newMatch((Synchronization) t.get(POSITION_S)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected NotSynchronizingStates.Match arrayToMatch(final Object[] match) { + try { + return NotSynchronizingStates.Match.newMatch((Synchronization) match[POSITION_S]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected NotSynchronizingStates.Match arrayToMatchMutable(final Object[] match) { + try { + return NotSynchronizingStates.Match.newMutableMatch((Synchronization) match[POSITION_S]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + /** + * @return the singleton instance of the query specification of this pattern + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static IQuerySpecification querySpecification() { + return NotSynchronizingStates.instance(); + } + } + + private NotSynchronizingStates() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static NotSynchronizingStates instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected NotSynchronizingStates.Matcher instantiate(final ViatraQueryEngine engine) { + return NotSynchronizingStates.Matcher.on(engine); + } + + @Override + public NotSynchronizingStates.Matcher instantiate() { + return NotSynchronizingStates.Matcher.create(); + } + + @Override + public NotSynchronizingStates.Match newEmptyMatch() { + return NotSynchronizingStates.Match.newEmptyMatch(); + } + + @Override + public NotSynchronizingStates.Match newMatch(final Object... parameters) { + return NotSynchronizingStates.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization) parameters[0]); + } + + /** + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created + * not at the class load time of the outer class, + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private final static NotSynchronizingStates INSTANCE = new NotSynchronizingStates(); + + /** + * Statically initializes the query specification after the field {@link #INSTANCE} is assigned. + * This initialization order is required to support indirect recursion. + * + *

The static initializer is defined using a helper field to work around limitations of the code generator. + * + */ + private final static Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private final static NotSynchronizingStates.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_s = new PParameter("s", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Synchronization")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_s); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.notSynchronizingStates"; + } + + @Override + public List getParameterNames() { + return Arrays.asList("s"); + } + + @Override + public List getParameters() { + return parameters; + } + + @Override + public Set doGetContainedBodies() { + setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); + Set bodies = new LinkedHashSet<>(); + { + PBody body = new PBody(this); + PVariable var_s = body.getOrCreateVariableByName("s"); + new TypeConstraint(body, Tuples.flatTupleOf(var_s), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Synchronization"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_s, parameter_s) + )); + // neg find hasMultipleOutgoingTrainsition(s) + new NegativePatternCall(body, Tuples.flatTupleOf(var_s), HasMultipleOutgoingTrainsition.instance().getInternalQueryRepresentation()); + // neg find hasMultipleIncomingTrainsition(s) + new NegativePatternCall(body, Tuples.flatTupleOf(var_s), HasMultipleIncomingTrainsition.instance().getInternalQueryRepresentation()); + bodies.add(body); + } + { + PAnnotation annotation = new PAnnotation("Constraint"); + annotation.addAttribute("severity", "error"); + annotation.addAttribute("message", "error"); + annotation.addAttribute("key", Arrays.asList(new Object[] { + new ParameterReference("s") + })); + addAnnotation(annotation); + } + return bodies; + } + } +} 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 @@ +/** + * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql + */ +package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; + +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Exit; +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.log4j.Logger; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.viatra.query.runtime.api.IPatternMatch; +import org.eclipse.viatra.query.runtime.api.IQuerySpecification; +import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; +import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; +import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; +import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; +import org.eclipse.viatra.query.runtime.emf.types.EStructuralFeatureInstancesKey; +import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; +import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; +import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; +import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; + +/** + * A pattern-specific query specification that can instantiate Matcher in a type-safe way. + * + *

Original source: + *

+ *         /////////
+ *         // Exit
+ *         /////////
+ *         
+ *         {@literal @}Constraint(severity="error", message="error", key = {e})
+ *         pattern outgoingFromExit(t : Transition, e : Exit) {
+ *         	Exit.outgoingTransitions(e,t);
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class OutgoingFromExit extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.outgoingFromExit pattern, + * to be used in conjunction with {@link Matcher}. + * + *

Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. + * Each instance is a (possibly partial) substitution of pattern parameters, + * usable to represent a match of the pattern in the result of a query, + * or to specify the bound (fixed) input parameters when issuing a query. + * + * @see Matcher + * + */ + public static abstract class Match extends BasePatternMatch { + private Transition fT; + + private Exit fE; + + private static List parameterNames = makeImmutableList("t", "e"); + + private Match(final Transition pT, final Exit pE) { + this.fT = pT; + this.fE = pE; + } + + @Override + public Object get(final String parameterName) { + if ("t".equals(parameterName)) return this.fT; + if ("e".equals(parameterName)) return this.fE; + return null; + } + + public Transition getT() { + return this.fT; + } + + public Exit getE() { + return this.fE; + } + + @Override + public boolean set(final String parameterName, final Object newValue) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + if ("t".equals(parameterName) ) { + this.fT = (Transition) newValue; + return true; + } + if ("e".equals(parameterName) ) { + this.fE = (Exit) newValue; + return true; + } + return false; + } + + public void setT(final Transition pT) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fT = pT; + } + + public void setE(final Exit pE) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fE = pE; + } + + @Override + public String patternName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.outgoingFromExit"; + } + + @Override + public List parameterNames() { + return OutgoingFromExit.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fT, fE}; + } + + @Override + public OutgoingFromExit.Match toImmutable() { + return isMutable() ? newMatch(fT, fE) : this; + } + + @Override + public String prettyPrint() { + StringBuilder result = new StringBuilder(); + result.append("\"t\"=" + prettyPrintValue(fT) + ", "); + result.append("\"e\"=" + prettyPrintValue(fE)); + return result.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(fT, fE); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) { + return false; + } + if ((obj instanceof OutgoingFromExit.Match)) { + OutgoingFromExit.Match other = (OutgoingFromExit.Match) obj; + return Objects.equals(fT, other.fT) && Objects.equals(fE, other.fE); + } else { + // this should be infrequent + if (!(obj instanceof IPatternMatch)) { + return false; + } + IPatternMatch otherSig = (IPatternMatch) obj; + return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); + } + } + + @Override + public OutgoingFromExit specification() { + return OutgoingFromExit.instance(); + } + + /** + * Returns an empty, mutable match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @return the empty match. + * + */ + public static OutgoingFromExit.Match newEmptyMatch() { + return new Mutable(null, null); + } + + /** + * Returns a mutable (partial) match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @return the new, mutable (partial) match object. + * + */ + public static OutgoingFromExit.Match newMutableMatch(final Transition pT, final Exit pE) { + return new Mutable(pT, pE); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @return the (partial) match object. + * + */ + public static OutgoingFromExit.Match newMatch(final Transition pT, final Exit pE) { + return new Immutable(pT, pE); + } + + private static final class Mutable extends OutgoingFromExit.Match { + Mutable(final Transition pT, final Exit pE) { + super(pT, pE); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends OutgoingFromExit.Match { + Immutable(final Transition pT, final Exit pE) { + super(pT, pE); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.outgoingFromExit pattern, + * providing pattern-specific query methods. + * + *

Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, + * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. + * + *

Matches of the pattern will be represented as {@link Match}. + * + *

Original source: + *

+   * /////////
+   * // Exit
+   * /////////
+   * 
+   * {@literal @}Constraint(severity="error", message="error", key = {e})
+   * pattern outgoingFromExit(t : Transition, e : Exit) {
+   * 	Exit.outgoingTransitions(e,t);
+   * }
+   * 
+ * + * @see Match + * @see OutgoingFromExit + * + */ + public static class Matcher extends BaseMatcher { + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + public static OutgoingFromExit.Matcher on(final ViatraQueryEngine engine) { + // check if matcher already exists + Matcher matcher = engine.getExistingMatcher(querySpecification()); + if (matcher == null) { + matcher = (Matcher)engine.getMatcher(querySpecification()); + } + return matcher; + } + + /** + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * @return an initialized matcher + * @noreference This method is for internal matcher initialization by the framework, do not call it manually. + * + */ + public static OutgoingFromExit.Matcher create() { + return new Matcher(); + } + + private final static int POSITION_T = 0; + + private final static int POSITION_E = 1; + + private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(OutgoingFromExit.Matcher.class); + + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + private Matcher() { + super(querySpecification()); + } + + /** + * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @return matches represented as a Match object. + * + */ + public Collection getAllMatches(final Transition pT, final Exit pE) { + return rawStreamAllMatches(new Object[]{pT, pE}).collect(Collectors.toSet()); + } + + /** + * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @return a stream of matches represented as a Match object. + * + */ + public Stream streamAllMatches(final Transition pT, final Exit pE) { + return rawStreamAllMatches(new Object[]{pT, pE}); + } + + /** + * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @return a match represented as a Match object, or null if no match is found. + * + */ + public Optional getOneArbitraryMatch(final Transition pT, final Exit pE) { + return rawGetOneArbitraryMatch(new Object[]{pT, pE}); + } + + /** + * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, + * under any possible substitution of the unspecified parameters (if any). + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @return true if the input is a valid (partial) match of the pattern. + * + */ + public boolean hasMatch(final Transition pT, final Exit pE) { + return rawHasMatch(new Object[]{pT, pE}); + } + + /** + * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @return the number of pattern matches found. + * + */ + public int countMatches(final Transition pT, final Exit pE) { + return rawCountMatches(new Object[]{pT, pE}); + } + + /** + * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @param processor the action that will process the selected match. + * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked + * + */ + public boolean forOneArbitraryMatch(final Transition pT, final Exit pE, final Consumer processor) { + return rawForOneArbitraryMatch(new Object[]{pT, pE}, processor); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pE the fixed value of pattern parameter e, or null if not bound. + * @return the (partial) match object. + * + */ + public OutgoingFromExit.Match newMatch(final Transition pT, final Exit pE) { + return OutgoingFromExit.Match.newMatch(pT, pE); + } + + /** + * Retrieve the set of values that occur in matches for t. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOft(final Object[] parameters) { + return rawStreamAllValues(POSITION_T, parameters).map(Transition.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for t. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOft() { + return rawStreamAllValuesOft(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for t. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOft() { + return rawStreamAllValuesOft(emptyArray()); + } + + /** + * Retrieve the set of values that occur in matches for t. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOft(final OutgoingFromExit.Match partialMatch) { + return rawStreamAllValuesOft(partialMatch.toArray()); + } + + /** + * Retrieve the set of values that occur in matches for t. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOft(final Exit pE) { + return rawStreamAllValuesOft(new Object[]{null, pE}); + } + + /** + * Retrieve the set of values that occur in matches for t. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOft(final OutgoingFromExit.Match partialMatch) { + return rawStreamAllValuesOft(partialMatch.toArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for t. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOft(final Exit pE) { + return rawStreamAllValuesOft(new Object[]{null, pE}).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for e. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfe(final Object[] parameters) { + return rawStreamAllValues(POSITION_E, parameters).map(Exit.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for e. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfe() { + return rawStreamAllValuesOfe(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for e. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfe() { + return rawStreamAllValuesOfe(emptyArray()); + } + + /** + * Retrieve the set of values that occur in matches for e. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfe(final OutgoingFromExit.Match partialMatch) { + return rawStreamAllValuesOfe(partialMatch.toArray()); + } + + /** + * Retrieve the set of values that occur in matches for e. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfe(final Transition pT) { + return rawStreamAllValuesOfe(new Object[]{pT, null}); + } + + /** + * Retrieve the set of values that occur in matches for e. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfe(final OutgoingFromExit.Match partialMatch) { + return rawStreamAllValuesOfe(partialMatch.toArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for e. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfe(final Transition pT) { + return rawStreamAllValuesOfe(new Object[]{pT, null}).collect(Collectors.toSet()); + } + + @Override + protected OutgoingFromExit.Match tupleToMatch(final Tuple t) { + try { + return OutgoingFromExit.Match.newMatch((Transition) t.get(POSITION_T), (Exit) t.get(POSITION_E)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected OutgoingFromExit.Match arrayToMatch(final Object[] match) { + try { + return OutgoingFromExit.Match.newMatch((Transition) match[POSITION_T], (Exit) match[POSITION_E]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected OutgoingFromExit.Match arrayToMatchMutable(final Object[] match) { + try { + return OutgoingFromExit.Match.newMutableMatch((Transition) match[POSITION_T], (Exit) match[POSITION_E]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + /** + * @return the singleton instance of the query specification of this pattern + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static IQuerySpecification querySpecification() { + return OutgoingFromExit.instance(); + } + } + + private OutgoingFromExit() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static OutgoingFromExit instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected OutgoingFromExit.Matcher instantiate(final ViatraQueryEngine engine) { + return OutgoingFromExit.Matcher.on(engine); + } + + @Override + public OutgoingFromExit.Matcher instantiate() { + return OutgoingFromExit.Matcher.create(); + } + + @Override + public OutgoingFromExit.Match newEmptyMatch() { + return OutgoingFromExit.Match.newEmptyMatch(); + } + + @Override + public OutgoingFromExit.Match newMatch(final Object... parameters) { + return OutgoingFromExit.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition) parameters[0], (ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Exit) parameters[1]); + } + + /** + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created + * not at the class load time of the outer class, + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private final static OutgoingFromExit INSTANCE = new OutgoingFromExit(); + + /** + * Statically initializes the query specification after the field {@link #INSTANCE} is assigned. + * This initialization order is required to support indirect recursion. + * + *

The static initializer is defined using a helper field to work around limitations of the code generator. + * + */ + private final static Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private final static OutgoingFromExit.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_t = new PParameter("t", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Transition")), PParameterDirection.INOUT); + + private final PParameter parameter_e = new PParameter("e", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Exit", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Exit")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_t, parameter_e); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.outgoingFromExit"; + } + + @Override + public List getParameterNames() { + return Arrays.asList("t","e"); + } + + @Override + public List getParameters() { + return parameters; + } + + @Override + public Set doGetContainedBodies() { + setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); + Set bodies = new LinkedHashSet<>(); + { + PBody body = new PBody(this); + PVariable var_t = body.getOrCreateVariableByName("t"); + PVariable var_e = body.getOrCreateVariableByName("e"); + new TypeConstraint(body, Tuples.flatTupleOf(var_t), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_e), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Exit"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_t, parameter_t), + new ExportedParameter(body, var_e, parameter_e) + )); + // Exit.outgoingTransitions(e,t) + new TypeConstraint(body, Tuples.flatTupleOf(var_e), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Exit"))); + PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_e, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Vertex", "outgoingTransitions"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); + new Equality(body, var__virtual_0_, var_t); + bodies.add(body); + } + { + PAnnotation annotation = new PAnnotation("Constraint"); + annotation.addAttribute("severity", "error"); + annotation.addAttribute("message", "error"); + annotation.addAttribute("key", Arrays.asList(new Object[] { + new ParameterReference("e") + })); + addAnnotation(annotation); + } + return bodies; + } + } +} 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 @@ +/** + * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql + */ +package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; + +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.FinalState; +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.log4j.Logger; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.viatra.query.runtime.api.IPatternMatch; +import org.eclipse.viatra.query.runtime.api.IQuerySpecification; +import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; +import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; +import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; +import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; +import org.eclipse.viatra.query.runtime.emf.types.EStructuralFeatureInstancesKey; +import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; +import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; +import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; +import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; + +/** + * A pattern-specific query specification that can instantiate Matcher in a type-safe way. + * + *

Original source: + *

+ *         /////////
+ *         // Final
+ *         /////////
+ *         
+ *         {@literal @}Constraint(severity="error", message="error", key = {f})
+ *         pattern outgoingFromFinal(t : Transition, f : FinalState) {
+ *         	FinalState.outgoingTransitions(f,t);
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class OutgoingFromFinal extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.outgoingFromFinal pattern, + * to be used in conjunction with {@link Matcher}. + * + *

Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. + * Each instance is a (possibly partial) substitution of pattern parameters, + * usable to represent a match of the pattern in the result of a query, + * or to specify the bound (fixed) input parameters when issuing a query. + * + * @see Matcher + * + */ + public static abstract class Match extends BasePatternMatch { + private Transition fT; + + private FinalState fF; + + private static List parameterNames = makeImmutableList("t", "f"); + + private Match(final Transition pT, final FinalState pF) { + this.fT = pT; + this.fF = pF; + } + + @Override + public Object get(final String parameterName) { + if ("t".equals(parameterName)) return this.fT; + if ("f".equals(parameterName)) return this.fF; + return null; + } + + public Transition getT() { + return this.fT; + } + + public FinalState getF() { + return this.fF; + } + + @Override + public boolean set(final String parameterName, final Object newValue) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + if ("t".equals(parameterName) ) { + this.fT = (Transition) newValue; + return true; + } + if ("f".equals(parameterName) ) { + this.fF = (FinalState) newValue; + return true; + } + return false; + } + + public void setT(final Transition pT) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fT = pT; + } + + public void setF(final FinalState pF) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fF = pF; + } + + @Override + public String patternName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.outgoingFromFinal"; + } + + @Override + public List parameterNames() { + return OutgoingFromFinal.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fT, fF}; + } + + @Override + public OutgoingFromFinal.Match toImmutable() { + return isMutable() ? newMatch(fT, fF) : this; + } + + @Override + public String prettyPrint() { + StringBuilder result = new StringBuilder(); + result.append("\"t\"=" + prettyPrintValue(fT) + ", "); + result.append("\"f\"=" + prettyPrintValue(fF)); + return result.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(fT, fF); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) { + return false; + } + if ((obj instanceof OutgoingFromFinal.Match)) { + OutgoingFromFinal.Match other = (OutgoingFromFinal.Match) obj; + return Objects.equals(fT, other.fT) && Objects.equals(fF, other.fF); + } else { + // this should be infrequent + if (!(obj instanceof IPatternMatch)) { + return false; + } + IPatternMatch otherSig = (IPatternMatch) obj; + return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); + } + } + + @Override + public OutgoingFromFinal specification() { + return OutgoingFromFinal.instance(); + } + + /** + * Returns an empty, mutable match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @return the empty match. + * + */ + public static OutgoingFromFinal.Match newEmptyMatch() { + return new Mutable(null, null); + } + + /** + * Returns a mutable (partial) match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pF the fixed value of pattern parameter f, or null if not bound. + * @return the new, mutable (partial) match object. + * + */ + public static OutgoingFromFinal.Match newMutableMatch(final Transition pT, final FinalState pF) { + return new Mutable(pT, pF); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pF the fixed value of pattern parameter f, or null if not bound. + * @return the (partial) match object. + * + */ + public static OutgoingFromFinal.Match newMatch(final Transition pT, final FinalState pF) { + return new Immutable(pT, pF); + } + + private static final class Mutable extends OutgoingFromFinal.Match { + Mutable(final Transition pT, final FinalState pF) { + super(pT, pF); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends OutgoingFromFinal.Match { + Immutable(final Transition pT, final FinalState pF) { + super(pT, pF); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.outgoingFromFinal pattern, + * providing pattern-specific query methods. + * + *

Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, + * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. + * + *

Matches of the pattern will be represented as {@link Match}. + * + *

Original source: + *

+   * /////////
+   * // Final
+   * /////////
+   * 
+   * {@literal @}Constraint(severity="error", message="error", key = {f})
+   * pattern outgoingFromFinal(t : Transition, f : FinalState) {
+   * 	FinalState.outgoingTransitions(f,t);
+   * }
+   * 
+ * + * @see Match + * @see OutgoingFromFinal + * + */ + public static class Matcher extends BaseMatcher { + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + public static OutgoingFromFinal.Matcher on(final ViatraQueryEngine engine) { + // check if matcher already exists + Matcher matcher = engine.getExistingMatcher(querySpecification()); + if (matcher == null) { + matcher = (Matcher)engine.getMatcher(querySpecification()); + } + return matcher; + } + + /** + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * @return an initialized matcher + * @noreference This method is for internal matcher initialization by the framework, do not call it manually. + * + */ + public static OutgoingFromFinal.Matcher create() { + return new Matcher(); + } + + private final static int POSITION_T = 0; + + private final static int POSITION_F = 1; + + private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(OutgoingFromFinal.Matcher.class); + + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + private Matcher() { + super(querySpecification()); + } + + /** + * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pF the fixed value of pattern parameter f, or null if not bound. + * @return matches represented as a Match object. + * + */ + public Collection getAllMatches(final Transition pT, final FinalState pF) { + return rawStreamAllMatches(new Object[]{pT, pF}).collect(Collectors.toSet()); + } + + /** + * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pF the fixed value of pattern parameter f, or null if not bound. + * @return a stream of matches represented as a Match object. + * + */ + public Stream streamAllMatches(final Transition pT, final FinalState pF) { + return rawStreamAllMatches(new Object[]{pT, pF}); + } + + /** + * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pF the fixed value of pattern parameter f, or null if not bound. + * @return a match represented as a Match object, or null if no match is found. + * + */ + public Optional getOneArbitraryMatch(final Transition pT, final FinalState pF) { + return rawGetOneArbitraryMatch(new Object[]{pT, pF}); + } + + /** + * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, + * under any possible substitution of the unspecified parameters (if any). + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pF the fixed value of pattern parameter f, or null if not bound. + * @return true if the input is a valid (partial) match of the pattern. + * + */ + public boolean hasMatch(final Transition pT, final FinalState pF) { + return rawHasMatch(new Object[]{pT, pF}); + } + + /** + * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pF the fixed value of pattern parameter f, or null if not bound. + * @return the number of pattern matches found. + * + */ + public int countMatches(final Transition pT, final FinalState pF) { + return rawCountMatches(new Object[]{pT, pF}); + } + + /** + * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pF the fixed value of pattern parameter f, or null if not bound. + * @param processor the action that will process the selected match. + * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked + * + */ + public boolean forOneArbitraryMatch(final Transition pT, final FinalState pF, final Consumer processor) { + return rawForOneArbitraryMatch(new Object[]{pT, pF}, processor); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pF the fixed value of pattern parameter f, or null if not bound. + * @return the (partial) match object. + * + */ + public OutgoingFromFinal.Match newMatch(final Transition pT, final FinalState pF) { + return OutgoingFromFinal.Match.newMatch(pT, pF); + } + + /** + * Retrieve the set of values that occur in matches for t. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOft(final Object[] parameters) { + return rawStreamAllValues(POSITION_T, parameters).map(Transition.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for t. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOft() { + return rawStreamAllValuesOft(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for t. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOft() { + return rawStreamAllValuesOft(emptyArray()); + } + + /** + * Retrieve the set of values that occur in matches for t. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOft(final OutgoingFromFinal.Match partialMatch) { + return rawStreamAllValuesOft(partialMatch.toArray()); + } + + /** + * Retrieve the set of values that occur in matches for t. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOft(final FinalState pF) { + return rawStreamAllValuesOft(new Object[]{null, pF}); + } + + /** + * Retrieve the set of values that occur in matches for t. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOft(final OutgoingFromFinal.Match partialMatch) { + return rawStreamAllValuesOft(partialMatch.toArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for t. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOft(final FinalState pF) { + return rawStreamAllValuesOft(new Object[]{null, pF}).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for f. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOff(final Object[] parameters) { + return rawStreamAllValues(POSITION_F, parameters).map(FinalState.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for f. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOff() { + return rawStreamAllValuesOff(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for f. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOff() { + return rawStreamAllValuesOff(emptyArray()); + } + + /** + * Retrieve the set of values that occur in matches for f. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOff(final OutgoingFromFinal.Match partialMatch) { + return rawStreamAllValuesOff(partialMatch.toArray()); + } + + /** + * Retrieve the set of values that occur in matches for f. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOff(final Transition pT) { + return rawStreamAllValuesOff(new Object[]{pT, null}); + } + + /** + * Retrieve the set of values that occur in matches for f. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOff(final OutgoingFromFinal.Match partialMatch) { + return rawStreamAllValuesOff(partialMatch.toArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for f. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOff(final Transition pT) { + return rawStreamAllValuesOff(new Object[]{pT, null}).collect(Collectors.toSet()); + } + + @Override + protected OutgoingFromFinal.Match tupleToMatch(final Tuple t) { + try { + return OutgoingFromFinal.Match.newMatch((Transition) t.get(POSITION_T), (FinalState) t.get(POSITION_F)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected OutgoingFromFinal.Match arrayToMatch(final Object[] match) { + try { + return OutgoingFromFinal.Match.newMatch((Transition) match[POSITION_T], (FinalState) match[POSITION_F]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected OutgoingFromFinal.Match arrayToMatchMutable(final Object[] match) { + try { + return OutgoingFromFinal.Match.newMutableMatch((Transition) match[POSITION_T], (FinalState) match[POSITION_F]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + /** + * @return the singleton instance of the query specification of this pattern + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static IQuerySpecification querySpecification() { + return OutgoingFromFinal.instance(); + } + } + + private OutgoingFromFinal() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static OutgoingFromFinal instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected OutgoingFromFinal.Matcher instantiate(final ViatraQueryEngine engine) { + return OutgoingFromFinal.Matcher.on(engine); + } + + @Override + public OutgoingFromFinal.Matcher instantiate() { + return OutgoingFromFinal.Matcher.create(); + } + + @Override + public OutgoingFromFinal.Match newEmptyMatch() { + return OutgoingFromFinal.Match.newEmptyMatch(); + } + + @Override + public OutgoingFromFinal.Match newMatch(final Object... parameters) { + return OutgoingFromFinal.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition) parameters[0], (ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.FinalState) parameters[1]); + } + + /** + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created + * not at the class load time of the outer class, + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private final static OutgoingFromFinal INSTANCE = new OutgoingFromFinal(); + + /** + * Statically initializes the query specification after the field {@link #INSTANCE} is assigned. + * This initialization order is required to support indirect recursion. + * + *

The static initializer is defined using a helper field to work around limitations of the code generator. + * + */ + private final static Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private final static OutgoingFromFinal.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_t = new PParameter("t", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Transition")), PParameterDirection.INOUT); + + private final PParameter parameter_f = new PParameter("f", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.FinalState", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "FinalState")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_t, parameter_f); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.outgoingFromFinal"; + } + + @Override + public List getParameterNames() { + return Arrays.asList("t","f"); + } + + @Override + public List getParameters() { + return parameters; + } + + @Override + public Set doGetContainedBodies() { + setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); + Set bodies = new LinkedHashSet<>(); + { + PBody body = new PBody(this); + PVariable var_t = body.getOrCreateVariableByName("t"); + PVariable var_f = body.getOrCreateVariableByName("f"); + new TypeConstraint(body, Tuples.flatTupleOf(var_t), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_f), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "FinalState"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_t, parameter_t), + new ExportedParameter(body, var_f, parameter_f) + )); + // FinalState.outgoingTransitions(f,t) + new TypeConstraint(body, Tuples.flatTupleOf(var_f), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "FinalState"))); + PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_f, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Vertex", "outgoingTransitions"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); + new Equality(body, var__virtual_0_, var_t); + bodies.add(body); + } + { + PAnnotation annotation = new PAnnotation("Constraint"); + annotation.addAttribute("severity", "error"); + annotation.addAttribute("message", "error"); + annotation.addAttribute("key", Arrays.asList(new Object[] { + new ParameterReference("f") + })); + addAnnotation(annotation); + } + return bodies; + } + } +} 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 @@ +/** + * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql + */ +package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; + +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Region; +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.State; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.log4j.Logger; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.viatra.query.runtime.api.IPatternMatch; +import org.eclipse.viatra.query.runtime.api.IQuerySpecification; +import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; +import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; +import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; +import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; +import org.eclipse.viatra.query.runtime.emf.types.EStructuralFeatureInstancesKey; +import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; +import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; +import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; +import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; + +/** + * A pattern-specific query specification that can instantiate Matcher in a type-safe way. + * + *

Original source: + *

+ *         pattern StateInRegion(region: Region, state: State) {
+ *         	Region.vertices(region,state);
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class StateInRegion extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.StateInRegion pattern, + * to be used in conjunction with {@link Matcher}. + * + *

Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. + * Each instance is a (possibly partial) substitution of pattern parameters, + * usable to represent a match of the pattern in the result of a query, + * or to specify the bound (fixed) input parameters when issuing a query. + * + * @see Matcher + * + */ + public static abstract class Match extends BasePatternMatch { + private Region fRegion; + + private State fState; + + private static List parameterNames = makeImmutableList("region", "state"); + + private Match(final Region pRegion, final State pState) { + this.fRegion = pRegion; + this.fState = pState; + } + + @Override + public Object get(final String parameterName) { + if ("region".equals(parameterName)) return this.fRegion; + if ("state".equals(parameterName)) return this.fState; + return null; + } + + public Region getRegion() { + return this.fRegion; + } + + public State getState() { + return this.fState; + } + + @Override + public boolean set(final String parameterName, final Object newValue) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + if ("region".equals(parameterName) ) { + this.fRegion = (Region) newValue; + return true; + } + if ("state".equals(parameterName) ) { + this.fState = (State) newValue; + return true; + } + return false; + } + + public void setRegion(final Region pRegion) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fRegion = pRegion; + } + + public void setState(final State pState) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fState = pState; + } + + @Override + public String patternName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.StateInRegion"; + } + + @Override + public List parameterNames() { + return StateInRegion.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fRegion, fState}; + } + + @Override + public StateInRegion.Match toImmutable() { + return isMutable() ? newMatch(fRegion, fState) : this; + } + + @Override + public String prettyPrint() { + StringBuilder result = new StringBuilder(); + result.append("\"region\"=" + prettyPrintValue(fRegion) + ", "); + result.append("\"state\"=" + prettyPrintValue(fState)); + return result.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(fRegion, fState); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) { + return false; + } + if ((obj instanceof StateInRegion.Match)) { + StateInRegion.Match other = (StateInRegion.Match) obj; + return Objects.equals(fRegion, other.fRegion) && Objects.equals(fState, other.fState); + } else { + // this should be infrequent + if (!(obj instanceof IPatternMatch)) { + return false; + } + IPatternMatch otherSig = (IPatternMatch) obj; + return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); + } + } + + @Override + public StateInRegion specification() { + return StateInRegion.instance(); + } + + /** + * Returns an empty, mutable match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @return the empty match. + * + */ + public static StateInRegion.Match newEmptyMatch() { + return new Mutable(null, null); + } + + /** + * Returns a mutable (partial) match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @param pRegion the fixed value of pattern parameter region, or null if not bound. + * @param pState the fixed value of pattern parameter state, or null if not bound. + * @return the new, mutable (partial) match object. + * + */ + public static StateInRegion.Match newMutableMatch(final Region pRegion, final State pState) { + return new Mutable(pRegion, pState); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pRegion the fixed value of pattern parameter region, or null if not bound. + * @param pState the fixed value of pattern parameter state, or null if not bound. + * @return the (partial) match object. + * + */ + public static StateInRegion.Match newMatch(final Region pRegion, final State pState) { + return new Immutable(pRegion, pState); + } + + private static final class Mutable extends StateInRegion.Match { + Mutable(final Region pRegion, final State pState) { + super(pRegion, pState); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends StateInRegion.Match { + Immutable(final Region pRegion, final State pState) { + super(pRegion, pState); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.StateInRegion pattern, + * providing pattern-specific query methods. + * + *

Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, + * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. + * + *

Matches of the pattern will be represented as {@link Match}. + * + *

Original source: + *

+   * pattern StateInRegion(region: Region, state: State) {
+   * 	Region.vertices(region,state);
+   * }
+   * 
+ * + * @see Match + * @see StateInRegion + * + */ + public static class Matcher extends BaseMatcher { + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + public static StateInRegion.Matcher on(final ViatraQueryEngine engine) { + // check if matcher already exists + Matcher matcher = engine.getExistingMatcher(querySpecification()); + if (matcher == null) { + matcher = (Matcher)engine.getMatcher(querySpecification()); + } + return matcher; + } + + /** + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * @return an initialized matcher + * @noreference This method is for internal matcher initialization by the framework, do not call it manually. + * + */ + public static StateInRegion.Matcher create() { + return new Matcher(); + } + + private final static int POSITION_REGION = 0; + + private final static int POSITION_STATE = 1; + + private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(StateInRegion.Matcher.class); + + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + private Matcher() { + super(querySpecification()); + } + + /** + * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pRegion the fixed value of pattern parameter region, or null if not bound. + * @param pState the fixed value of pattern parameter state, or null if not bound. + * @return matches represented as a Match object. + * + */ + public Collection getAllMatches(final Region pRegion, final State pState) { + return rawStreamAllMatches(new Object[]{pRegion, pState}).collect(Collectors.toSet()); + } + + /** + * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * @param pRegion the fixed value of pattern parameter region, or null if not bound. + * @param pState the fixed value of pattern parameter state, or null if not bound. + * @return a stream of matches represented as a Match object. + * + */ + public Stream streamAllMatches(final Region pRegion, final State pState) { + return rawStreamAllMatches(new Object[]{pRegion, pState}); + } + + /** + * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pRegion the fixed value of pattern parameter region, or null if not bound. + * @param pState the fixed value of pattern parameter state, or null if not bound. + * @return a match represented as a Match object, or null if no match is found. + * + */ + public Optional getOneArbitraryMatch(final Region pRegion, final State pState) { + return rawGetOneArbitraryMatch(new Object[]{pRegion, pState}); + } + + /** + * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, + * under any possible substitution of the unspecified parameters (if any). + * @param pRegion the fixed value of pattern parameter region, or null if not bound. + * @param pState the fixed value of pattern parameter state, or null if not bound. + * @return true if the input is a valid (partial) match of the pattern. + * + */ + public boolean hasMatch(final Region pRegion, final State pState) { + return rawHasMatch(new Object[]{pRegion, pState}); + } + + /** + * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pRegion the fixed value of pattern parameter region, or null if not bound. + * @param pState the fixed value of pattern parameter state, or null if not bound. + * @return the number of pattern matches found. + * + */ + public int countMatches(final Region pRegion, final State pState) { + return rawCountMatches(new Object[]{pRegion, pState}); + } + + /** + * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pRegion the fixed value of pattern parameter region, or null if not bound. + * @param pState the fixed value of pattern parameter state, or null if not bound. + * @param processor the action that will process the selected match. + * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked + * + */ + public boolean forOneArbitraryMatch(final Region pRegion, final State pState, final Consumer processor) { + return rawForOneArbitraryMatch(new Object[]{pRegion, pState}, processor); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pRegion the fixed value of pattern parameter region, or null if not bound. + * @param pState the fixed value of pattern parameter state, or null if not bound. + * @return the (partial) match object. + * + */ + public StateInRegion.Match newMatch(final Region pRegion, final State pState) { + return StateInRegion.Match.newMatch(pRegion, pState); + } + + /** + * Retrieve the set of values that occur in matches for region. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfregion(final Object[] parameters) { + return rawStreamAllValues(POSITION_REGION, parameters).map(Region.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for region. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfregion() { + return rawStreamAllValuesOfregion(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for region. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfregion() { + return rawStreamAllValuesOfregion(emptyArray()); + } + + /** + * Retrieve the set of values that occur in matches for region. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfregion(final StateInRegion.Match partialMatch) { + return rawStreamAllValuesOfregion(partialMatch.toArray()); + } + + /** + * Retrieve the set of values that occur in matches for region. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfregion(final State pState) { + return rawStreamAllValuesOfregion(new Object[]{null, pState}); + } + + /** + * Retrieve the set of values that occur in matches for region. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfregion(final StateInRegion.Match partialMatch) { + return rawStreamAllValuesOfregion(partialMatch.toArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for region. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfregion(final State pState) { + return rawStreamAllValuesOfregion(new Object[]{null, pState}).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for state. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfstate(final Object[] parameters) { + return rawStreamAllValues(POSITION_STATE, parameters).map(State.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for state. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfstate() { + return rawStreamAllValuesOfstate(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for state. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfstate() { + return rawStreamAllValuesOfstate(emptyArray()); + } + + /** + * Retrieve the set of values that occur in matches for state. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfstate(final StateInRegion.Match partialMatch) { + return rawStreamAllValuesOfstate(partialMatch.toArray()); + } + + /** + * Retrieve the set of values that occur in matches for state. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfstate(final Region pRegion) { + return rawStreamAllValuesOfstate(new Object[]{pRegion, null}); + } + + /** + * Retrieve the set of values that occur in matches for state. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfstate(final StateInRegion.Match partialMatch) { + return rawStreamAllValuesOfstate(partialMatch.toArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for state. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfstate(final Region pRegion) { + return rawStreamAllValuesOfstate(new Object[]{pRegion, null}).collect(Collectors.toSet()); + } + + @Override + protected StateInRegion.Match tupleToMatch(final Tuple t) { + try { + return StateInRegion.Match.newMatch((Region) t.get(POSITION_REGION), (State) t.get(POSITION_STATE)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected StateInRegion.Match arrayToMatch(final Object[] match) { + try { + return StateInRegion.Match.newMatch((Region) match[POSITION_REGION], (State) match[POSITION_STATE]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected StateInRegion.Match arrayToMatchMutable(final Object[] match) { + try { + return StateInRegion.Match.newMutableMatch((Region) match[POSITION_REGION], (State) match[POSITION_STATE]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + /** + * @return the singleton instance of the query specification of this pattern + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static IQuerySpecification querySpecification() { + return StateInRegion.instance(); + } + } + + private StateInRegion() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static StateInRegion instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected StateInRegion.Matcher instantiate(final ViatraQueryEngine engine) { + return StateInRegion.Matcher.on(engine); + } + + @Override + public StateInRegion.Matcher instantiate() { + return StateInRegion.Matcher.create(); + } + + @Override + public StateInRegion.Match newEmptyMatch() { + return StateInRegion.Match.newEmptyMatch(); + } + + @Override + public StateInRegion.Match newMatch(final Object... parameters) { + return StateInRegion.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Region) parameters[0], (ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.State) parameters[1]); + } + + /** + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created + * not at the class load time of the outer class, + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private final static StateInRegion INSTANCE = new StateInRegion(); + + /** + * Statically initializes the query specification after the field {@link #INSTANCE} is assigned. + * This initialization order is required to support indirect recursion. + * + *

The static initializer is defined using a helper field to work around limitations of the code generator. + * + */ + private final static Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private final static StateInRegion.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_region = new PParameter("region", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Region", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Region")), PParameterDirection.INOUT); + + private final PParameter parameter_state = new PParameter("state", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.State", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "State")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_region, parameter_state); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.StateInRegion"; + } + + @Override + public List getParameterNames() { + return Arrays.asList("region","state"); + } + + @Override + public List getParameters() { + return parameters; + } + + @Override + public Set doGetContainedBodies() { + setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); + Set bodies = new LinkedHashSet<>(); + { + PBody body = new PBody(this); + PVariable var_region = body.getOrCreateVariableByName("region"); + PVariable var_state = body.getOrCreateVariableByName("state"); + new TypeConstraint(body, Tuples.flatTupleOf(var_region), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Region"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_state), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "State"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_region, parameter_region), + new ExportedParameter(body, var_state, parameter_state) + )); + // Region.vertices(region,state) + new TypeConstraint(body, Tuples.flatTupleOf(var_region), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Region"))); + PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_region, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Region", "vertices"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); + new Equality(body, var__virtual_0_, var_state); + bodies.add(body); + } + return bodies; + } + } +} 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 @@ +/** + * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql + */ +package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; + +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization; +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.Transition; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.log4j.Logger; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.viatra.query.runtime.api.IPatternMatch; +import org.eclipse.viatra.query.runtime.api.IQuerySpecification; +import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; +import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; +import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; +import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; +import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; +import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; +import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.NegativePatternCall; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; +import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; + +/** + * A pattern-specific query specification that can instantiate Matcher in a type-safe way. + * + *

Original source: + *

+ *         {@literal @}Constraint(severity="error", message="error", key = {s})
+ *         pattern synchHasNoIncoming(s : Synchronization) {
+ *         	neg find transition(_, _, s);
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class SynchHasNoIncoming extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.synchHasNoIncoming pattern, + * to be used in conjunction with {@link Matcher}. + * + *

Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. + * Each instance is a (possibly partial) substitution of pattern parameters, + * usable to represent a match of the pattern in the result of a query, + * or to specify the bound (fixed) input parameters when issuing a query. + * + * @see Matcher + * + */ + public static abstract class Match extends BasePatternMatch { + private Synchronization fS; + + private static List parameterNames = makeImmutableList("s"); + + private Match(final Synchronization pS) { + this.fS = pS; + } + + @Override + public Object get(final String parameterName) { + if ("s".equals(parameterName)) return this.fS; + return null; + } + + public Synchronization getS() { + return this.fS; + } + + @Override + public boolean set(final String parameterName, final Object newValue) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + if ("s".equals(parameterName) ) { + this.fS = (Synchronization) newValue; + return true; + } + return false; + } + + public void setS(final Synchronization pS) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fS = pS; + } + + @Override + public String patternName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.synchHasNoIncoming"; + } + + @Override + public List parameterNames() { + return SynchHasNoIncoming.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fS}; + } + + @Override + public SynchHasNoIncoming.Match toImmutable() { + return isMutable() ? newMatch(fS) : this; + } + + @Override + public String prettyPrint() { + StringBuilder result = new StringBuilder(); + result.append("\"s\"=" + prettyPrintValue(fS)); + return result.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(fS); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) { + return false; + } + if ((obj instanceof SynchHasNoIncoming.Match)) { + SynchHasNoIncoming.Match other = (SynchHasNoIncoming.Match) obj; + return Objects.equals(fS, other.fS); + } else { + // this should be infrequent + if (!(obj instanceof IPatternMatch)) { + return false; + } + IPatternMatch otherSig = (IPatternMatch) obj; + return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); + } + } + + @Override + public SynchHasNoIncoming specification() { + return SynchHasNoIncoming.instance(); + } + + /** + * Returns an empty, mutable match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @return the empty match. + * + */ + public static SynchHasNoIncoming.Match newEmptyMatch() { + return new Mutable(null); + } + + /** + * Returns a mutable (partial) match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @return the new, mutable (partial) match object. + * + */ + public static SynchHasNoIncoming.Match newMutableMatch(final Synchronization pS) { + return new Mutable(pS); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @return the (partial) match object. + * + */ + public static SynchHasNoIncoming.Match newMatch(final Synchronization pS) { + return new Immutable(pS); + } + + private static final class Mutable extends SynchHasNoIncoming.Match { + Mutable(final Synchronization pS) { + super(pS); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends SynchHasNoIncoming.Match { + Immutable(final Synchronization pS) { + super(pS); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.synchHasNoIncoming pattern, + * providing pattern-specific query methods. + * + *

Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, + * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. + * + *

Matches of the pattern will be represented as {@link Match}. + * + *

Original source: + *

+   * {@literal @}Constraint(severity="error", message="error", key = {s})
+   * pattern synchHasNoIncoming(s : Synchronization) {
+   * 	neg find transition(_, _, s);
+   * }
+   * 
+ * + * @see Match + * @see SynchHasNoIncoming + * + */ + public static class Matcher extends BaseMatcher { + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + public static SynchHasNoIncoming.Matcher on(final ViatraQueryEngine engine) { + // check if matcher already exists + Matcher matcher = engine.getExistingMatcher(querySpecification()); + if (matcher == null) { + matcher = (Matcher)engine.getMatcher(querySpecification()); + } + return matcher; + } + + /** + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * @return an initialized matcher + * @noreference This method is for internal matcher initialization by the framework, do not call it manually. + * + */ + public static SynchHasNoIncoming.Matcher create() { + return new Matcher(); + } + + private final static int POSITION_S = 0; + + private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(SynchHasNoIncoming.Matcher.class); + + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + private Matcher() { + super(querySpecification()); + } + + /** + * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @return matches represented as a Match object. + * + */ + public Collection getAllMatches(final Synchronization pS) { + return rawStreamAllMatches(new Object[]{pS}).collect(Collectors.toSet()); + } + + /** + * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @return a stream of matches represented as a Match object. + * + */ + public Stream streamAllMatches(final Synchronization pS) { + return rawStreamAllMatches(new Object[]{pS}); + } + + /** + * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @return a match represented as a Match object, or null if no match is found. + * + */ + public Optional getOneArbitraryMatch(final Synchronization pS) { + return rawGetOneArbitraryMatch(new Object[]{pS}); + } + + /** + * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, + * under any possible substitution of the unspecified parameters (if any). + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @return true if the input is a valid (partial) match of the pattern. + * + */ + public boolean hasMatch(final Synchronization pS) { + return rawHasMatch(new Object[]{pS}); + } + + /** + * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @return the number of pattern matches found. + * + */ + public int countMatches(final Synchronization pS) { + return rawCountMatches(new Object[]{pS}); + } + + /** + * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @param processor the action that will process the selected match. + * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked + * + */ + public boolean forOneArbitraryMatch(final Synchronization pS, final Consumer processor) { + return rawForOneArbitraryMatch(new Object[]{pS}, processor); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @return the (partial) match object. + * + */ + public SynchHasNoIncoming.Match newMatch(final Synchronization pS) { + return SynchHasNoIncoming.Match.newMatch(pS); + } + + /** + * Retrieve the set of values that occur in matches for s. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfs(final Object[] parameters) { + return rawStreamAllValues(POSITION_S, parameters).map(Synchronization.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for s. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfs() { + return rawStreamAllValuesOfs(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for s. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfs() { + return rawStreamAllValuesOfs(emptyArray()); + } + + @Override + protected SynchHasNoIncoming.Match tupleToMatch(final Tuple t) { + try { + return SynchHasNoIncoming.Match.newMatch((Synchronization) t.get(POSITION_S)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected SynchHasNoIncoming.Match arrayToMatch(final Object[] match) { + try { + return SynchHasNoIncoming.Match.newMatch((Synchronization) match[POSITION_S]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected SynchHasNoIncoming.Match arrayToMatchMutable(final Object[] match) { + try { + return SynchHasNoIncoming.Match.newMutableMatch((Synchronization) match[POSITION_S]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + /** + * @return the singleton instance of the query specification of this pattern + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static IQuerySpecification querySpecification() { + return SynchHasNoIncoming.instance(); + } + } + + private SynchHasNoIncoming() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static SynchHasNoIncoming instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected SynchHasNoIncoming.Matcher instantiate(final ViatraQueryEngine engine) { + return SynchHasNoIncoming.Matcher.on(engine); + } + + @Override + public SynchHasNoIncoming.Matcher instantiate() { + return SynchHasNoIncoming.Matcher.create(); + } + + @Override + public SynchHasNoIncoming.Match newEmptyMatch() { + return SynchHasNoIncoming.Match.newEmptyMatch(); + } + + @Override + public SynchHasNoIncoming.Match newMatch(final Object... parameters) { + return SynchHasNoIncoming.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization) parameters[0]); + } + + /** + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created + * not at the class load time of the outer class, + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private final static SynchHasNoIncoming INSTANCE = new SynchHasNoIncoming(); + + /** + * Statically initializes the query specification after the field {@link #INSTANCE} is assigned. + * This initialization order is required to support indirect recursion. + * + *

The static initializer is defined using a helper field to work around limitations of the code generator. + * + */ + private final static Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private final static SynchHasNoIncoming.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_s = new PParameter("s", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Synchronization")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_s); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.synchHasNoIncoming"; + } + + @Override + public List getParameterNames() { + return Arrays.asList("s"); + } + + @Override + public List getParameters() { + return parameters; + } + + @Override + public Set doGetContainedBodies() { + setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); + Set bodies = new LinkedHashSet<>(); + { + PBody body = new PBody(this); + PVariable var_s = body.getOrCreateVariableByName("s"); + PVariable var___0_ = body.getOrCreateVariableByName("_<0>"); + PVariable var___1_ = body.getOrCreateVariableByName("_<1>"); + new TypeConstraint(body, Tuples.flatTupleOf(var_s), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Synchronization"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_s, parameter_s) + )); + // neg find transition(_, _, s) + new NegativePatternCall(body, Tuples.flatTupleOf(var___0_, var___1_, var_s), Transition.instance().getInternalQueryRepresentation()); + bodies.add(body); + } + { + PAnnotation annotation = new PAnnotation("Constraint"); + annotation.addAttribute("severity", "error"); + annotation.addAttribute("message", "error"); + annotation.addAttribute("key", Arrays.asList(new Object[] { + new ParameterReference("s") + })); + addAnnotation(annotation); + } + return bodies; + } + } +} 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 @@ +/** + * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql + */ +package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; + +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization; +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.Transition; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.log4j.Logger; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.viatra.query.runtime.api.IPatternMatch; +import org.eclipse.viatra.query.runtime.api.IQuerySpecification; +import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; +import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; +import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; +import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; +import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; +import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; +import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.NegativePatternCall; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; +import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; + +/** + * A pattern-specific query specification that can instantiate Matcher in a type-safe way. + * + *

Original source: + *

+ *         /////////
+ *         // Synchronization
+ *         /////////
+ *         
+ *         {@literal @}Constraint(severity="error", message="error", key = {s})
+ *         pattern synchHasNoOutgoing(s : Synchronization) {
+ *         	neg find transition(_, s, _);
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class SynchHasNoOutgoing extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.synchHasNoOutgoing pattern, + * to be used in conjunction with {@link Matcher}. + * + *

Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. + * Each instance is a (possibly partial) substitution of pattern parameters, + * usable to represent a match of the pattern in the result of a query, + * or to specify the bound (fixed) input parameters when issuing a query. + * + * @see Matcher + * + */ + public static abstract class Match extends BasePatternMatch { + private Synchronization fS; + + private static List parameterNames = makeImmutableList("s"); + + private Match(final Synchronization pS) { + this.fS = pS; + } + + @Override + public Object get(final String parameterName) { + if ("s".equals(parameterName)) return this.fS; + return null; + } + + public Synchronization getS() { + return this.fS; + } + + @Override + public boolean set(final String parameterName, final Object newValue) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + if ("s".equals(parameterName) ) { + this.fS = (Synchronization) newValue; + return true; + } + return false; + } + + public void setS(final Synchronization pS) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fS = pS; + } + + @Override + public String patternName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.synchHasNoOutgoing"; + } + + @Override + public List parameterNames() { + return SynchHasNoOutgoing.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fS}; + } + + @Override + public SynchHasNoOutgoing.Match toImmutable() { + return isMutable() ? newMatch(fS) : this; + } + + @Override + public String prettyPrint() { + StringBuilder result = new StringBuilder(); + result.append("\"s\"=" + prettyPrintValue(fS)); + return result.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(fS); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) { + return false; + } + if ((obj instanceof SynchHasNoOutgoing.Match)) { + SynchHasNoOutgoing.Match other = (SynchHasNoOutgoing.Match) obj; + return Objects.equals(fS, other.fS); + } else { + // this should be infrequent + if (!(obj instanceof IPatternMatch)) { + return false; + } + IPatternMatch otherSig = (IPatternMatch) obj; + return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); + } + } + + @Override + public SynchHasNoOutgoing specification() { + return SynchHasNoOutgoing.instance(); + } + + /** + * Returns an empty, mutable match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @return the empty match. + * + */ + public static SynchHasNoOutgoing.Match newEmptyMatch() { + return new Mutable(null); + } + + /** + * Returns a mutable (partial) match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @return the new, mutable (partial) match object. + * + */ + public static SynchHasNoOutgoing.Match newMutableMatch(final Synchronization pS) { + return new Mutable(pS); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @return the (partial) match object. + * + */ + public static SynchHasNoOutgoing.Match newMatch(final Synchronization pS) { + return new Immutable(pS); + } + + private static final class Mutable extends SynchHasNoOutgoing.Match { + Mutable(final Synchronization pS) { + super(pS); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends SynchHasNoOutgoing.Match { + Immutable(final Synchronization pS) { + super(pS); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.synchHasNoOutgoing pattern, + * providing pattern-specific query methods. + * + *

Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, + * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. + * + *

Matches of the pattern will be represented as {@link Match}. + * + *

Original source: + *

+   * /////////
+   * // Synchronization
+   * /////////
+   * 
+   * {@literal @}Constraint(severity="error", message="error", key = {s})
+   * pattern synchHasNoOutgoing(s : Synchronization) {
+   * 	neg find transition(_, s, _);
+   * }
+   * 
+ * + * @see Match + * @see SynchHasNoOutgoing + * + */ + public static class Matcher extends BaseMatcher { + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + public static SynchHasNoOutgoing.Matcher on(final ViatraQueryEngine engine) { + // check if matcher already exists + Matcher matcher = engine.getExistingMatcher(querySpecification()); + if (matcher == null) { + matcher = (Matcher)engine.getMatcher(querySpecification()); + } + return matcher; + } + + /** + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * @return an initialized matcher + * @noreference This method is for internal matcher initialization by the framework, do not call it manually. + * + */ + public static SynchHasNoOutgoing.Matcher create() { + return new Matcher(); + } + + private final static int POSITION_S = 0; + + private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(SynchHasNoOutgoing.Matcher.class); + + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + private Matcher() { + super(querySpecification()); + } + + /** + * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @return matches represented as a Match object. + * + */ + public Collection getAllMatches(final Synchronization pS) { + return rawStreamAllMatches(new Object[]{pS}).collect(Collectors.toSet()); + } + + /** + * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @return a stream of matches represented as a Match object. + * + */ + public Stream streamAllMatches(final Synchronization pS) { + return rawStreamAllMatches(new Object[]{pS}); + } + + /** + * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @return a match represented as a Match object, or null if no match is found. + * + */ + public Optional getOneArbitraryMatch(final Synchronization pS) { + return rawGetOneArbitraryMatch(new Object[]{pS}); + } + + /** + * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, + * under any possible substitution of the unspecified parameters (if any). + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @return true if the input is a valid (partial) match of the pattern. + * + */ + public boolean hasMatch(final Synchronization pS) { + return rawHasMatch(new Object[]{pS}); + } + + /** + * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @return the number of pattern matches found. + * + */ + public int countMatches(final Synchronization pS) { + return rawCountMatches(new Object[]{pS}); + } + + /** + * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @param processor the action that will process the selected match. + * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked + * + */ + public boolean forOneArbitraryMatch(final Synchronization pS, final Consumer processor) { + return rawForOneArbitraryMatch(new Object[]{pS}, processor); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @return the (partial) match object. + * + */ + public SynchHasNoOutgoing.Match newMatch(final Synchronization pS) { + return SynchHasNoOutgoing.Match.newMatch(pS); + } + + /** + * Retrieve the set of values that occur in matches for s. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfs(final Object[] parameters) { + return rawStreamAllValues(POSITION_S, parameters).map(Synchronization.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for s. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfs() { + return rawStreamAllValuesOfs(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for s. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfs() { + return rawStreamAllValuesOfs(emptyArray()); + } + + @Override + protected SynchHasNoOutgoing.Match tupleToMatch(final Tuple t) { + try { + return SynchHasNoOutgoing.Match.newMatch((Synchronization) t.get(POSITION_S)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected SynchHasNoOutgoing.Match arrayToMatch(final Object[] match) { + try { + return SynchHasNoOutgoing.Match.newMatch((Synchronization) match[POSITION_S]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected SynchHasNoOutgoing.Match arrayToMatchMutable(final Object[] match) { + try { + return SynchHasNoOutgoing.Match.newMutableMatch((Synchronization) match[POSITION_S]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + /** + * @return the singleton instance of the query specification of this pattern + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static IQuerySpecification querySpecification() { + return SynchHasNoOutgoing.instance(); + } + } + + private SynchHasNoOutgoing() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static SynchHasNoOutgoing instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected SynchHasNoOutgoing.Matcher instantiate(final ViatraQueryEngine engine) { + return SynchHasNoOutgoing.Matcher.on(engine); + } + + @Override + public SynchHasNoOutgoing.Matcher instantiate() { + return SynchHasNoOutgoing.Matcher.create(); + } + + @Override + public SynchHasNoOutgoing.Match newEmptyMatch() { + return SynchHasNoOutgoing.Match.newEmptyMatch(); + } + + @Override + public SynchHasNoOutgoing.Match newMatch(final Object... parameters) { + return SynchHasNoOutgoing.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization) parameters[0]); + } + + /** + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created + * not at the class load time of the outer class, + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private final static SynchHasNoOutgoing INSTANCE = new SynchHasNoOutgoing(); + + /** + * Statically initializes the query specification after the field {@link #INSTANCE} is assigned. + * This initialization order is required to support indirect recursion. + * + *

The static initializer is defined using a helper field to work around limitations of the code generator. + * + */ + private final static Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private final static SynchHasNoOutgoing.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_s = new PParameter("s", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Synchronization")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_s); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.synchHasNoOutgoing"; + } + + @Override + public List getParameterNames() { + return Arrays.asList("s"); + } + + @Override + public List getParameters() { + return parameters; + } + + @Override + public Set doGetContainedBodies() { + setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); + Set bodies = new LinkedHashSet<>(); + { + PBody body = new PBody(this); + PVariable var_s = body.getOrCreateVariableByName("s"); + PVariable var___0_ = body.getOrCreateVariableByName("_<0>"); + PVariable var___1_ = body.getOrCreateVariableByName("_<1>"); + new TypeConstraint(body, Tuples.flatTupleOf(var_s), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Synchronization"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_s, parameter_s) + )); + // neg find transition(_, s, _) + new NegativePatternCall(body, Tuples.flatTupleOf(var___0_, var_s, var___1_), Transition.instance().getInternalQueryRepresentation()); + bodies.add(body); + } + { + PAnnotation annotation = new PAnnotation("Constraint"); + annotation.addAttribute("severity", "error"); + annotation.addAttribute("message", "error"); + annotation.addAttribute("key", Arrays.asList(new Object[] { + new ParameterReference("s") + })); + addAnnotation(annotation); + } + return bodies; + } + } +} 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 @@ +/** + * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql + */ +package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; + +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.log4j.Logger; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.viatra.query.runtime.api.IPatternMatch; +import org.eclipse.viatra.query.runtime.api.IQuerySpecification; +import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; +import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; +import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; +import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; +import org.eclipse.viatra.query.runtime.emf.types.EStructuralFeatureInstancesKey; +import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; +import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; +import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Inequality; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; +import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; + +/** + * A pattern-specific query specification that can instantiate Matcher in a type-safe way. + * + *

Original source: + *

+ *         Simplifying model generation
+ *          
+ *         {@literal @}Constraint(severity="error", message="error", key = {s})
+ *         pattern synchThree(s: Synchronization) {
+ *         	Transition.target(t1,s);
+ *         	Transition.target(t2,s);
+ *         	Transition.target(t3,s);
+ *         	t1!=t2;
+ *         	t2!=t3;
+ *         	t1!=t3;
+ *         } or {
+ *         	Transition.source(t1,s);
+ *         	Transition.source(t2,s);
+ *         	Transition.source(t3,s);
+ *         	t1!=t2;
+ *         	t2!=t3;
+ *         	t1!=t3;
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class SynchThree extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.synchThree pattern, + * to be used in conjunction with {@link Matcher}. + * + *

Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. + * Each instance is a (possibly partial) substitution of pattern parameters, + * usable to represent a match of the pattern in the result of a query, + * or to specify the bound (fixed) input parameters when issuing a query. + * + * @see Matcher + * + */ + public static abstract class Match extends BasePatternMatch { + private Synchronization fS; + + private static List parameterNames = makeImmutableList("s"); + + private Match(final Synchronization pS) { + this.fS = pS; + } + + @Override + public Object get(final String parameterName) { + if ("s".equals(parameterName)) return this.fS; + return null; + } + + public Synchronization getS() { + return this.fS; + } + + @Override + public boolean set(final String parameterName, final Object newValue) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + if ("s".equals(parameterName) ) { + this.fS = (Synchronization) newValue; + return true; + } + return false; + } + + public void setS(final Synchronization pS) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fS = pS; + } + + @Override + public String patternName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.synchThree"; + } + + @Override + public List parameterNames() { + return SynchThree.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fS}; + } + + @Override + public SynchThree.Match toImmutable() { + return isMutable() ? newMatch(fS) : this; + } + + @Override + public String prettyPrint() { + StringBuilder result = new StringBuilder(); + result.append("\"s\"=" + prettyPrintValue(fS)); + return result.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(fS); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) { + return false; + } + if ((obj instanceof SynchThree.Match)) { + SynchThree.Match other = (SynchThree.Match) obj; + return Objects.equals(fS, other.fS); + } else { + // this should be infrequent + if (!(obj instanceof IPatternMatch)) { + return false; + } + IPatternMatch otherSig = (IPatternMatch) obj; + return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); + } + } + + @Override + public SynchThree specification() { + return SynchThree.instance(); + } + + /** + * Returns an empty, mutable match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @return the empty match. + * + */ + public static SynchThree.Match newEmptyMatch() { + return new Mutable(null); + } + + /** + * Returns a mutable (partial) match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @return the new, mutable (partial) match object. + * + */ + public static SynchThree.Match newMutableMatch(final Synchronization pS) { + return new Mutable(pS); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @return the (partial) match object. + * + */ + public static SynchThree.Match newMatch(final Synchronization pS) { + return new Immutable(pS); + } + + private static final class Mutable extends SynchThree.Match { + Mutable(final Synchronization pS) { + super(pS); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends SynchThree.Match { + Immutable(final Synchronization pS) { + super(pS); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.synchThree pattern, + * providing pattern-specific query methods. + * + *

Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, + * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. + * + *

Matches of the pattern will be represented as {@link Match}. + * + *

Original source: + *

+   * Simplifying model generation
+   *  
+   * {@literal @}Constraint(severity="error", message="error", key = {s})
+   * pattern synchThree(s: Synchronization) {
+   * 	Transition.target(t1,s);
+   * 	Transition.target(t2,s);
+   * 	Transition.target(t3,s);
+   * 	t1!=t2;
+   * 	t2!=t3;
+   * 	t1!=t3;
+   * } or {
+   * 	Transition.source(t1,s);
+   * 	Transition.source(t2,s);
+   * 	Transition.source(t3,s);
+   * 	t1!=t2;
+   * 	t2!=t3;
+   * 	t1!=t3;
+   * }
+   * 
+ * + * @see Match + * @see SynchThree + * + */ + public static class Matcher extends BaseMatcher { + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + public static SynchThree.Matcher on(final ViatraQueryEngine engine) { + // check if matcher already exists + Matcher matcher = engine.getExistingMatcher(querySpecification()); + if (matcher == null) { + matcher = (Matcher)engine.getMatcher(querySpecification()); + } + return matcher; + } + + /** + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * @return an initialized matcher + * @noreference This method is for internal matcher initialization by the framework, do not call it manually. + * + */ + public static SynchThree.Matcher create() { + return new Matcher(); + } + + private final static int POSITION_S = 0; + + private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(SynchThree.Matcher.class); + + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + private Matcher() { + super(querySpecification()); + } + + /** + * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @return matches represented as a Match object. + * + */ + public Collection getAllMatches(final Synchronization pS) { + return rawStreamAllMatches(new Object[]{pS}).collect(Collectors.toSet()); + } + + /** + * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @return a stream of matches represented as a Match object. + * + */ + public Stream streamAllMatches(final Synchronization pS) { + return rawStreamAllMatches(new Object[]{pS}); + } + + /** + * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @return a match represented as a Match object, or null if no match is found. + * + */ + public Optional getOneArbitraryMatch(final Synchronization pS) { + return rawGetOneArbitraryMatch(new Object[]{pS}); + } + + /** + * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, + * under any possible substitution of the unspecified parameters (if any). + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @return true if the input is a valid (partial) match of the pattern. + * + */ + public boolean hasMatch(final Synchronization pS) { + return rawHasMatch(new Object[]{pS}); + } + + /** + * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @return the number of pattern matches found. + * + */ + public int countMatches(final Synchronization pS) { + return rawCountMatches(new Object[]{pS}); + } + + /** + * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @param processor the action that will process the selected match. + * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked + * + */ + public boolean forOneArbitraryMatch(final Synchronization pS, final Consumer processor) { + return rawForOneArbitraryMatch(new Object[]{pS}, processor); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @return the (partial) match object. + * + */ + public SynchThree.Match newMatch(final Synchronization pS) { + return SynchThree.Match.newMatch(pS); + } + + /** + * Retrieve the set of values that occur in matches for s. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfs(final Object[] parameters) { + return rawStreamAllValues(POSITION_S, parameters).map(Synchronization.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for s. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfs() { + return rawStreamAllValuesOfs(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for s. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfs() { + return rawStreamAllValuesOfs(emptyArray()); + } + + @Override + protected SynchThree.Match tupleToMatch(final Tuple t) { + try { + return SynchThree.Match.newMatch((Synchronization) t.get(POSITION_S)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected SynchThree.Match arrayToMatch(final Object[] match) { + try { + return SynchThree.Match.newMatch((Synchronization) match[POSITION_S]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected SynchThree.Match arrayToMatchMutable(final Object[] match) { + try { + return SynchThree.Match.newMutableMatch((Synchronization) match[POSITION_S]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + /** + * @return the singleton instance of the query specification of this pattern + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static IQuerySpecification querySpecification() { + return SynchThree.instance(); + } + } + + private SynchThree() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static SynchThree instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected SynchThree.Matcher instantiate(final ViatraQueryEngine engine) { + return SynchThree.Matcher.on(engine); + } + + @Override + public SynchThree.Matcher instantiate() { + return SynchThree.Matcher.create(); + } + + @Override + public SynchThree.Match newEmptyMatch() { + return SynchThree.Match.newEmptyMatch(); + } + + @Override + public SynchThree.Match newMatch(final Object... parameters) { + return SynchThree.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization) parameters[0]); + } + + /** + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created + * not at the class load time of the outer class, + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private final static SynchThree INSTANCE = new SynchThree(); + + /** + * Statically initializes the query specification after the field {@link #INSTANCE} is assigned. + * This initialization order is required to support indirect recursion. + * + *

The static initializer is defined using a helper field to work around limitations of the code generator. + * + */ + private final static Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private final static SynchThree.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_s = new PParameter("s", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Synchronization")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_s); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.synchThree"; + } + + @Override + public List getParameterNames() { + return Arrays.asList("s"); + } + + @Override + public List getParameters() { + return parameters; + } + + @Override + public Set doGetContainedBodies() { + setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); + Set bodies = new LinkedHashSet<>(); + { + PBody body = new PBody(this); + PVariable var_s = body.getOrCreateVariableByName("s"); + PVariable var_t1 = body.getOrCreateVariableByName("t1"); + PVariable var_t2 = body.getOrCreateVariableByName("t2"); + PVariable var_t3 = body.getOrCreateVariableByName("t3"); + new TypeConstraint(body, Tuples.flatTupleOf(var_s), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Synchronization"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_s, parameter_s) + )); + // Transition.target(t1,s) + new TypeConstraint(body, Tuples.flatTupleOf(var_t1), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); + PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_t1, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Transition", "target"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); + new Equality(body, var__virtual_0_, var_s); + // Transition.target(t2,s) + new TypeConstraint(body, Tuples.flatTupleOf(var_t2), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); + PVariable var__virtual_1_ = body.getOrCreateVariableByName(".virtual{1}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_t2, var__virtual_1_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Transition", "target"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_1_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); + new Equality(body, var__virtual_1_, var_s); + // Transition.target(t3,s) + new TypeConstraint(body, Tuples.flatTupleOf(var_t3), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); + PVariable var__virtual_2_ = body.getOrCreateVariableByName(".virtual{2}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_t3, var__virtual_2_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Transition", "target"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_2_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); + new Equality(body, var__virtual_2_, var_s); + // t1!=t2 + new Inequality(body, var_t1, var_t2); + // t2!=t3 + new Inequality(body, var_t2, var_t3); + // t1!=t3 + new Inequality(body, var_t1, var_t3); + bodies.add(body); + } + { + PBody body = new PBody(this); + PVariable var_s = body.getOrCreateVariableByName("s"); + PVariable var_t1 = body.getOrCreateVariableByName("t1"); + PVariable var_t2 = body.getOrCreateVariableByName("t2"); + PVariable var_t3 = body.getOrCreateVariableByName("t3"); + new TypeConstraint(body, Tuples.flatTupleOf(var_s), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Synchronization"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_s, parameter_s) + )); + // Transition.source(t1,s) + new TypeConstraint(body, Tuples.flatTupleOf(var_t1), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); + PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_t1, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Transition", "source"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); + new Equality(body, var__virtual_0_, var_s); + // Transition.source(t2,s) + new TypeConstraint(body, Tuples.flatTupleOf(var_t2), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); + PVariable var__virtual_1_ = body.getOrCreateVariableByName(".virtual{1}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_t2, var__virtual_1_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Transition", "source"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_1_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); + new Equality(body, var__virtual_1_, var_s); + // Transition.source(t3,s) + new TypeConstraint(body, Tuples.flatTupleOf(var_t3), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); + PVariable var__virtual_2_ = body.getOrCreateVariableByName(".virtual{2}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_t3, var__virtual_2_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Transition", "source"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_2_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); + new Equality(body, var__virtual_2_, var_s); + // t1!=t2 + new Inequality(body, var_t1, var_t2); + // t2!=t3 + new Inequality(body, var_t2, var_t3); + // t1!=t3 + new Inequality(body, var_t1, var_t3); + bodies.add(body); + } + { + PAnnotation annotation = new PAnnotation("Constraint"); + annotation.addAttribute("severity", "error"); + annotation.addAttribute("message", "error"); + annotation.addAttribute("key", Arrays.asList(new Object[] { + new ParameterReference("s") + })); + addAnnotation(annotation); + } + return bodies; + } + } +} 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 @@ +/** + * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql + */ +package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; + +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization; +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex; +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.Transition; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.log4j.Logger; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.viatra.query.runtime.api.IPatternMatch; +import org.eclipse.viatra.query.runtime.api.IQuerySpecification; +import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; +import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; +import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; +import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; +import org.eclipse.viatra.query.runtime.emf.types.EStructuralFeatureInstancesKey; +import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; +import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; +import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Inequality; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; +import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; + +/** + * A pattern-specific query specification that can instantiate Matcher in a type-safe way. + * + *

Original source: + *

+ *         {@literal @}Constraint(severity="error", message="error", key = {s})
+ *         pattern SynchronizedIncomingInSameRegion(s : Synchronization, v1 : Vertex, v2 : Vertex) {
+ *         	find transition(t1, v1, s);
+ *         	find transition(t2, v2, s);
+ *         	t1!=t2;
+ *         	Region.vertices(r, v1);
+ *         	Region.vertices(r, v2);
+ *         } or {
+ *         	find transition(t1, s, v1);
+ *         	find transition(t2, s, v2);
+ *         	t1!=t2;
+ *         	Region.vertices(r, v1);
+ *         	Region.vertices(r, v2);
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class SynchronizedIncomingInSameRegion extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedIncomingInSameRegion pattern, + * to be used in conjunction with {@link Matcher}. + * + *

Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. + * Each instance is a (possibly partial) substitution of pattern parameters, + * usable to represent a match of the pattern in the result of a query, + * or to specify the bound (fixed) input parameters when issuing a query. + * + * @see Matcher + * + */ + public static abstract class Match extends BasePatternMatch { + private Synchronization fS; + + private Vertex fV1; + + private Vertex fV2; + + private static List parameterNames = makeImmutableList("s", "v1", "v2"); + + private Match(final Synchronization pS, final Vertex pV1, final Vertex pV2) { + this.fS = pS; + this.fV1 = pV1; + this.fV2 = pV2; + } + + @Override + public Object get(final String parameterName) { + if ("s".equals(parameterName)) return this.fS; + if ("v1".equals(parameterName)) return this.fV1; + if ("v2".equals(parameterName)) return this.fV2; + return null; + } + + public Synchronization getS() { + return this.fS; + } + + public Vertex getV1() { + return this.fV1; + } + + public Vertex getV2() { + return this.fV2; + } + + @Override + public boolean set(final String parameterName, final Object newValue) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + if ("s".equals(parameterName) ) { + this.fS = (Synchronization) newValue; + return true; + } + if ("v1".equals(parameterName) ) { + this.fV1 = (Vertex) newValue; + return true; + } + if ("v2".equals(parameterName) ) { + this.fV2 = (Vertex) newValue; + return true; + } + return false; + } + + public void setS(final Synchronization pS) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fS = pS; + } + + public void setV1(final Vertex pV1) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fV1 = pV1; + } + + public void setV2(final Vertex pV2) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fV2 = pV2; + } + + @Override + public String patternName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedIncomingInSameRegion"; + } + + @Override + public List parameterNames() { + return SynchronizedIncomingInSameRegion.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fS, fV1, fV2}; + } + + @Override + public SynchronizedIncomingInSameRegion.Match toImmutable() { + return isMutable() ? newMatch(fS, fV1, fV2) : this; + } + + @Override + public String prettyPrint() { + StringBuilder result = new StringBuilder(); + result.append("\"s\"=" + prettyPrintValue(fS) + ", "); + result.append("\"v1\"=" + prettyPrintValue(fV1) + ", "); + result.append("\"v2\"=" + prettyPrintValue(fV2)); + return result.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(fS, fV1, fV2); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) { + return false; + } + if ((obj instanceof SynchronizedIncomingInSameRegion.Match)) { + SynchronizedIncomingInSameRegion.Match other = (SynchronizedIncomingInSameRegion.Match) obj; + return Objects.equals(fS, other.fS) && Objects.equals(fV1, other.fV1) && Objects.equals(fV2, other.fV2); + } else { + // this should be infrequent + if (!(obj instanceof IPatternMatch)) { + return false; + } + IPatternMatch otherSig = (IPatternMatch) obj; + return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); + } + } + + @Override + public SynchronizedIncomingInSameRegion specification() { + return SynchronizedIncomingInSameRegion.instance(); + } + + /** + * Returns an empty, mutable match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @return the empty match. + * + */ + public static SynchronizedIncomingInSameRegion.Match newEmptyMatch() { + return new Mutable(null, null, null); + } + + /** + * Returns a mutable (partial) match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @param pV1 the fixed value of pattern parameter v1, or null if not bound. + * @param pV2 the fixed value of pattern parameter v2, or null if not bound. + * @return the new, mutable (partial) match object. + * + */ + public static SynchronizedIncomingInSameRegion.Match newMutableMatch(final Synchronization pS, final Vertex pV1, final Vertex pV2) { + return new Mutable(pS, pV1, pV2); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @param pV1 the fixed value of pattern parameter v1, or null if not bound. + * @param pV2 the fixed value of pattern parameter v2, or null if not bound. + * @return the (partial) match object. + * + */ + public static SynchronizedIncomingInSameRegion.Match newMatch(final Synchronization pS, final Vertex pV1, final Vertex pV2) { + return new Immutable(pS, pV1, pV2); + } + + private static final class Mutable extends SynchronizedIncomingInSameRegion.Match { + Mutable(final Synchronization pS, final Vertex pV1, final Vertex pV2) { + super(pS, pV1, pV2); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends SynchronizedIncomingInSameRegion.Match { + Immutable(final Synchronization pS, final Vertex pV1, final Vertex pV2) { + super(pS, pV1, pV2); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedIncomingInSameRegion pattern, + * providing pattern-specific query methods. + * + *

Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, + * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. + * + *

Matches of the pattern will be represented as {@link Match}. + * + *

Original source: + *

+   * {@literal @}Constraint(severity="error", message="error", key = {s})
+   * pattern SynchronizedIncomingInSameRegion(s : Synchronization, v1 : Vertex, v2 : Vertex) {
+   * 	find transition(t1, v1, s);
+   * 	find transition(t2, v2, s);
+   * 	t1!=t2;
+   * 	Region.vertices(r, v1);
+   * 	Region.vertices(r, v2);
+   * } or {
+   * 	find transition(t1, s, v1);
+   * 	find transition(t2, s, v2);
+   * 	t1!=t2;
+   * 	Region.vertices(r, v1);
+   * 	Region.vertices(r, v2);
+   * }
+   * 
+ * + * @see Match + * @see SynchronizedIncomingInSameRegion + * + */ + public static class Matcher extends BaseMatcher { + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + public static SynchronizedIncomingInSameRegion.Matcher on(final ViatraQueryEngine engine) { + // check if matcher already exists + Matcher matcher = engine.getExistingMatcher(querySpecification()); + if (matcher == null) { + matcher = (Matcher)engine.getMatcher(querySpecification()); + } + return matcher; + } + + /** + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * @return an initialized matcher + * @noreference This method is for internal matcher initialization by the framework, do not call it manually. + * + */ + public static SynchronizedIncomingInSameRegion.Matcher create() { + return new Matcher(); + } + + private final static int POSITION_S = 0; + + private final static int POSITION_V1 = 1; + + private final static int POSITION_V2 = 2; + + private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(SynchronizedIncomingInSameRegion.Matcher.class); + + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + private Matcher() { + super(querySpecification()); + } + + /** + * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @param pV1 the fixed value of pattern parameter v1, or null if not bound. + * @param pV2 the fixed value of pattern parameter v2, or null if not bound. + * @return matches represented as a Match object. + * + */ + public Collection getAllMatches(final Synchronization pS, final Vertex pV1, final Vertex pV2) { + return rawStreamAllMatches(new Object[]{pS, pV1, pV2}).collect(Collectors.toSet()); + } + + /** + * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @param pV1 the fixed value of pattern parameter v1, or null if not bound. + * @param pV2 the fixed value of pattern parameter v2, or null if not bound. + * @return a stream of matches represented as a Match object. + * + */ + public Stream streamAllMatches(final Synchronization pS, final Vertex pV1, final Vertex pV2) { + return rawStreamAllMatches(new Object[]{pS, pV1, pV2}); + } + + /** + * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @param pV1 the fixed value of pattern parameter v1, or null if not bound. + * @param pV2 the fixed value of pattern parameter v2, or null if not bound. + * @return a match represented as a Match object, or null if no match is found. + * + */ + public Optional getOneArbitraryMatch(final Synchronization pS, final Vertex pV1, final Vertex pV2) { + return rawGetOneArbitraryMatch(new Object[]{pS, pV1, pV2}); + } + + /** + * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, + * under any possible substitution of the unspecified parameters (if any). + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @param pV1 the fixed value of pattern parameter v1, or null if not bound. + * @param pV2 the fixed value of pattern parameter v2, or null if not bound. + * @return true if the input is a valid (partial) match of the pattern. + * + */ + public boolean hasMatch(final Synchronization pS, final Vertex pV1, final Vertex pV2) { + return rawHasMatch(new Object[]{pS, pV1, pV2}); + } + + /** + * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @param pV1 the fixed value of pattern parameter v1, or null if not bound. + * @param pV2 the fixed value of pattern parameter v2, or null if not bound. + * @return the number of pattern matches found. + * + */ + public int countMatches(final Synchronization pS, final Vertex pV1, final Vertex pV2) { + return rawCountMatches(new Object[]{pS, pV1, pV2}); + } + + /** + * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @param pV1 the fixed value of pattern parameter v1, or null if not bound. + * @param pV2 the fixed value of pattern parameter v2, or null if not bound. + * @param processor the action that will process the selected match. + * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked + * + */ + public boolean forOneArbitraryMatch(final Synchronization pS, final Vertex pV1, final Vertex pV2, final Consumer processor) { + return rawForOneArbitraryMatch(new Object[]{pS, pV1, pV2}, processor); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @param pV1 the fixed value of pattern parameter v1, or null if not bound. + * @param pV2 the fixed value of pattern parameter v2, or null if not bound. + * @return the (partial) match object. + * + */ + public SynchronizedIncomingInSameRegion.Match newMatch(final Synchronization pS, final Vertex pV1, final Vertex pV2) { + return SynchronizedIncomingInSameRegion.Match.newMatch(pS, pV1, pV2); + } + + /** + * Retrieve the set of values that occur in matches for s. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfs(final Object[] parameters) { + return rawStreamAllValues(POSITION_S, parameters).map(Synchronization.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for s. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfs() { + return rawStreamAllValuesOfs(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for s. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfs() { + return rawStreamAllValuesOfs(emptyArray()); + } + + /** + * Retrieve the set of values that occur in matches for s. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfs(final SynchronizedIncomingInSameRegion.Match partialMatch) { + return rawStreamAllValuesOfs(partialMatch.toArray()); + } + + /** + * Retrieve the set of values that occur in matches for s. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfs(final Vertex pV1, final Vertex pV2) { + return rawStreamAllValuesOfs(new Object[]{null, pV1, pV2}); + } + + /** + * Retrieve the set of values that occur in matches for s. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfs(final SynchronizedIncomingInSameRegion.Match partialMatch) { + return rawStreamAllValuesOfs(partialMatch.toArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for s. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfs(final Vertex pV1, final Vertex pV2) { + return rawStreamAllValuesOfs(new Object[]{null, pV1, pV2}).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for v1. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfv1(final Object[] parameters) { + return rawStreamAllValues(POSITION_V1, parameters).map(Vertex.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for v1. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfv1() { + return rawStreamAllValuesOfv1(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for v1. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfv1() { + return rawStreamAllValuesOfv1(emptyArray()); + } + + /** + * Retrieve the set of values that occur in matches for v1. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfv1(final SynchronizedIncomingInSameRegion.Match partialMatch) { + return rawStreamAllValuesOfv1(partialMatch.toArray()); + } + + /** + * Retrieve the set of values that occur in matches for v1. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfv1(final Synchronization pS, final Vertex pV2) { + return rawStreamAllValuesOfv1(new Object[]{pS, null, pV2}); + } + + /** + * Retrieve the set of values that occur in matches for v1. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfv1(final SynchronizedIncomingInSameRegion.Match partialMatch) { + return rawStreamAllValuesOfv1(partialMatch.toArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for v1. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfv1(final Synchronization pS, final Vertex pV2) { + return rawStreamAllValuesOfv1(new Object[]{pS, null, pV2}).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for v2. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfv2(final Object[] parameters) { + return rawStreamAllValues(POSITION_V2, parameters).map(Vertex.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for v2. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfv2() { + return rawStreamAllValuesOfv2(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for v2. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfv2() { + return rawStreamAllValuesOfv2(emptyArray()); + } + + /** + * Retrieve the set of values that occur in matches for v2. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfv2(final SynchronizedIncomingInSameRegion.Match partialMatch) { + return rawStreamAllValuesOfv2(partialMatch.toArray()); + } + + /** + * Retrieve the set of values that occur in matches for v2. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfv2(final Synchronization pS, final Vertex pV1) { + return rawStreamAllValuesOfv2(new Object[]{pS, pV1, null}); + } + + /** + * Retrieve the set of values that occur in matches for v2. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfv2(final SynchronizedIncomingInSameRegion.Match partialMatch) { + return rawStreamAllValuesOfv2(partialMatch.toArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for v2. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfv2(final Synchronization pS, final Vertex pV1) { + return rawStreamAllValuesOfv2(new Object[]{pS, pV1, null}).collect(Collectors.toSet()); + } + + @Override + protected SynchronizedIncomingInSameRegion.Match tupleToMatch(final Tuple t) { + try { + return SynchronizedIncomingInSameRegion.Match.newMatch((Synchronization) t.get(POSITION_S), (Vertex) t.get(POSITION_V1), (Vertex) t.get(POSITION_V2)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected SynchronizedIncomingInSameRegion.Match arrayToMatch(final Object[] match) { + try { + return SynchronizedIncomingInSameRegion.Match.newMatch((Synchronization) match[POSITION_S], (Vertex) match[POSITION_V1], (Vertex) match[POSITION_V2]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected SynchronizedIncomingInSameRegion.Match arrayToMatchMutable(final Object[] match) { + try { + return SynchronizedIncomingInSameRegion.Match.newMutableMatch((Synchronization) match[POSITION_S], (Vertex) match[POSITION_V1], (Vertex) match[POSITION_V2]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + /** + * @return the singleton instance of the query specification of this pattern + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static IQuerySpecification querySpecification() { + return SynchronizedIncomingInSameRegion.instance(); + } + } + + private SynchronizedIncomingInSameRegion() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static SynchronizedIncomingInSameRegion instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected SynchronizedIncomingInSameRegion.Matcher instantiate(final ViatraQueryEngine engine) { + return SynchronizedIncomingInSameRegion.Matcher.on(engine); + } + + @Override + public SynchronizedIncomingInSameRegion.Matcher instantiate() { + return SynchronizedIncomingInSameRegion.Matcher.create(); + } + + @Override + public SynchronizedIncomingInSameRegion.Match newEmptyMatch() { + return SynchronizedIncomingInSameRegion.Match.newEmptyMatch(); + } + + @Override + public SynchronizedIncomingInSameRegion.Match newMatch(final Object... parameters) { + 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]); + } + + /** + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created + * not at the class load time of the outer class, + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private final static SynchronizedIncomingInSameRegion INSTANCE = new SynchronizedIncomingInSameRegion(); + + /** + * Statically initializes the query specification after the field {@link #INSTANCE} is assigned. + * This initialization order is required to support indirect recursion. + * + *

The static initializer is defined using a helper field to work around limitations of the code generator. + * + */ + private final static Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private final static SynchronizedIncomingInSameRegion.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_s = new PParameter("s", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Synchronization")), PParameterDirection.INOUT); + + private final PParameter parameter_v1 = new PParameter("v1", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Vertex")), PParameterDirection.INOUT); + + private final PParameter parameter_v2 = new PParameter("v2", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Vertex")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_s, parameter_v1, parameter_v2); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedIncomingInSameRegion"; + } + + @Override + public List getParameterNames() { + return Arrays.asList("s","v1","v2"); + } + + @Override + public List getParameters() { + return parameters; + } + + @Override + public Set doGetContainedBodies() { + setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); + Set bodies = new LinkedHashSet<>(); + { + PBody body = new PBody(this); + PVariable var_s = body.getOrCreateVariableByName("s"); + PVariable var_v1 = body.getOrCreateVariableByName("v1"); + PVariable var_v2 = body.getOrCreateVariableByName("v2"); + PVariable var_t1 = body.getOrCreateVariableByName("t1"); + PVariable var_t2 = body.getOrCreateVariableByName("t2"); + PVariable var_r = body.getOrCreateVariableByName("r"); + new TypeConstraint(body, Tuples.flatTupleOf(var_s), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Synchronization"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_v1), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_v2), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_s, parameter_s), + new ExportedParameter(body, var_v1, parameter_v1), + new ExportedParameter(body, var_v2, parameter_v2) + )); + // find transition(t1, v1, s) + new PositivePatternCall(body, Tuples.flatTupleOf(var_t1, var_v1, var_s), Transition.instance().getInternalQueryRepresentation()); + // find transition(t2, v2, s) + new PositivePatternCall(body, Tuples.flatTupleOf(var_t2, var_v2, var_s), Transition.instance().getInternalQueryRepresentation()); + // t1!=t2 + new Inequality(body, var_t1, var_t2); + // Region.vertices(r, v1) + new TypeConstraint(body, Tuples.flatTupleOf(var_r), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Region"))); + PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_r, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Region", "vertices"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); + new Equality(body, var__virtual_0_, var_v1); + // Region.vertices(r, v2) + new TypeConstraint(body, Tuples.flatTupleOf(var_r), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Region"))); + PVariable var__virtual_1_ = body.getOrCreateVariableByName(".virtual{1}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_r, var__virtual_1_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Region", "vertices"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_1_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); + new Equality(body, var__virtual_1_, var_v2); + bodies.add(body); + } + { + PBody body = new PBody(this); + PVariable var_s = body.getOrCreateVariableByName("s"); + PVariable var_v1 = body.getOrCreateVariableByName("v1"); + PVariable var_v2 = body.getOrCreateVariableByName("v2"); + PVariable var_t1 = body.getOrCreateVariableByName("t1"); + PVariable var_t2 = body.getOrCreateVariableByName("t2"); + PVariable var_r = body.getOrCreateVariableByName("r"); + new TypeConstraint(body, Tuples.flatTupleOf(var_s), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Synchronization"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_v1), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_v2), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_s, parameter_s), + new ExportedParameter(body, var_v1, parameter_v1), + new ExportedParameter(body, var_v2, parameter_v2) + )); + // find transition(t1, s, v1) + new PositivePatternCall(body, Tuples.flatTupleOf(var_t1, var_s, var_v1), Transition.instance().getInternalQueryRepresentation()); + // find transition(t2, s, v2) + new PositivePatternCall(body, Tuples.flatTupleOf(var_t2, var_s, var_v2), Transition.instance().getInternalQueryRepresentation()); + // t1!=t2 + new Inequality(body, var_t1, var_t2); + // Region.vertices(r, v1) + new TypeConstraint(body, Tuples.flatTupleOf(var_r), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Region"))); + PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_r, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Region", "vertices"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); + new Equality(body, var__virtual_0_, var_v1); + // Region.vertices(r, v2) + new TypeConstraint(body, Tuples.flatTupleOf(var_r), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Region"))); + PVariable var__virtual_1_ = body.getOrCreateVariableByName(".virtual{1}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_r, var__virtual_1_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Region", "vertices"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_1_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); + new Equality(body, var__virtual_1_, var_v2); + bodies.add(body); + } + { + PAnnotation annotation = new PAnnotation("Constraint"); + annotation.addAttribute("severity", "error"); + annotation.addAttribute("message", "error"); + annotation.addAttribute("key", Arrays.asList(new Object[] { + new ParameterReference("s") + })); + addAnnotation(annotation); + } + return bodies; + } + } +} 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 @@ +/** + * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql + */ +package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; + +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization; +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex; +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.Child; +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.HasMultipleRegions; +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.Transition; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.log4j.Logger; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.viatra.query.runtime.api.IPatternMatch; +import org.eclipse.viatra.query.runtime.api.IQuerySpecification; +import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; +import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; +import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; +import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; +import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; +import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; +import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.NegativePatternCall; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; +import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; + +/** + * A pattern-specific query specification that can instantiate Matcher in a type-safe way. + * + *

Original source: + *

+ *         {@literal @}Constraint(severity="error", message="error", key = {s})
+ *         pattern SynchronizedRegionDoesNotHaveMultipleRegions(s : Synchronization, v : Vertex) {
+ *         	find transition(_, v, s);
+ *         	find child(c,v);
+ *         	neg find hasMultipleRegions(c);
+ *         } or {
+ *         	find transition(_, s, v);
+ *         	find child(c,v);
+ *         	neg find hasMultipleRegions(c);
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class SynchronizedRegionDoesNotHaveMultipleRegions extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedRegionDoesNotHaveMultipleRegions pattern, + * to be used in conjunction with {@link Matcher}. + * + *

Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. + * Each instance is a (possibly partial) substitution of pattern parameters, + * usable to represent a match of the pattern in the result of a query, + * or to specify the bound (fixed) input parameters when issuing a query. + * + * @see Matcher + * + */ + public static abstract class Match extends BasePatternMatch { + private Synchronization fS; + + private Vertex fV; + + private static List parameterNames = makeImmutableList("s", "v"); + + private Match(final Synchronization pS, final Vertex pV) { + this.fS = pS; + this.fV = pV; + } + + @Override + public Object get(final String parameterName) { + if ("s".equals(parameterName)) return this.fS; + if ("v".equals(parameterName)) return this.fV; + return null; + } + + public Synchronization getS() { + return this.fS; + } + + public Vertex getV() { + return this.fV; + } + + @Override + public boolean set(final String parameterName, final Object newValue) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + if ("s".equals(parameterName) ) { + this.fS = (Synchronization) newValue; + return true; + } + if ("v".equals(parameterName) ) { + this.fV = (Vertex) newValue; + return true; + } + return false; + } + + public void setS(final Synchronization pS) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fS = pS; + } + + public void setV(final Vertex pV) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fV = pV; + } + + @Override + public String patternName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedRegionDoesNotHaveMultipleRegions"; + } + + @Override + public List parameterNames() { + return SynchronizedRegionDoesNotHaveMultipleRegions.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fS, fV}; + } + + @Override + public SynchronizedRegionDoesNotHaveMultipleRegions.Match toImmutable() { + return isMutable() ? newMatch(fS, fV) : this; + } + + @Override + public String prettyPrint() { + StringBuilder result = new StringBuilder(); + result.append("\"s\"=" + prettyPrintValue(fS) + ", "); + result.append("\"v\"=" + prettyPrintValue(fV)); + return result.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(fS, fV); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) { + return false; + } + if ((obj instanceof SynchronizedRegionDoesNotHaveMultipleRegions.Match)) { + SynchronizedRegionDoesNotHaveMultipleRegions.Match other = (SynchronizedRegionDoesNotHaveMultipleRegions.Match) obj; + return Objects.equals(fS, other.fS) && Objects.equals(fV, other.fV); + } else { + // this should be infrequent + if (!(obj instanceof IPatternMatch)) { + return false; + } + IPatternMatch otherSig = (IPatternMatch) obj; + return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); + } + } + + @Override + public SynchronizedRegionDoesNotHaveMultipleRegions specification() { + return SynchronizedRegionDoesNotHaveMultipleRegions.instance(); + } + + /** + * Returns an empty, mutable match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @return the empty match. + * + */ + public static SynchronizedRegionDoesNotHaveMultipleRegions.Match newEmptyMatch() { + return new Mutable(null, null); + } + + /** + * Returns a mutable (partial) match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @param pV the fixed value of pattern parameter v, or null if not bound. + * @return the new, mutable (partial) match object. + * + */ + public static SynchronizedRegionDoesNotHaveMultipleRegions.Match newMutableMatch(final Synchronization pS, final Vertex pV) { + return new Mutable(pS, pV); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @param pV the fixed value of pattern parameter v, or null if not bound. + * @return the (partial) match object. + * + */ + public static SynchronizedRegionDoesNotHaveMultipleRegions.Match newMatch(final Synchronization pS, final Vertex pV) { + return new Immutable(pS, pV); + } + + private static final class Mutable extends SynchronizedRegionDoesNotHaveMultipleRegions.Match { + Mutable(final Synchronization pS, final Vertex pV) { + super(pS, pV); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends SynchronizedRegionDoesNotHaveMultipleRegions.Match { + Immutable(final Synchronization pS, final Vertex pV) { + super(pS, pV); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedRegionDoesNotHaveMultipleRegions pattern, + * providing pattern-specific query methods. + * + *

Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, + * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. + * + *

Matches of the pattern will be represented as {@link Match}. + * + *

Original source: + *

+   * {@literal @}Constraint(severity="error", message="error", key = {s})
+   * pattern SynchronizedRegionDoesNotHaveMultipleRegions(s : Synchronization, v : Vertex) {
+   * 	find transition(_, v, s);
+   * 	find child(c,v);
+   * 	neg find hasMultipleRegions(c);
+   * } or {
+   * 	find transition(_, s, v);
+   * 	find child(c,v);
+   * 	neg find hasMultipleRegions(c);
+   * }
+   * 
+ * + * @see Match + * @see SynchronizedRegionDoesNotHaveMultipleRegions + * + */ + public static class Matcher extends BaseMatcher { + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + public static SynchronizedRegionDoesNotHaveMultipleRegions.Matcher on(final ViatraQueryEngine engine) { + // check if matcher already exists + Matcher matcher = engine.getExistingMatcher(querySpecification()); + if (matcher == null) { + matcher = (Matcher)engine.getMatcher(querySpecification()); + } + return matcher; + } + + /** + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * @return an initialized matcher + * @noreference This method is for internal matcher initialization by the framework, do not call it manually. + * + */ + public static SynchronizedRegionDoesNotHaveMultipleRegions.Matcher create() { + return new Matcher(); + } + + private final static int POSITION_S = 0; + + private final static int POSITION_V = 1; + + private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(SynchronizedRegionDoesNotHaveMultipleRegions.Matcher.class); + + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + private Matcher() { + super(querySpecification()); + } + + /** + * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @param pV the fixed value of pattern parameter v, or null if not bound. + * @return matches represented as a Match object. + * + */ + public Collection getAllMatches(final Synchronization pS, final Vertex pV) { + return rawStreamAllMatches(new Object[]{pS, pV}).collect(Collectors.toSet()); + } + + /** + * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @param pV the fixed value of pattern parameter v, or null if not bound. + * @return a stream of matches represented as a Match object. + * + */ + public Stream streamAllMatches(final Synchronization pS, final Vertex pV) { + return rawStreamAllMatches(new Object[]{pS, pV}); + } + + /** + * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @param pV the fixed value of pattern parameter v, or null if not bound. + * @return a match represented as a Match object, or null if no match is found. + * + */ + public Optional getOneArbitraryMatch(final Synchronization pS, final Vertex pV) { + return rawGetOneArbitraryMatch(new Object[]{pS, pV}); + } + + /** + * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, + * under any possible substitution of the unspecified parameters (if any). + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @param pV the fixed value of pattern parameter v, or null if not bound. + * @return true if the input is a valid (partial) match of the pattern. + * + */ + public boolean hasMatch(final Synchronization pS, final Vertex pV) { + return rawHasMatch(new Object[]{pS, pV}); + } + + /** + * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @param pV the fixed value of pattern parameter v, or null if not bound. + * @return the number of pattern matches found. + * + */ + public int countMatches(final Synchronization pS, final Vertex pV) { + return rawCountMatches(new Object[]{pS, pV}); + } + + /** + * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @param pV the fixed value of pattern parameter v, or null if not bound. + * @param processor the action that will process the selected match. + * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked + * + */ + public boolean forOneArbitraryMatch(final Synchronization pS, final Vertex pV, final Consumer processor) { + return rawForOneArbitraryMatch(new Object[]{pS, pV}, processor); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @param pV the fixed value of pattern parameter v, or null if not bound. + * @return the (partial) match object. + * + */ + public SynchronizedRegionDoesNotHaveMultipleRegions.Match newMatch(final Synchronization pS, final Vertex pV) { + return SynchronizedRegionDoesNotHaveMultipleRegions.Match.newMatch(pS, pV); + } + + /** + * Retrieve the set of values that occur in matches for s. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfs(final Object[] parameters) { + return rawStreamAllValues(POSITION_S, parameters).map(Synchronization.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for s. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfs() { + return rawStreamAllValuesOfs(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for s. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfs() { + return rawStreamAllValuesOfs(emptyArray()); + } + + /** + * Retrieve the set of values that occur in matches for s. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfs(final SynchronizedRegionDoesNotHaveMultipleRegions.Match partialMatch) { + return rawStreamAllValuesOfs(partialMatch.toArray()); + } + + /** + * Retrieve the set of values that occur in matches for s. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfs(final Vertex pV) { + return rawStreamAllValuesOfs(new Object[]{null, pV}); + } + + /** + * Retrieve the set of values that occur in matches for s. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfs(final SynchronizedRegionDoesNotHaveMultipleRegions.Match partialMatch) { + return rawStreamAllValuesOfs(partialMatch.toArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for s. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfs(final Vertex pV) { + return rawStreamAllValuesOfs(new Object[]{null, pV}).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for v. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfv(final Object[] parameters) { + return rawStreamAllValues(POSITION_V, parameters).map(Vertex.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for v. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfv() { + return rawStreamAllValuesOfv(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for v. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfv() { + return rawStreamAllValuesOfv(emptyArray()); + } + + /** + * Retrieve the set of values that occur in matches for v. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfv(final SynchronizedRegionDoesNotHaveMultipleRegions.Match partialMatch) { + return rawStreamAllValuesOfv(partialMatch.toArray()); + } + + /** + * Retrieve the set of values that occur in matches for v. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfv(final Synchronization pS) { + return rawStreamAllValuesOfv(new Object[]{pS, null}); + } + + /** + * Retrieve the set of values that occur in matches for v. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfv(final SynchronizedRegionDoesNotHaveMultipleRegions.Match partialMatch) { + return rawStreamAllValuesOfv(partialMatch.toArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for v. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfv(final Synchronization pS) { + return rawStreamAllValuesOfv(new Object[]{pS, null}).collect(Collectors.toSet()); + } + + @Override + protected SynchronizedRegionDoesNotHaveMultipleRegions.Match tupleToMatch(final Tuple t) { + try { + return SynchronizedRegionDoesNotHaveMultipleRegions.Match.newMatch((Synchronization) t.get(POSITION_S), (Vertex) t.get(POSITION_V)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected SynchronizedRegionDoesNotHaveMultipleRegions.Match arrayToMatch(final Object[] match) { + try { + return SynchronizedRegionDoesNotHaveMultipleRegions.Match.newMatch((Synchronization) match[POSITION_S], (Vertex) match[POSITION_V]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected SynchronizedRegionDoesNotHaveMultipleRegions.Match arrayToMatchMutable(final Object[] match) { + try { + return SynchronizedRegionDoesNotHaveMultipleRegions.Match.newMutableMatch((Synchronization) match[POSITION_S], (Vertex) match[POSITION_V]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + /** + * @return the singleton instance of the query specification of this pattern + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static IQuerySpecification querySpecification() { + return SynchronizedRegionDoesNotHaveMultipleRegions.instance(); + } + } + + private SynchronizedRegionDoesNotHaveMultipleRegions() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static SynchronizedRegionDoesNotHaveMultipleRegions instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected SynchronizedRegionDoesNotHaveMultipleRegions.Matcher instantiate(final ViatraQueryEngine engine) { + return SynchronizedRegionDoesNotHaveMultipleRegions.Matcher.on(engine); + } + + @Override + public SynchronizedRegionDoesNotHaveMultipleRegions.Matcher instantiate() { + return SynchronizedRegionDoesNotHaveMultipleRegions.Matcher.create(); + } + + @Override + public SynchronizedRegionDoesNotHaveMultipleRegions.Match newEmptyMatch() { + return SynchronizedRegionDoesNotHaveMultipleRegions.Match.newEmptyMatch(); + } + + @Override + public SynchronizedRegionDoesNotHaveMultipleRegions.Match newMatch(final Object... parameters) { + return SynchronizedRegionDoesNotHaveMultipleRegions.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization) parameters[0], (ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex) parameters[1]); + } + + /** + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created + * not at the class load time of the outer class, + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private final static SynchronizedRegionDoesNotHaveMultipleRegions INSTANCE = new SynchronizedRegionDoesNotHaveMultipleRegions(); + + /** + * Statically initializes the query specification after the field {@link #INSTANCE} is assigned. + * This initialization order is required to support indirect recursion. + * + *

The static initializer is defined using a helper field to work around limitations of the code generator. + * + */ + private final static Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private final static SynchronizedRegionDoesNotHaveMultipleRegions.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_s = new PParameter("s", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Synchronization")), PParameterDirection.INOUT); + + private final PParameter parameter_v = new PParameter("v", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Vertex")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_s, parameter_v); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedRegionDoesNotHaveMultipleRegions"; + } + + @Override + public List getParameterNames() { + return Arrays.asList("s","v"); + } + + @Override + public List getParameters() { + return parameters; + } + + @Override + public Set doGetContainedBodies() { + setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); + Set bodies = new LinkedHashSet<>(); + { + PBody body = new PBody(this); + PVariable var_s = body.getOrCreateVariableByName("s"); + PVariable var_v = body.getOrCreateVariableByName("v"); + PVariable var___0_ = body.getOrCreateVariableByName("_<0>"); + PVariable var_c = body.getOrCreateVariableByName("c"); + new TypeConstraint(body, Tuples.flatTupleOf(var_s), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Synchronization"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_v), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_s, parameter_s), + new ExportedParameter(body, var_v, parameter_v) + )); + // find transition(_, v, s) + new PositivePatternCall(body, Tuples.flatTupleOf(var___0_, var_v, var_s), Transition.instance().getInternalQueryRepresentation()); + // find child(c,v) + new PositivePatternCall(body, Tuples.flatTupleOf(var_c, var_v), Child.instance().getInternalQueryRepresentation()); + // neg find hasMultipleRegions(c) + new NegativePatternCall(body, Tuples.flatTupleOf(var_c), HasMultipleRegions.instance().getInternalQueryRepresentation()); + bodies.add(body); + } + { + PBody body = new PBody(this); + PVariable var_s = body.getOrCreateVariableByName("s"); + PVariable var_v = body.getOrCreateVariableByName("v"); + PVariable var___0_ = body.getOrCreateVariableByName("_<0>"); + PVariable var_c = body.getOrCreateVariableByName("c"); + new TypeConstraint(body, Tuples.flatTupleOf(var_s), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Synchronization"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_v), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_s, parameter_s), + new ExportedParameter(body, var_v, parameter_v) + )); + // find transition(_, s, v) + new PositivePatternCall(body, Tuples.flatTupleOf(var___0_, var_s, var_v), Transition.instance().getInternalQueryRepresentation()); + // find child(c,v) + new PositivePatternCall(body, Tuples.flatTupleOf(var_c, var_v), Child.instance().getInternalQueryRepresentation()); + // neg find hasMultipleRegions(c) + new NegativePatternCall(body, Tuples.flatTupleOf(var_c), HasMultipleRegions.instance().getInternalQueryRepresentation()); + bodies.add(body); + } + { + PAnnotation annotation = new PAnnotation("Constraint"); + annotation.addAttribute("severity", "error"); + annotation.addAttribute("message", "error"); + annotation.addAttribute("key", Arrays.asList(new Object[] { + new ParameterReference("s") + })); + addAnnotation(annotation); + } + return bodies; + } + } +} 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 @@ +/** + * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql + */ +package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; + +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization; +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex; +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.Transition; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.log4j.Logger; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.viatra.query.runtime.api.IPatternMatch; +import org.eclipse.viatra.query.runtime.api.IQuerySpecification; +import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; +import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; +import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; +import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; +import org.eclipse.viatra.query.runtime.emf.types.EStructuralFeatureInstancesKey; +import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; +import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; +import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Inequality; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.PositivePatternCall; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; +import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; + +/** + * A pattern-specific query specification that can instantiate Matcher in a type-safe way. + * + *

Original source: + *

+ *         {@literal @}Constraint(severity="error", message="error", key = {s})
+ *         pattern SynchronizedRegionsAreNotSiblings(s : Synchronization, v1 : Vertex, v2 : Vertex) {
+ *         	find transition(_, v1, s);
+ *         	find transition(_, v2, s);
+ *         	CompositeElement.regions.vertices(r1, v1);
+ *         	CompositeElement.regions.vertices(r2, v2);
+ *         	r1 != r2;
+ *         } or {
+ *         	find transition(_, s, v1);
+ *         	find transition(_, s, v2);
+ *         	CompositeElement.regions.vertices(r1, v1);
+ *         	CompositeElement.regions.vertices(r2, v2);
+ *         	r1 != r2;
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class SynchronizedRegionsAreNotSiblings extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedRegionsAreNotSiblings pattern, + * to be used in conjunction with {@link Matcher}. + * + *

Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. + * Each instance is a (possibly partial) substitution of pattern parameters, + * usable to represent a match of the pattern in the result of a query, + * or to specify the bound (fixed) input parameters when issuing a query. + * + * @see Matcher + * + */ + public static abstract class Match extends BasePatternMatch { + private Synchronization fS; + + private Vertex fV1; + + private Vertex fV2; + + private static List parameterNames = makeImmutableList("s", "v1", "v2"); + + private Match(final Synchronization pS, final Vertex pV1, final Vertex pV2) { + this.fS = pS; + this.fV1 = pV1; + this.fV2 = pV2; + } + + @Override + public Object get(final String parameterName) { + if ("s".equals(parameterName)) return this.fS; + if ("v1".equals(parameterName)) return this.fV1; + if ("v2".equals(parameterName)) return this.fV2; + return null; + } + + public Synchronization getS() { + return this.fS; + } + + public Vertex getV1() { + return this.fV1; + } + + public Vertex getV2() { + return this.fV2; + } + + @Override + public boolean set(final String parameterName, final Object newValue) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + if ("s".equals(parameterName) ) { + this.fS = (Synchronization) newValue; + return true; + } + if ("v1".equals(parameterName) ) { + this.fV1 = (Vertex) newValue; + return true; + } + if ("v2".equals(parameterName) ) { + this.fV2 = (Vertex) newValue; + return true; + } + return false; + } + + public void setS(final Synchronization pS) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fS = pS; + } + + public void setV1(final Vertex pV1) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fV1 = pV1; + } + + public void setV2(final Vertex pV2) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fV2 = pV2; + } + + @Override + public String patternName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedRegionsAreNotSiblings"; + } + + @Override + public List parameterNames() { + return SynchronizedRegionsAreNotSiblings.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fS, fV1, fV2}; + } + + @Override + public SynchronizedRegionsAreNotSiblings.Match toImmutable() { + return isMutable() ? newMatch(fS, fV1, fV2) : this; + } + + @Override + public String prettyPrint() { + StringBuilder result = new StringBuilder(); + result.append("\"s\"=" + prettyPrintValue(fS) + ", "); + result.append("\"v1\"=" + prettyPrintValue(fV1) + ", "); + result.append("\"v2\"=" + prettyPrintValue(fV2)); + return result.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(fS, fV1, fV2); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) { + return false; + } + if ((obj instanceof SynchronizedRegionsAreNotSiblings.Match)) { + SynchronizedRegionsAreNotSiblings.Match other = (SynchronizedRegionsAreNotSiblings.Match) obj; + return Objects.equals(fS, other.fS) && Objects.equals(fV1, other.fV1) && Objects.equals(fV2, other.fV2); + } else { + // this should be infrequent + if (!(obj instanceof IPatternMatch)) { + return false; + } + IPatternMatch otherSig = (IPatternMatch) obj; + return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); + } + } + + @Override + public SynchronizedRegionsAreNotSiblings specification() { + return SynchronizedRegionsAreNotSiblings.instance(); + } + + /** + * Returns an empty, mutable match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @return the empty match. + * + */ + public static SynchronizedRegionsAreNotSiblings.Match newEmptyMatch() { + return new Mutable(null, null, null); + } + + /** + * Returns a mutable (partial) match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @param pV1 the fixed value of pattern parameter v1, or null if not bound. + * @param pV2 the fixed value of pattern parameter v2, or null if not bound. + * @return the new, mutable (partial) match object. + * + */ + public static SynchronizedRegionsAreNotSiblings.Match newMutableMatch(final Synchronization pS, final Vertex pV1, final Vertex pV2) { + return new Mutable(pS, pV1, pV2); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @param pV1 the fixed value of pattern parameter v1, or null if not bound. + * @param pV2 the fixed value of pattern parameter v2, or null if not bound. + * @return the (partial) match object. + * + */ + public static SynchronizedRegionsAreNotSiblings.Match newMatch(final Synchronization pS, final Vertex pV1, final Vertex pV2) { + return new Immutable(pS, pV1, pV2); + } + + private static final class Mutable extends SynchronizedRegionsAreNotSiblings.Match { + Mutable(final Synchronization pS, final Vertex pV1, final Vertex pV2) { + super(pS, pV1, pV2); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends SynchronizedRegionsAreNotSiblings.Match { + Immutable(final Synchronization pS, final Vertex pV1, final Vertex pV2) { + super(pS, pV1, pV2); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedRegionsAreNotSiblings pattern, + * providing pattern-specific query methods. + * + *

Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, + * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. + * + *

Matches of the pattern will be represented as {@link Match}. + * + *

Original source: + *

+   * {@literal @}Constraint(severity="error", message="error", key = {s})
+   * pattern SynchronizedRegionsAreNotSiblings(s : Synchronization, v1 : Vertex, v2 : Vertex) {
+   * 	find transition(_, v1, s);
+   * 	find transition(_, v2, s);
+   * 	CompositeElement.regions.vertices(r1, v1);
+   * 	CompositeElement.regions.vertices(r2, v2);
+   * 	r1 != r2;
+   * } or {
+   * 	find transition(_, s, v1);
+   * 	find transition(_, s, v2);
+   * 	CompositeElement.regions.vertices(r1, v1);
+   * 	CompositeElement.regions.vertices(r2, v2);
+   * 	r1 != r2;
+   * }
+   * 
+ * + * @see Match + * @see SynchronizedRegionsAreNotSiblings + * + */ + public static class Matcher extends BaseMatcher { + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + public static SynchronizedRegionsAreNotSiblings.Matcher on(final ViatraQueryEngine engine) { + // check if matcher already exists + Matcher matcher = engine.getExistingMatcher(querySpecification()); + if (matcher == null) { + matcher = (Matcher)engine.getMatcher(querySpecification()); + } + return matcher; + } + + /** + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * @return an initialized matcher + * @noreference This method is for internal matcher initialization by the framework, do not call it manually. + * + */ + public static SynchronizedRegionsAreNotSiblings.Matcher create() { + return new Matcher(); + } + + private final static int POSITION_S = 0; + + private final static int POSITION_V1 = 1; + + private final static int POSITION_V2 = 2; + + private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(SynchronizedRegionsAreNotSiblings.Matcher.class); + + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + private Matcher() { + super(querySpecification()); + } + + /** + * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @param pV1 the fixed value of pattern parameter v1, or null if not bound. + * @param pV2 the fixed value of pattern parameter v2, or null if not bound. + * @return matches represented as a Match object. + * + */ + public Collection getAllMatches(final Synchronization pS, final Vertex pV1, final Vertex pV2) { + return rawStreamAllMatches(new Object[]{pS, pV1, pV2}).collect(Collectors.toSet()); + } + + /** + * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @param pV1 the fixed value of pattern parameter v1, or null if not bound. + * @param pV2 the fixed value of pattern parameter v2, or null if not bound. + * @return a stream of matches represented as a Match object. + * + */ + public Stream streamAllMatches(final Synchronization pS, final Vertex pV1, final Vertex pV2) { + return rawStreamAllMatches(new Object[]{pS, pV1, pV2}); + } + + /** + * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @param pV1 the fixed value of pattern parameter v1, or null if not bound. + * @param pV2 the fixed value of pattern parameter v2, or null if not bound. + * @return a match represented as a Match object, or null if no match is found. + * + */ + public Optional getOneArbitraryMatch(final Synchronization pS, final Vertex pV1, final Vertex pV2) { + return rawGetOneArbitraryMatch(new Object[]{pS, pV1, pV2}); + } + + /** + * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, + * under any possible substitution of the unspecified parameters (if any). + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @param pV1 the fixed value of pattern parameter v1, or null if not bound. + * @param pV2 the fixed value of pattern parameter v2, or null if not bound. + * @return true if the input is a valid (partial) match of the pattern. + * + */ + public boolean hasMatch(final Synchronization pS, final Vertex pV1, final Vertex pV2) { + return rawHasMatch(new Object[]{pS, pV1, pV2}); + } + + /** + * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @param pV1 the fixed value of pattern parameter v1, or null if not bound. + * @param pV2 the fixed value of pattern parameter v2, or null if not bound. + * @return the number of pattern matches found. + * + */ + public int countMatches(final Synchronization pS, final Vertex pV1, final Vertex pV2) { + return rawCountMatches(new Object[]{pS, pV1, pV2}); + } + + /** + * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @param pV1 the fixed value of pattern parameter v1, or null if not bound. + * @param pV2 the fixed value of pattern parameter v2, or null if not bound. + * @param processor the action that will process the selected match. + * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked + * + */ + public boolean forOneArbitraryMatch(final Synchronization pS, final Vertex pV1, final Vertex pV2, final Consumer processor) { + return rawForOneArbitraryMatch(new Object[]{pS, pV1, pV2}, processor); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pS the fixed value of pattern parameter s, or null if not bound. + * @param pV1 the fixed value of pattern parameter v1, or null if not bound. + * @param pV2 the fixed value of pattern parameter v2, or null if not bound. + * @return the (partial) match object. + * + */ + public SynchronizedRegionsAreNotSiblings.Match newMatch(final Synchronization pS, final Vertex pV1, final Vertex pV2) { + return SynchronizedRegionsAreNotSiblings.Match.newMatch(pS, pV1, pV2); + } + + /** + * Retrieve the set of values that occur in matches for s. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfs(final Object[] parameters) { + return rawStreamAllValues(POSITION_S, parameters).map(Synchronization.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for s. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfs() { + return rawStreamAllValuesOfs(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for s. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfs() { + return rawStreamAllValuesOfs(emptyArray()); + } + + /** + * Retrieve the set of values that occur in matches for s. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfs(final SynchronizedRegionsAreNotSiblings.Match partialMatch) { + return rawStreamAllValuesOfs(partialMatch.toArray()); + } + + /** + * Retrieve the set of values that occur in matches for s. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfs(final Vertex pV1, final Vertex pV2) { + return rawStreamAllValuesOfs(new Object[]{null, pV1, pV2}); + } + + /** + * Retrieve the set of values that occur in matches for s. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfs(final SynchronizedRegionsAreNotSiblings.Match partialMatch) { + return rawStreamAllValuesOfs(partialMatch.toArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for s. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfs(final Vertex pV1, final Vertex pV2) { + return rawStreamAllValuesOfs(new Object[]{null, pV1, pV2}).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for v1. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfv1(final Object[] parameters) { + return rawStreamAllValues(POSITION_V1, parameters).map(Vertex.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for v1. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfv1() { + return rawStreamAllValuesOfv1(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for v1. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfv1() { + return rawStreamAllValuesOfv1(emptyArray()); + } + + /** + * Retrieve the set of values that occur in matches for v1. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfv1(final SynchronizedRegionsAreNotSiblings.Match partialMatch) { + return rawStreamAllValuesOfv1(partialMatch.toArray()); + } + + /** + * Retrieve the set of values that occur in matches for v1. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfv1(final Synchronization pS, final Vertex pV2) { + return rawStreamAllValuesOfv1(new Object[]{pS, null, pV2}); + } + + /** + * Retrieve the set of values that occur in matches for v1. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfv1(final SynchronizedRegionsAreNotSiblings.Match partialMatch) { + return rawStreamAllValuesOfv1(partialMatch.toArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for v1. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfv1(final Synchronization pS, final Vertex pV2) { + return rawStreamAllValuesOfv1(new Object[]{pS, null, pV2}).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for v2. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfv2(final Object[] parameters) { + return rawStreamAllValues(POSITION_V2, parameters).map(Vertex.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for v2. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfv2() { + return rawStreamAllValuesOfv2(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for v2. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfv2() { + return rawStreamAllValuesOfv2(emptyArray()); + } + + /** + * Retrieve the set of values that occur in matches for v2. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfv2(final SynchronizedRegionsAreNotSiblings.Match partialMatch) { + return rawStreamAllValuesOfv2(partialMatch.toArray()); + } + + /** + * Retrieve the set of values that occur in matches for v2. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfv2(final Synchronization pS, final Vertex pV1) { + return rawStreamAllValuesOfv2(new Object[]{pS, pV1, null}); + } + + /** + * Retrieve the set of values that occur in matches for v2. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfv2(final SynchronizedRegionsAreNotSiblings.Match partialMatch) { + return rawStreamAllValuesOfv2(partialMatch.toArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for v2. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfv2(final Synchronization pS, final Vertex pV1) { + return rawStreamAllValuesOfv2(new Object[]{pS, pV1, null}).collect(Collectors.toSet()); + } + + @Override + protected SynchronizedRegionsAreNotSiblings.Match tupleToMatch(final Tuple t) { + try { + return SynchronizedRegionsAreNotSiblings.Match.newMatch((Synchronization) t.get(POSITION_S), (Vertex) t.get(POSITION_V1), (Vertex) t.get(POSITION_V2)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected SynchronizedRegionsAreNotSiblings.Match arrayToMatch(final Object[] match) { + try { + return SynchronizedRegionsAreNotSiblings.Match.newMatch((Synchronization) match[POSITION_S], (Vertex) match[POSITION_V1], (Vertex) match[POSITION_V2]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected SynchronizedRegionsAreNotSiblings.Match arrayToMatchMutable(final Object[] match) { + try { + return SynchronizedRegionsAreNotSiblings.Match.newMutableMatch((Synchronization) match[POSITION_S], (Vertex) match[POSITION_V1], (Vertex) match[POSITION_V2]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + /** + * @return the singleton instance of the query specification of this pattern + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static IQuerySpecification querySpecification() { + return SynchronizedRegionsAreNotSiblings.instance(); + } + } + + private SynchronizedRegionsAreNotSiblings() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static SynchronizedRegionsAreNotSiblings instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected SynchronizedRegionsAreNotSiblings.Matcher instantiate(final ViatraQueryEngine engine) { + return SynchronizedRegionsAreNotSiblings.Matcher.on(engine); + } + + @Override + public SynchronizedRegionsAreNotSiblings.Matcher instantiate() { + return SynchronizedRegionsAreNotSiblings.Matcher.create(); + } + + @Override + public SynchronizedRegionsAreNotSiblings.Match newEmptyMatch() { + return SynchronizedRegionsAreNotSiblings.Match.newEmptyMatch(); + } + + @Override + public SynchronizedRegionsAreNotSiblings.Match newMatch(final Object... parameters) { + 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]); + } + + /** + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created + * not at the class load time of the outer class, + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private final static SynchronizedRegionsAreNotSiblings INSTANCE = new SynchronizedRegionsAreNotSiblings(); + + /** + * Statically initializes the query specification after the field {@link #INSTANCE} is assigned. + * This initialization order is required to support indirect recursion. + * + *

The static initializer is defined using a helper field to work around limitations of the code generator. + * + */ + private final static Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private final static SynchronizedRegionsAreNotSiblings.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_s = new PParameter("s", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Synchronization")), PParameterDirection.INOUT); + + private final PParameter parameter_v1 = new PParameter("v1", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Vertex")), PParameterDirection.INOUT); + + private final PParameter parameter_v2 = new PParameter("v2", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Vertex")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_s, parameter_v1, parameter_v2); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.SynchronizedRegionsAreNotSiblings"; + } + + @Override + public List getParameterNames() { + return Arrays.asList("s","v1","v2"); + } + + @Override + public List getParameters() { + return parameters; + } + + @Override + public Set doGetContainedBodies() { + setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); + Set bodies = new LinkedHashSet<>(); + { + PBody body = new PBody(this); + PVariable var_s = body.getOrCreateVariableByName("s"); + PVariable var_v1 = body.getOrCreateVariableByName("v1"); + PVariable var_v2 = body.getOrCreateVariableByName("v2"); + PVariable var___0_ = body.getOrCreateVariableByName("_<0>"); + PVariable var___1_ = body.getOrCreateVariableByName("_<1>"); + PVariable var_r1 = body.getOrCreateVariableByName("r1"); + PVariable var_r2 = body.getOrCreateVariableByName("r2"); + new TypeConstraint(body, Tuples.flatTupleOf(var_s), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Synchronization"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_v1), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_v2), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_s, parameter_s), + new ExportedParameter(body, var_v1, parameter_v1), + new ExportedParameter(body, var_v2, parameter_v2) + )); + // find transition(_, v1, s) + new PositivePatternCall(body, Tuples.flatTupleOf(var___0_, var_v1, var_s), Transition.instance().getInternalQueryRepresentation()); + // find transition(_, v2, s) + new PositivePatternCall(body, Tuples.flatTupleOf(var___1_, var_v2, var_s), Transition.instance().getInternalQueryRepresentation()); + // CompositeElement.regions.vertices(r1, v1) + new TypeConstraint(body, Tuples.flatTupleOf(var_r1), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "CompositeElement"))); + PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_r1, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "CompositeElement", "regions"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Region"))); + PVariable var__virtual_1_ = body.getOrCreateVariableByName(".virtual{1}"); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_, var__virtual_1_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Region", "vertices"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_1_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); + new Equality(body, var__virtual_1_, var_v1); + // CompositeElement.regions.vertices(r2, v2) + new TypeConstraint(body, Tuples.flatTupleOf(var_r2), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "CompositeElement"))); + PVariable var__virtual_2_ = body.getOrCreateVariableByName(".virtual{2}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_r2, var__virtual_2_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "CompositeElement", "regions"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_2_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Region"))); + PVariable var__virtual_3_ = body.getOrCreateVariableByName(".virtual{3}"); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_2_, var__virtual_3_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Region", "vertices"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_3_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); + new Equality(body, var__virtual_3_, var_v2); + // r1 != r2 + new Inequality(body, var_r1, var_r2); + bodies.add(body); + } + { + PBody body = new PBody(this); + PVariable var_s = body.getOrCreateVariableByName("s"); + PVariable var_v1 = body.getOrCreateVariableByName("v1"); + PVariable var_v2 = body.getOrCreateVariableByName("v2"); + PVariable var___0_ = body.getOrCreateVariableByName("_<0>"); + PVariable var___1_ = body.getOrCreateVariableByName("_<1>"); + PVariable var_r1 = body.getOrCreateVariableByName("r1"); + PVariable var_r2 = body.getOrCreateVariableByName("r2"); + new TypeConstraint(body, Tuples.flatTupleOf(var_s), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Synchronization"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_v1), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_v2), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_s, parameter_s), + new ExportedParameter(body, var_v1, parameter_v1), + new ExportedParameter(body, var_v2, parameter_v2) + )); + // find transition(_, s, v1) + new PositivePatternCall(body, Tuples.flatTupleOf(var___0_, var_s, var_v1), Transition.instance().getInternalQueryRepresentation()); + // find transition(_, s, v2) + new PositivePatternCall(body, Tuples.flatTupleOf(var___1_, var_s, var_v2), Transition.instance().getInternalQueryRepresentation()); + // CompositeElement.regions.vertices(r1, v1) + new TypeConstraint(body, Tuples.flatTupleOf(var_r1), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "CompositeElement"))); + PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_r1, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "CompositeElement", "regions"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Region"))); + PVariable var__virtual_1_ = body.getOrCreateVariableByName(".virtual{1}"); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_, var__virtual_1_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Region", "vertices"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_1_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); + new Equality(body, var__virtual_1_, var_v1); + // CompositeElement.regions.vertices(r2, v2) + new TypeConstraint(body, Tuples.flatTupleOf(var_r2), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "CompositeElement"))); + PVariable var__virtual_2_ = body.getOrCreateVariableByName(".virtual{2}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_r2, var__virtual_2_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "CompositeElement", "regions"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_2_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Region"))); + PVariable var__virtual_3_ = body.getOrCreateVariableByName(".virtual{3}"); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_2_, var__virtual_3_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Region", "vertices"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_3_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); + new Equality(body, var__virtual_3_, var_v2); + // r1 != r2 + new Inequality(body, var_r1, var_r2); + bodies.add(body); + } + { + PAnnotation annotation = new PAnnotation("Constraint"); + annotation.addAttribute("severity", "error"); + annotation.addAttribute("message", "error"); + annotation.addAttribute("key", Arrays.asList(new Object[] { + new ParameterReference("s") + })); + addAnnotation(annotation); + } + return bodies; + } + } +} 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 @@ +/** + * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql + */ +package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; + +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.log4j.Logger; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.viatra.query.runtime.api.IPatternMatch; +import org.eclipse.viatra.query.runtime.api.IQuerySpecification; +import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; +import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; +import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; +import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; +import org.eclipse.viatra.query.runtime.emf.types.EStructuralFeatureInstancesKey; +import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; +import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; +import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Equality; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; +import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; + +/** + * A pattern-specific query specification that can instantiate Matcher in a type-safe way. + * + *

Original source: + *

+ *         pattern transition(t : Transition, src : Vertex, trg : Vertex) {
+ *         	Transition.source(t, src);
+ *         	Transition.target(t, trg);
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class Transition extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.transition pattern, + * to be used in conjunction with {@link Matcher}. + * + *

Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. + * Each instance is a (possibly partial) substitution of pattern parameters, + * usable to represent a match of the pattern in the result of a query, + * or to specify the bound (fixed) input parameters when issuing a query. + * + * @see Matcher + * + */ + public static abstract class Match extends BasePatternMatch { + private ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition fT; + + private Vertex fSrc; + + private Vertex fTrg; + + private static List parameterNames = makeImmutableList("t", "src", "trg"); + + private Match(final ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition pT, final Vertex pSrc, final Vertex pTrg) { + this.fT = pT; + this.fSrc = pSrc; + this.fTrg = pTrg; + } + + @Override + public Object get(final String parameterName) { + if ("t".equals(parameterName)) return this.fT; + if ("src".equals(parameterName)) return this.fSrc; + if ("trg".equals(parameterName)) return this.fTrg; + return null; + } + + public ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition getT() { + return this.fT; + } + + public Vertex getSrc() { + return this.fSrc; + } + + public Vertex getTrg() { + return this.fTrg; + } + + @Override + public boolean set(final String parameterName, final Object newValue) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + if ("t".equals(parameterName) ) { + this.fT = (ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition) newValue; + return true; + } + if ("src".equals(parameterName) ) { + this.fSrc = (Vertex) newValue; + return true; + } + if ("trg".equals(parameterName) ) { + this.fTrg = (Vertex) newValue; + return true; + } + return false; + } + + public void setT(final ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition pT) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fT = pT; + } + + public void setSrc(final Vertex pSrc) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fSrc = pSrc; + } + + public void setTrg(final Vertex pTrg) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fTrg = pTrg; + } + + @Override + public String patternName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.transition"; + } + + @Override + public List parameterNames() { + return Transition.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fT, fSrc, fTrg}; + } + + @Override + public Transition.Match toImmutable() { + return isMutable() ? newMatch(fT, fSrc, fTrg) : this; + } + + @Override + public String prettyPrint() { + StringBuilder result = new StringBuilder(); + result.append("\"t\"=" + prettyPrintValue(fT) + ", "); + result.append("\"src\"=" + prettyPrintValue(fSrc) + ", "); + result.append("\"trg\"=" + prettyPrintValue(fTrg)); + return result.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(fT, fSrc, fTrg); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) { + return false; + } + if ((obj instanceof Transition.Match)) { + Transition.Match other = (Transition.Match) obj; + return Objects.equals(fT, other.fT) && Objects.equals(fSrc, other.fSrc) && Objects.equals(fTrg, other.fTrg); + } else { + // this should be infrequent + if (!(obj instanceof IPatternMatch)) { + return false; + } + IPatternMatch otherSig = (IPatternMatch) obj; + return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); + } + } + + @Override + public Transition specification() { + return Transition.instance(); + } + + /** + * Returns an empty, mutable match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @return the empty match. + * + */ + public static Transition.Match newEmptyMatch() { + return new Mutable(null, null, null); + } + + /** + * Returns a mutable (partial) match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pSrc the fixed value of pattern parameter src, or null if not bound. + * @param pTrg the fixed value of pattern parameter trg, or null if not bound. + * @return the new, mutable (partial) match object. + * + */ + public static Transition.Match newMutableMatch(final ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition pT, final Vertex pSrc, final Vertex pTrg) { + return new Mutable(pT, pSrc, pTrg); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pSrc the fixed value of pattern parameter src, or null if not bound. + * @param pTrg the fixed value of pattern parameter trg, or null if not bound. + * @return the (partial) match object. + * + */ + public static Transition.Match newMatch(final ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition pT, final Vertex pSrc, final Vertex pTrg) { + return new Immutable(pT, pSrc, pTrg); + } + + private static final class Mutable extends Transition.Match { + Mutable(final ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition pT, final Vertex pSrc, final Vertex pTrg) { + super(pT, pSrc, pTrg); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends Transition.Match { + Immutable(final ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition pT, final Vertex pSrc, final Vertex pTrg) { + super(pT, pSrc, pTrg); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.transition pattern, + * providing pattern-specific query methods. + * + *

Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, + * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. + * + *

Matches of the pattern will be represented as {@link Match}. + * + *

Original source: + *

+   * pattern transition(t : Transition, src : Vertex, trg : Vertex) {
+   * 	Transition.source(t, src);
+   * 	Transition.target(t, trg);
+   * }
+   * 
+ * + * @see Match + * @see Transition + * + */ + public static class Matcher extends BaseMatcher { + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + public static Transition.Matcher on(final ViatraQueryEngine engine) { + // check if matcher already exists + Matcher matcher = engine.getExistingMatcher(querySpecification()); + if (matcher == null) { + matcher = (Matcher)engine.getMatcher(querySpecification()); + } + return matcher; + } + + /** + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * @return an initialized matcher + * @noreference This method is for internal matcher initialization by the framework, do not call it manually. + * + */ + public static Transition.Matcher create() { + return new Matcher(); + } + + private final static int POSITION_T = 0; + + private final static int POSITION_SRC = 1; + + private final static int POSITION_TRG = 2; + + private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(Transition.Matcher.class); + + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + private Matcher() { + super(querySpecification()); + } + + /** + * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pSrc the fixed value of pattern parameter src, or null if not bound. + * @param pTrg the fixed value of pattern parameter trg, or null if not bound. + * @return matches represented as a Match object. + * + */ + public Collection getAllMatches(final ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition pT, final Vertex pSrc, final Vertex pTrg) { + return rawStreamAllMatches(new Object[]{pT, pSrc, pTrg}).collect(Collectors.toSet()); + } + + /** + * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pSrc the fixed value of pattern parameter src, or null if not bound. + * @param pTrg the fixed value of pattern parameter trg, or null if not bound. + * @return a stream of matches represented as a Match object. + * + */ + public Stream streamAllMatches(final ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition pT, final Vertex pSrc, final Vertex pTrg) { + return rawStreamAllMatches(new Object[]{pT, pSrc, pTrg}); + } + + /** + * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pSrc the fixed value of pattern parameter src, or null if not bound. + * @param pTrg the fixed value of pattern parameter trg, or null if not bound. + * @return a match represented as a Match object, or null if no match is found. + * + */ + public Optional getOneArbitraryMatch(final ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition pT, final Vertex pSrc, final Vertex pTrg) { + return rawGetOneArbitraryMatch(new Object[]{pT, pSrc, pTrg}); + } + + /** + * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, + * under any possible substitution of the unspecified parameters (if any). + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pSrc the fixed value of pattern parameter src, or null if not bound. + * @param pTrg the fixed value of pattern parameter trg, or null if not bound. + * @return true if the input is a valid (partial) match of the pattern. + * + */ + public boolean hasMatch(final ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition pT, final Vertex pSrc, final Vertex pTrg) { + return rawHasMatch(new Object[]{pT, pSrc, pTrg}); + } + + /** + * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pSrc the fixed value of pattern parameter src, or null if not bound. + * @param pTrg the fixed value of pattern parameter trg, or null if not bound. + * @return the number of pattern matches found. + * + */ + public int countMatches(final ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition pT, final Vertex pSrc, final Vertex pTrg) { + return rawCountMatches(new Object[]{pT, pSrc, pTrg}); + } + + /** + * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pSrc the fixed value of pattern parameter src, or null if not bound. + * @param pTrg the fixed value of pattern parameter trg, or null if not bound. + * @param processor the action that will process the selected match. + * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked + * + */ + public boolean forOneArbitraryMatch(final ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition pT, final Vertex pSrc, final Vertex pTrg, final Consumer processor) { + return rawForOneArbitraryMatch(new Object[]{pT, pSrc, pTrg}, processor); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pT the fixed value of pattern parameter t, or null if not bound. + * @param pSrc the fixed value of pattern parameter src, or null if not bound. + * @param pTrg the fixed value of pattern parameter trg, or null if not bound. + * @return the (partial) match object. + * + */ + public Transition.Match newMatch(final ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition pT, final Vertex pSrc, final Vertex pTrg) { + return Transition.Match.newMatch(pT, pSrc, pTrg); + } + + /** + * Retrieve the set of values that occur in matches for t. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOft(final Object[] parameters) { + return rawStreamAllValues(POSITION_T, parameters).map(ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for t. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOft() { + return rawStreamAllValuesOft(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for t. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOft() { + return rawStreamAllValuesOft(emptyArray()); + } + + /** + * Retrieve the set of values that occur in matches for t. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOft(final Transition.Match partialMatch) { + return rawStreamAllValuesOft(partialMatch.toArray()); + } + + /** + * Retrieve the set of values that occur in matches for t. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOft(final Vertex pSrc, final Vertex pTrg) { + return rawStreamAllValuesOft(new Object[]{null, pSrc, pTrg}); + } + + /** + * Retrieve the set of values that occur in matches for t. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOft(final Transition.Match partialMatch) { + return rawStreamAllValuesOft(partialMatch.toArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for t. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOft(final Vertex pSrc, final Vertex pTrg) { + return rawStreamAllValuesOft(new Object[]{null, pSrc, pTrg}).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for src. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfsrc(final Object[] parameters) { + return rawStreamAllValues(POSITION_SRC, parameters).map(Vertex.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for src. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfsrc() { + return rawStreamAllValuesOfsrc(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for src. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfsrc() { + return rawStreamAllValuesOfsrc(emptyArray()); + } + + /** + * Retrieve the set of values that occur in matches for src. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfsrc(final Transition.Match partialMatch) { + return rawStreamAllValuesOfsrc(partialMatch.toArray()); + } + + /** + * Retrieve the set of values that occur in matches for src. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfsrc(final ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition pT, final Vertex pTrg) { + return rawStreamAllValuesOfsrc(new Object[]{pT, null, pTrg}); + } + + /** + * Retrieve the set of values that occur in matches for src. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfsrc(final Transition.Match partialMatch) { + return rawStreamAllValuesOfsrc(partialMatch.toArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for src. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfsrc(final ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition pT, final Vertex pTrg) { + return rawStreamAllValuesOfsrc(new Object[]{pT, null, pTrg}).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for trg. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOftrg(final Object[] parameters) { + return rawStreamAllValues(POSITION_TRG, parameters).map(Vertex.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for trg. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOftrg() { + return rawStreamAllValuesOftrg(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for trg. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOftrg() { + return rawStreamAllValuesOftrg(emptyArray()); + } + + /** + * Retrieve the set of values that occur in matches for trg. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOftrg(final Transition.Match partialMatch) { + return rawStreamAllValuesOftrg(partialMatch.toArray()); + } + + /** + * Retrieve the set of values that occur in matches for trg. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOftrg(final ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition pT, final Vertex pSrc) { + return rawStreamAllValuesOftrg(new Object[]{pT, pSrc, null}); + } + + /** + * Retrieve the set of values that occur in matches for trg. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOftrg(final Transition.Match partialMatch) { + return rawStreamAllValuesOftrg(partialMatch.toArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for trg. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOftrg(final ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition pT, final Vertex pSrc) { + return rawStreamAllValuesOftrg(new Object[]{pT, pSrc, null}).collect(Collectors.toSet()); + } + + @Override + protected Transition.Match tupleToMatch(final Tuple t) { + try { + 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)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected Transition.Match arrayToMatch(final Object[] match) { + try { + return Transition.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition) match[POSITION_T], (Vertex) match[POSITION_SRC], (Vertex) match[POSITION_TRG]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected Transition.Match arrayToMatchMutable(final Object[] match) { + try { + return Transition.Match.newMutableMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition) match[POSITION_T], (Vertex) match[POSITION_SRC], (Vertex) match[POSITION_TRG]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + /** + * @return the singleton instance of the query specification of this pattern + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static IQuerySpecification querySpecification() { + return Transition.instance(); + } + } + + private Transition() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static Transition instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected Transition.Matcher instantiate(final ViatraQueryEngine engine) { + return Transition.Matcher.on(engine); + } + + @Override + public Transition.Matcher instantiate() { + return Transition.Matcher.create(); + } + + @Override + public Transition.Match newEmptyMatch() { + return Transition.Match.newEmptyMatch(); + } + + @Override + public Transition.Match newMatch(final Object... parameters) { + 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]); + } + + /** + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created + * not at the class load time of the outer class, + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private final static Transition INSTANCE = new Transition(); + + /** + * Statically initializes the query specification after the field {@link #INSTANCE} is assigned. + * This initialization order is required to support indirect recursion. + * + *

The static initializer is defined using a helper field to work around limitations of the code generator. + * + */ + private final static Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private final static Transition.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_t = new PParameter("t", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Transition", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Transition")), PParameterDirection.INOUT); + + private final PParameter parameter_src = new PParameter("src", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Vertex")), PParameterDirection.INOUT); + + private final PParameter parameter_trg = new PParameter("trg", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Vertex", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Vertex")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_t, parameter_src, parameter_trg); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.transition"; + } + + @Override + public List getParameterNames() { + return Arrays.asList("t","src","trg"); + } + + @Override + public List getParameters() { + return parameters; + } + + @Override + public Set doGetContainedBodies() { + setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); + Set bodies = new LinkedHashSet<>(); + { + PBody body = new PBody(this); + PVariable var_t = body.getOrCreateVariableByName("t"); + PVariable var_src = body.getOrCreateVariableByName("src"); + PVariable var_trg = body.getOrCreateVariableByName("trg"); + new TypeConstraint(body, Tuples.flatTupleOf(var_t), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_src), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_trg), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_t, parameter_t), + new ExportedParameter(body, var_src, parameter_src), + new ExportedParameter(body, var_trg, parameter_trg) + )); + // Transition.source(t, src) + new TypeConstraint(body, Tuples.flatTupleOf(var_t), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); + PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_t, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Transition", "source"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); + new Equality(body, var__virtual_0_, var_src); + // Transition.target(t, trg) + new TypeConstraint(body, Tuples.flatTupleOf(var_t), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Transition"))); + PVariable var__virtual_1_ = body.getOrCreateVariableByName(".virtual{1}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_t, var__virtual_1_), new EStructuralFeatureInstancesKey(getFeatureLiteral("YakinduMetamodel", "Transition", "target"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_1_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Vertex"))); + new Equality(body, var__virtual_1_, var_trg); + bodies.add(body); + } + return bodies; + } + } +} 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 @@ +/** + * Generated from platform:/resource/ca.mcgill.ecse.dslreasoner.standalone.test/queries/ca/mcgill/ecse/dslreasoner/standalone/test/yakindu/queries/yakinduPatterns.vql + */ +package ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries; + +import ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.log4j.Logger; +import org.eclipse.emf.ecore.EClass; +import org.eclipse.viatra.query.runtime.api.IPatternMatch; +import org.eclipse.viatra.query.runtime.api.IQuerySpecification; +import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFPQuery; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedEMFQuerySpecification; +import org.eclipse.viatra.query.runtime.api.impl.BaseMatcher; +import org.eclipse.viatra.query.runtime.api.impl.BasePatternMatch; +import org.eclipse.viatra.query.runtime.emf.types.EClassTransitiveInstancesKey; +import org.eclipse.viatra.query.runtime.matchers.backend.QueryEvaluationHint; +import org.eclipse.viatra.query.runtime.matchers.psystem.PBody; +import org.eclipse.viatra.query.runtime.matchers.psystem.PVariable; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.PAnnotation; +import org.eclipse.viatra.query.runtime.matchers.psystem.annotations.ParameterReference; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.Inequality; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.TypeConstraint; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PParameterDirection; +import org.eclipse.viatra.query.runtime.matchers.psystem.queries.PVisibility; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuple; +import org.eclipse.viatra.query.runtime.matchers.tuple.Tuples; +import org.eclipse.viatra.query.runtime.util.ViatraQueryLoggingUtil; + +/** + * A pattern-specific query specification that can instantiate Matcher in a type-safe way. + * + *

Original source: + *

+ *         Simplifying model generation
+ *          
+ *         {@literal @}Constraint(severity="error", message="error", key = {s1,s2})
+ *         pattern twoSynch(s1 : Synchronization, s2 : Synchronization) {
+ *         	Synchronization(s1);
+ *         	Synchronization(s2);
+ *         	s1 != s2;
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class TwoSynch extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.twoSynch pattern, + * to be used in conjunction with {@link Matcher}. + * + *

Class fields correspond to parameters of the pattern. Fields with value null are considered unassigned. + * Each instance is a (possibly partial) substitution of pattern parameters, + * usable to represent a match of the pattern in the result of a query, + * or to specify the bound (fixed) input parameters when issuing a query. + * + * @see Matcher + * + */ + public static abstract class Match extends BasePatternMatch { + private Synchronization fS1; + + private Synchronization fS2; + + private static List parameterNames = makeImmutableList("s1", "s2"); + + private Match(final Synchronization pS1, final Synchronization pS2) { + this.fS1 = pS1; + this.fS2 = pS2; + } + + @Override + public Object get(final String parameterName) { + if ("s1".equals(parameterName)) return this.fS1; + if ("s2".equals(parameterName)) return this.fS2; + return null; + } + + public Synchronization getS1() { + return this.fS1; + } + + public Synchronization getS2() { + return this.fS2; + } + + @Override + public boolean set(final String parameterName, final Object newValue) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + if ("s1".equals(parameterName) ) { + this.fS1 = (Synchronization) newValue; + return true; + } + if ("s2".equals(parameterName) ) { + this.fS2 = (Synchronization) newValue; + return true; + } + return false; + } + + public void setS1(final Synchronization pS1) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fS1 = pS1; + } + + public void setS2(final Synchronization pS2) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fS2 = pS2; + } + + @Override + public String patternName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.twoSynch"; + } + + @Override + public List parameterNames() { + return TwoSynch.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fS1, fS2}; + } + + @Override + public TwoSynch.Match toImmutable() { + return isMutable() ? newMatch(fS1, fS2) : this; + } + + @Override + public String prettyPrint() { + StringBuilder result = new StringBuilder(); + result.append("\"s1\"=" + prettyPrintValue(fS1) + ", "); + result.append("\"s2\"=" + prettyPrintValue(fS2)); + return result.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(fS1, fS2); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) { + return false; + } + if ((obj instanceof TwoSynch.Match)) { + TwoSynch.Match other = (TwoSynch.Match) obj; + return Objects.equals(fS1, other.fS1) && Objects.equals(fS2, other.fS2); + } else { + // this should be infrequent + if (!(obj instanceof IPatternMatch)) { + return false; + } + IPatternMatch otherSig = (IPatternMatch) obj; + return Objects.equals(specification(), otherSig.specification()) && Arrays.deepEquals(toArray(), otherSig.toArray()); + } + } + + @Override + public TwoSynch specification() { + return TwoSynch.instance(); + } + + /** + * Returns an empty, mutable match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @return the empty match. + * + */ + public static TwoSynch.Match newEmptyMatch() { + return new Mutable(null, null); + } + + /** + * Returns a mutable (partial) match. + * Fields of the mutable match can be filled to create a partial match, usable as matcher input. + * + * @param pS1 the fixed value of pattern parameter s1, or null if not bound. + * @param pS2 the fixed value of pattern parameter s2, or null if not bound. + * @return the new, mutable (partial) match object. + * + */ + public static TwoSynch.Match newMutableMatch(final Synchronization pS1, final Synchronization pS2) { + return new Mutable(pS1, pS2); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pS1 the fixed value of pattern parameter s1, or null if not bound. + * @param pS2 the fixed value of pattern parameter s2, or null if not bound. + * @return the (partial) match object. + * + */ + public static TwoSynch.Match newMatch(final Synchronization pS1, final Synchronization pS2) { + return new Immutable(pS1, pS2); + } + + private static final class Mutable extends TwoSynch.Match { + Mutable(final Synchronization pS1, final Synchronization pS2) { + super(pS1, pS2); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends TwoSynch.Match { + Immutable(final Synchronization pS1, final Synchronization pS2) { + super(pS1, pS2); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.twoSynch pattern, + * providing pattern-specific query methods. + * + *

Use the pattern matcher on a given model via {@link #on(ViatraQueryEngine)}, + * e.g. in conjunction with {@link ViatraQueryEngine#on(QueryScope)}. + * + *

Matches of the pattern will be represented as {@link Match}. + * + *

Original source: + *

+   * Simplifying model generation
+   *  
+   * {@literal @}Constraint(severity="error", message="error", key = {s1,s2})
+   * pattern twoSynch(s1 : Synchronization, s2 : Synchronization) {
+   * 	Synchronization(s1);
+   * 	Synchronization(s2);
+   * 	s1 != s2;
+   * }
+   * 
+ * + * @see Match + * @see TwoSynch + * + */ + public static class Matcher extends BaseMatcher { + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + public static TwoSynch.Matcher on(final ViatraQueryEngine engine) { + // check if matcher already exists + Matcher matcher = engine.getExistingMatcher(querySpecification()); + if (matcher == null) { + matcher = (Matcher)engine.getMatcher(querySpecification()); + } + return matcher; + } + + /** + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * @return an initialized matcher + * @noreference This method is for internal matcher initialization by the framework, do not call it manually. + * + */ + public static TwoSynch.Matcher create() { + return new Matcher(); + } + + private final static int POSITION_S1 = 0; + + private final static int POSITION_S2 = 1; + + private final static Logger LOGGER = ViatraQueryLoggingUtil.getLogger(TwoSynch.Matcher.class); + + /** + * Initializes the pattern matcher within an existing VIATRA Query engine. + * If the pattern matcher is already constructed in the engine, only a light-weight reference is returned. + * + * @param engine the existing VIATRA Query engine in which this matcher will be created. + * @throws ViatraQueryRuntimeException if an error occurs during pattern matcher creation + * + */ + private Matcher() { + super(querySpecification()); + } + + /** + * Returns the set of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pS1 the fixed value of pattern parameter s1, or null if not bound. + * @param pS2 the fixed value of pattern parameter s2, or null if not bound. + * @return matches represented as a Match object. + * + */ + public Collection getAllMatches(final Synchronization pS1, final Synchronization pS2) { + return rawStreamAllMatches(new Object[]{pS1, pS2}).collect(Collectors.toSet()); + } + + /** + * Returns a stream of all matches of the pattern that conform to the given fixed values of some parameters. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * @param pS1 the fixed value of pattern parameter s1, or null if not bound. + * @param pS2 the fixed value of pattern parameter s2, or null if not bound. + * @return a stream of matches represented as a Match object. + * + */ + public Stream streamAllMatches(final Synchronization pS1, final Synchronization pS2) { + return rawStreamAllMatches(new Object[]{pS1, pS2}); + } + + /** + * Returns an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pS1 the fixed value of pattern parameter s1, or null if not bound. + * @param pS2 the fixed value of pattern parameter s2, or null if not bound. + * @return a match represented as a Match object, or null if no match is found. + * + */ + public Optional getOneArbitraryMatch(final Synchronization pS1, final Synchronization pS2) { + return rawGetOneArbitraryMatch(new Object[]{pS1, pS2}); + } + + /** + * Indicates whether the given combination of specified pattern parameters constitute a valid pattern match, + * under any possible substitution of the unspecified parameters (if any). + * @param pS1 the fixed value of pattern parameter s1, or null if not bound. + * @param pS2 the fixed value of pattern parameter s2, or null if not bound. + * @return true if the input is a valid (partial) match of the pattern. + * + */ + public boolean hasMatch(final Synchronization pS1, final Synchronization pS2) { + return rawHasMatch(new Object[]{pS1, pS2}); + } + + /** + * Returns the number of all matches of the pattern that conform to the given fixed values of some parameters. + * @param pS1 the fixed value of pattern parameter s1, or null if not bound. + * @param pS2 the fixed value of pattern parameter s2, or null if not bound. + * @return the number of pattern matches found. + * + */ + public int countMatches(final Synchronization pS1, final Synchronization pS2) { + return rawCountMatches(new Object[]{pS1, pS2}); + } + + /** + * Executes the given processor on an arbitrarily chosen match of the pattern that conforms to the given fixed values of some parameters. + * Neither determinism nor randomness of selection is guaranteed. + * @param pS1 the fixed value of pattern parameter s1, or null if not bound. + * @param pS2 the fixed value of pattern parameter s2, or null if not bound. + * @param processor the action that will process the selected match. + * @return true if the pattern has at least one match with the given parameter values, false if the processor was not invoked + * + */ + public boolean forOneArbitraryMatch(final Synchronization pS1, final Synchronization pS2, final Consumer processor) { + return rawForOneArbitraryMatch(new Object[]{pS1, pS2}, processor); + } + + /** + * Returns a new (partial) match. + * This can be used e.g. to call the matcher with a partial match. + *

The returned match will be immutable. Use {@link #newEmptyMatch()} to obtain a mutable match object. + * @param pS1 the fixed value of pattern parameter s1, or null if not bound. + * @param pS2 the fixed value of pattern parameter s2, or null if not bound. + * @return the (partial) match object. + * + */ + public TwoSynch.Match newMatch(final Synchronization pS1, final Synchronization pS2) { + return TwoSynch.Match.newMatch(pS1, pS2); + } + + /** + * Retrieve the set of values that occur in matches for s1. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfs1(final Object[] parameters) { + return rawStreamAllValues(POSITION_S1, parameters).map(Synchronization.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for s1. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfs1() { + return rawStreamAllValuesOfs1(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for s1. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfs1() { + return rawStreamAllValuesOfs1(emptyArray()); + } + + /** + * Retrieve the set of values that occur in matches for s1. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfs1(final TwoSynch.Match partialMatch) { + return rawStreamAllValuesOfs1(partialMatch.toArray()); + } + + /** + * Retrieve the set of values that occur in matches for s1. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfs1(final Synchronization pS2) { + return rawStreamAllValuesOfs1(new Object[]{null, pS2}); + } + + /** + * Retrieve the set of values that occur in matches for s1. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfs1(final TwoSynch.Match partialMatch) { + return rawStreamAllValuesOfs1(partialMatch.toArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for s1. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfs1(final Synchronization pS2) { + return rawStreamAllValuesOfs1(new Object[]{null, pS2}).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for s2. + * @return the Set of all values or empty set if there are no matches + * + */ + protected Stream rawStreamAllValuesOfs2(final Object[] parameters) { + return rawStreamAllValues(POSITION_S2, parameters).map(Synchronization.class::cast); + } + + /** + * Retrieve the set of values that occur in matches for s2. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfs2() { + return rawStreamAllValuesOfs2(emptyArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for s2. + * @return the Set of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfs2() { + return rawStreamAllValuesOfs2(emptyArray()); + } + + /** + * Retrieve the set of values that occur in matches for s2. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfs2(final TwoSynch.Match partialMatch) { + return rawStreamAllValuesOfs2(partialMatch.toArray()); + } + + /** + * Retrieve the set of values that occur in matches for s2. + *

+ * NOTE: It is important not to modify the source model while the stream is being processed. + * If the match set of the pattern changes during processing, the contents of the stream is undefined. + * In such cases, either rely on {@link #getAllMatches()} or collect the results of the stream in end-user code. + * + * @return the Stream of all values or empty set if there are no matches + * + */ + public Stream streamAllValuesOfs2(final Synchronization pS1) { + return rawStreamAllValuesOfs2(new Object[]{pS1, null}); + } + + /** + * Retrieve the set of values that occur in matches for s2. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfs2(final TwoSynch.Match partialMatch) { + return rawStreamAllValuesOfs2(partialMatch.toArray()).collect(Collectors.toSet()); + } + + /** + * Retrieve the set of values that occur in matches for s2. + * @return the Set of all values or empty set if there are no matches + * + */ + public Set getAllValuesOfs2(final Synchronization pS1) { + return rawStreamAllValuesOfs2(new Object[]{pS1, null}).collect(Collectors.toSet()); + } + + @Override + protected TwoSynch.Match tupleToMatch(final Tuple t) { + try { + return TwoSynch.Match.newMatch((Synchronization) t.get(POSITION_S1), (Synchronization) t.get(POSITION_S2)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected TwoSynch.Match arrayToMatch(final Object[] match) { + try { + return TwoSynch.Match.newMatch((Synchronization) match[POSITION_S1], (Synchronization) match[POSITION_S2]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected TwoSynch.Match arrayToMatchMutable(final Object[] match) { + try { + return TwoSynch.Match.newMutableMatch((Synchronization) match[POSITION_S1], (Synchronization) match[POSITION_S2]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + /** + * @return the singleton instance of the query specification of this pattern + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static IQuerySpecification querySpecification() { + return TwoSynch.instance(); + } + } + + private TwoSynch() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static TwoSynch instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected TwoSynch.Matcher instantiate(final ViatraQueryEngine engine) { + return TwoSynch.Matcher.on(engine); + } + + @Override + public TwoSynch.Matcher instantiate() { + return TwoSynch.Matcher.create(); + } + + @Override + public TwoSynch.Match newEmptyMatch() { + return TwoSynch.Match.newEmptyMatch(); + } + + @Override + public TwoSynch.Match newMatch(final Object... parameters) { + return TwoSynch.Match.newMatch((ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization) parameters[0], (ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization) parameters[1]); + } + + /** + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)} to be created + * not at the class load time of the outer class, + * 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: ) (abstract: false, static: false, final: true, packageName: ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries) (interface: false, strictFloatingPoint: false, anonymous: false)#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private final static TwoSynch INSTANCE = new TwoSynch(); + + /** + * Statically initializes the query specification after the field {@link #INSTANCE} is assigned. + * This initialization order is required to support indirect recursion. + * + *

The static initializer is defined using a helper field to work around limitations of the code generator. + * + */ + private final static Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private final static TwoSynch.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_s1 = new PParameter("s1", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Synchronization")), PParameterDirection.INOUT); + + private final PParameter parameter_s2 = new PParameter("s2", "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.Synchronization", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("YakinduMetamodel", "Synchronization")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_s1, parameter_s2); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "ca.mcgill.ecse.dslreasoner.standalone.test.yakindu.queries.twoSynch"; + } + + @Override + public List getParameterNames() { + return Arrays.asList("s1","s2"); + } + + @Override + public List getParameters() { + return parameters; + } + + @Override + public Set doGetContainedBodies() { + setEvaluationHints(new QueryEvaluationHint(null, QueryEvaluationHint.BackendRequirement.UNSPECIFIED)); + Set bodies = new LinkedHashSet<>(); + { + PBody body = new PBody(this); + PVariable var_s1 = body.getOrCreateVariableByName("s1"); + PVariable var_s2 = body.getOrCreateVariableByName("s2"); + new TypeConstraint(body, Tuples.flatTupleOf(var_s1), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Synchronization"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_s2), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Synchronization"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_s1, parameter_s1), + new ExportedParameter(body, var_s2, parameter_s2) + )); + // Synchronization(s1) + new TypeConstraint(body, Tuples.flatTupleOf(var_s1), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Synchronization"))); + // Synchronization(s2) + new TypeConstraint(body, Tuples.flatTupleOf(var_s2), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("YakinduMetamodel", "Synchronization"))); + // s1 != s2 + new Inequality(body, var_s1, var_s2); + bodies.add(body); + } + { + PAnnotation annotation = new PAnnotation("Constraint"); + annotation.addAttribute("severity", "error"); + annotation.addAttribute("message", "error"); + annotation.addAttribute("key", Arrays.asList(new Object[] { + new ParameterReference("s1"), + new ParameterReference("s2") + })); + addAnnotation(annotation); + } + return bodies; + } + } +} -- cgit v1.2.3-54-g00ecf