From a620f07468780778bd55dcffc30245def37ece69 Mon Sep 17 00:00:00 2001 From: Kristóf Marussy Date: Thu, 6 Aug 2020 16:07:16 +0200 Subject: MoDeS3 unit propagation WIP --- .../vql-gen/modes3/queries/.gitignore | 26 + .../vql-gen/modes3/queries/Adjacent.java | 719 ++++++++++++++++++++ .../vql-gen/modes3/queries/ConnectedTo.java | 704 ++++++++++++++++++++ .../modes3/queries/ConnectedToNotSymmetric.java | 724 ++++++++++++++++++++ .../modes3/queries/ConnectedToReflexive.java | 563 ++++++++++++++++ .../modes3/queries/ExtraInputOfTurnout.java | 730 +++++++++++++++++++++ .../vql-gen/modes3/queries/Modes3Queries.java | 229 +++++++ .../modes3/queries/NoExtraInputOfTurnout.java | 560 ++++++++++++++++ .../vql-gen/modes3/queries/Output.java | 724 ++++++++++++++++++++ .../vql-gen/modes3/queries/OutputReflexive.java | 559 ++++++++++++++++ .../vql-gen/modes3/queries/Reachable.java | 719 ++++++++++++++++++++ .../queries/TooManyExtraInputsOfTurnout.java | 570 ++++++++++++++++ .../modes3/queries/TooManyInputsOfSegment.java | 601 +++++++++++++++++ .../vql-gen/modes3/queries/Turnout.java | 543 +++++++++++++++ .../queries/TurnoutConnectedToBothOutputs.java | 589 +++++++++++++++++ .../vql-gen/modes3/queries/TurnoutInSegments.java | 564 ++++++++++++++++ .../vql-gen/modes3/queries/TurnoutOutput.java | 727 ++++++++++++++++++++ .../modes3/queries/TurnoutOutputsAreSame.java | 572 ++++++++++++++++ .../vql-gen/modes3/queries/Unreachable.java | 714 ++++++++++++++++++++ 19 files changed, 11137 insertions(+) create mode 100644 Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/.gitignore create mode 100644 Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/Adjacent.java create mode 100644 Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/ConnectedTo.java create mode 100644 Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/ConnectedToNotSymmetric.java create mode 100644 Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/ConnectedToReflexive.java create mode 100644 Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/ExtraInputOfTurnout.java create mode 100644 Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/Modes3Queries.java create mode 100644 Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/NoExtraInputOfTurnout.java create mode 100644 Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/Output.java create mode 100644 Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/OutputReflexive.java create mode 100644 Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/Reachable.java create mode 100644 Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/TooManyExtraInputsOfTurnout.java create mode 100644 Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/TooManyInputsOfSegment.java create mode 100644 Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/Turnout.java create mode 100644 Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/TurnoutConnectedToBothOutputs.java create mode 100644 Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/TurnoutInSegments.java create mode 100644 Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/TurnoutOutput.java create mode 100644 Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/TurnoutOutputsAreSame.java create mode 100644 Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/Unreachable.java (limited to 'Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3') diff --git a/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/.gitignore b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/.gitignore new file mode 100644 index 00000000..e3a0ad7e --- /dev/null +++ b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/.gitignore @@ -0,0 +1,26 @@ +/.ConnectedToReflexive.java._trace +/.Modes3Queries.java._trace +/.StraightReflexive.java._trace +/.DivergentReflexive.java._trace +/.TurnoutOutputsAreSame.java._trace +/.Adjacent.java._trace +/.Output.java._trace +/.OutputReflexive.java._trace +/.TooManyAdjacentSegmentsOfSegment.java._trace +/.Turnout.java._trace +/.ConnectedTo.java._trace +/.TurnoutNotConnectedToOutput.java._trace +/.DisjointNetwork.java._trace +/.Reachable.java._trace +/.Unreachable.java._trace +/.TurnoutInSegments.java._trace +/.ConnectedToNotSymmetric.java._trace +/.TurnoutConnectedToBothOutputs.java._trace +/.TooManyAdjacentTurnouts.java._trace +/.NoAdjacentSegmentOfSegment.java._trace +/.TurnoutOutput.java._trace +/.NoInputOfSegment.java._trace +/.TooManyInputsOfSegment.java._trace +/.ExtraInputOfTurnout.java._trace +/.NoExtraInputOfTurnout.java._trace +/.TooManyExtraInputsOfTurnout.java._trace diff --git a/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/Adjacent.java b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/Adjacent.java new file mode 100644 index 00000000..e87f9c18 --- /dev/null +++ b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/Adjacent.java @@ -0,0 +1,719 @@ +/** + * Generated from platform:/resource/ca.mcgill.rtgmrt.example.modes3/src/modes3/queries/Modes3Queries.vql + */ +package modes3.queries; + +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 modes3.Segment; +import modes3.queries.Output; +import modes3.queries.TurnoutOutput; +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.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 adjacent(S1 : Segment, S2 : Segment) {
+ *         	find output(S1, S2);
+ *         } or {
+ *         	find turnoutOutput(S2, S1);
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class Adjacent extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the modes3.queries.adjacent 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 Segment fS1; + + private Segment fS2; + + private static List parameterNames = makeImmutableList("S1", "S2"); + + private Match(final Segment pS1, final Segment pS2) { + this.fS1 = pS1; + this.fS2 = pS2; + } + + @Override + public Object get(final String parameterName) { + switch(parameterName) { + case "S1": return this.fS1; + case "S2": return this.fS2; + default: return null; + } + } + + @Override + public Object get(final int index) { + switch(index) { + case 0: return this.fS1; + case 1: return this.fS2; + default: return null; + } + } + + public Segment getS1() { + return this.fS1; + } + + public Segment 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 = (Segment) newValue; + return true; + } + if ("S2".equals(parameterName) ) { + this.fS2 = (Segment) newValue; + return true; + } + return false; + } + + public void setS1(final Segment pS1) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fS1 = pS1; + } + + public void setS2(final Segment pS2) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fS2 = pS2; + } + + @Override + public String patternName() { + return "modes3.queries.adjacent"; + } + + @Override + public List parameterNames() { + return Adjacent.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fS1, fS2}; + } + + @Override + public Adjacent.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 Adjacent.Match)) { + Adjacent.Match other = (Adjacent.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 Adjacent specification() { + return Adjacent.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 Adjacent.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 Adjacent.Match newMutableMatch(final Segment pS1, final Segment 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 Adjacent.Match newMatch(final Segment pS1, final Segment pS2) { + return new Immutable(pS1, pS2); + } + + private static final class Mutable extends Adjacent.Match { + Mutable(final Segment pS1, final Segment pS2) { + super(pS1, pS2); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends Adjacent.Match { + Immutable(final Segment pS1, final Segment pS2) { + super(pS1, pS2); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the modes3.queries.adjacent 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 adjacent(S1 : Segment, S2 : Segment) {
+   * 	find output(S1, S2);
+   * } or {
+   * 	find turnoutOutput(S2, S1);
+   * }
+   * 
+ * + * @see Match + * @see Adjacent + * + */ + 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 Adjacent.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 Adjacent.Matcher create() { + return new Matcher(); + } + + private static final int POSITION_S1 = 0; + + private static final int POSITION_S2 = 1; + + private static final Logger LOGGER = ViatraQueryLoggingUtil.getLogger(Adjacent.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 Segment pS1, final Segment 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 Segment pS1, final Segment 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 Segment pS1, final Segment 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 Segment pS1, final Segment 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 Segment pS1, final Segment 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 Segment pS1, final Segment 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 Adjacent.Match newMatch(final Segment pS1, final Segment pS2) { + return Adjacent.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(Segment.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 Adjacent.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 Segment 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 Adjacent.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 Segment 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(Segment.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 Adjacent.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 Segment 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 Adjacent.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 Segment pS1) { + return rawStreamAllValuesOfS2(new Object[]{pS1, null}).collect(Collectors.toSet()); + } + + @Override + protected Adjacent.Match tupleToMatch(final Tuple t) { + try { + return Adjacent.Match.newMatch((Segment) t.get(POSITION_S1), (Segment) t.get(POSITION_S2)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected Adjacent.Match arrayToMatch(final Object[] match) { + try { + return Adjacent.Match.newMatch((Segment) match[POSITION_S1], (Segment) match[POSITION_S2]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected Adjacent.Match arrayToMatchMutable(final Object[] match) { + try { + return Adjacent.Match.newMutableMatch((Segment) match[POSITION_S1], (Segment) 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 Adjacent.instance(); + } + } + + private Adjacent() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static Adjacent instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected Adjacent.Matcher instantiate(final ViatraQueryEngine engine) { + return Adjacent.Matcher.on(engine); + } + + @Override + public Adjacent.Matcher instantiate() { + return Adjacent.Matcher.create(); + } + + @Override + public Adjacent.Match newEmptyMatch() { + return Adjacent.Match.newEmptyMatch(); + } + + @Override + public Adjacent.Match newMatch(final Object... parameters) { + return Adjacent.Match.newMatch((modes3.Segment) parameters[0], (modes3.Segment) parameters[1]); + } + + /** + * Inner class allowing the singleton instance of {@link Adjacent} to be created + * not at the class load time of the outer class, + * but rather at the first call to {@link Adjacent#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private static final Adjacent INSTANCE = new Adjacent(); + + /** + * 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 static final Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private static final Adjacent.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_S1 = new PParameter("S1", "modes3.Segment", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("http://www.ece.mcgill.ca/wcet/modes3", "Segment")), PParameterDirection.INOUT); + + private final PParameter parameter_S2 = new PParameter("S2", "modes3.Segment", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("http://www.ece.mcgill.ca/wcet/modes3", "Segment")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_S1, parameter_S2); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "modes3.queries.adjacent"; + } + + @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("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_S2), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_S1, parameter_S1), + new ExportedParameter(body, var_S2, parameter_S2) + )); + // find output(S1, S2) + new PositivePatternCall(body, Tuples.flatTupleOf(var_S1, var_S2), Output.instance().getInternalQueryRepresentation()); + bodies.add(body); + } + { + 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("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_S2), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_S1, parameter_S1), + new ExportedParameter(body, var_S2, parameter_S2) + )); + // find turnoutOutput(S2, S1) + new PositivePatternCall(body, Tuples.flatTupleOf(var_S2, var_S1), TurnoutOutput.instance().getInternalQueryRepresentation()); + bodies.add(body); + } + return bodies; + } + } +} diff --git a/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/ConnectedTo.java b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/ConnectedTo.java new file mode 100644 index 00000000..a0f14958 --- /dev/null +++ b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/ConnectedTo.java @@ -0,0 +1,704 @@ +/** + * Generated from platform:/resource/ca.mcgill.rtgmrt.example.modes3/src/modes3/queries/Modes3Queries.vql + */ +package modes3.queries; + +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 modes3.Segment; +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 connectedTo(S1 : Segment, S2 : Segment) {
+ *         	Segment.connectedTo(S1, S2);
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class ConnectedTo extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the modes3.queries.connectedTo 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 Segment fS1; + + private Segment fS2; + + private static List parameterNames = makeImmutableList("S1", "S2"); + + private Match(final Segment pS1, final Segment pS2) { + this.fS1 = pS1; + this.fS2 = pS2; + } + + @Override + public Object get(final String parameterName) { + switch(parameterName) { + case "S1": return this.fS1; + case "S2": return this.fS2; + default: return null; + } + } + + @Override + public Object get(final int index) { + switch(index) { + case 0: return this.fS1; + case 1: return this.fS2; + default: return null; + } + } + + public Segment getS1() { + return this.fS1; + } + + public Segment 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 = (Segment) newValue; + return true; + } + if ("S2".equals(parameterName) ) { + this.fS2 = (Segment) newValue; + return true; + } + return false; + } + + public void setS1(final Segment pS1) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fS1 = pS1; + } + + public void setS2(final Segment pS2) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fS2 = pS2; + } + + @Override + public String patternName() { + return "modes3.queries.connectedTo"; + } + + @Override + public List parameterNames() { + return ConnectedTo.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fS1, fS2}; + } + + @Override + public ConnectedTo.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 ConnectedTo.Match)) { + ConnectedTo.Match other = (ConnectedTo.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 ConnectedTo specification() { + return ConnectedTo.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 ConnectedTo.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 ConnectedTo.Match newMutableMatch(final Segment pS1, final Segment 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 ConnectedTo.Match newMatch(final Segment pS1, final Segment pS2) { + return new Immutable(pS1, pS2); + } + + private static final class Mutable extends ConnectedTo.Match { + Mutable(final Segment pS1, final Segment pS2) { + super(pS1, pS2); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends ConnectedTo.Match { + Immutable(final Segment pS1, final Segment pS2) { + super(pS1, pS2); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the modes3.queries.connectedTo 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 connectedTo(S1 : Segment, S2 : Segment) {
+   * 	Segment.connectedTo(S1, S2);
+   * }
+   * 
+ * + * @see Match + * @see ConnectedTo + * + */ + 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 ConnectedTo.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 ConnectedTo.Matcher create() { + return new Matcher(); + } + + private static final int POSITION_S1 = 0; + + private static final int POSITION_S2 = 1; + + private static final Logger LOGGER = ViatraQueryLoggingUtil.getLogger(ConnectedTo.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 Segment pS1, final Segment 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 Segment pS1, final Segment 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 Segment pS1, final Segment 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 Segment pS1, final Segment 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 Segment pS1, final Segment 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 Segment pS1, final Segment 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 ConnectedTo.Match newMatch(final Segment pS1, final Segment pS2) { + return ConnectedTo.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(Segment.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 ConnectedTo.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 Segment 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 ConnectedTo.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 Segment 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(Segment.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 ConnectedTo.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 Segment 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 ConnectedTo.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 Segment pS1) { + return rawStreamAllValuesOfS2(new Object[]{pS1, null}).collect(Collectors.toSet()); + } + + @Override + protected ConnectedTo.Match tupleToMatch(final Tuple t) { + try { + return ConnectedTo.Match.newMatch((Segment) t.get(POSITION_S1), (Segment) t.get(POSITION_S2)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected ConnectedTo.Match arrayToMatch(final Object[] match) { + try { + return ConnectedTo.Match.newMatch((Segment) match[POSITION_S1], (Segment) match[POSITION_S2]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected ConnectedTo.Match arrayToMatchMutable(final Object[] match) { + try { + return ConnectedTo.Match.newMutableMatch((Segment) match[POSITION_S1], (Segment) 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 ConnectedTo.instance(); + } + } + + private ConnectedTo() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static ConnectedTo instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected ConnectedTo.Matcher instantiate(final ViatraQueryEngine engine) { + return ConnectedTo.Matcher.on(engine); + } + + @Override + public ConnectedTo.Matcher instantiate() { + return ConnectedTo.Matcher.create(); + } + + @Override + public ConnectedTo.Match newEmptyMatch() { + return ConnectedTo.Match.newEmptyMatch(); + } + + @Override + public ConnectedTo.Match newMatch(final Object... parameters) { + return ConnectedTo.Match.newMatch((modes3.Segment) parameters[0], (modes3.Segment) parameters[1]); + } + + /** + * Inner class allowing the singleton instance of {@link ConnectedTo} to be created + * not at the class load time of the outer class, + * but rather at the first call to {@link ConnectedTo#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private static final ConnectedTo INSTANCE = new ConnectedTo(); + + /** + * 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 static final Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private static final ConnectedTo.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_S1 = new PParameter("S1", "modes3.Segment", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("http://www.ece.mcgill.ca/wcet/modes3", "Segment")), PParameterDirection.INOUT); + + private final PParameter parameter_S2 = new PParameter("S2", "modes3.Segment", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("http://www.ece.mcgill.ca/wcet/modes3", "Segment")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_S1, parameter_S2); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "modes3.queries.connectedTo"; + } + + @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("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_S2), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_S1, parameter_S1), + new ExportedParameter(body, var_S2, parameter_S2) + )); + // Segment.connectedTo(S1, S2) + new TypeConstraint(body, Tuples.flatTupleOf(var_S1), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_S1, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment", "connectedTo"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + new Equality(body, var__virtual_0_, var_S2); + bodies.add(body); + } + return bodies; + } + } +} diff --git a/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/ConnectedToNotSymmetric.java b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/ConnectedToNotSymmetric.java new file mode 100644 index 00000000..91b74c7e --- /dev/null +++ b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/ConnectedToNotSymmetric.java @@ -0,0 +1,724 @@ +/** + * Generated from platform:/resource/ca.mcgill.rtgmrt.example.modes3/src/modes3/queries/Modes3Queries.vql + */ +package modes3.queries; + +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 modes3.Segment; +import modes3.queries.ConnectedTo; +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.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(message = "connectedToNotSymmetric", severity = "error", key = { S1, S2 })
+ *         pattern connectedToNotSymmetric(S1 : Segment, S2 : Segment) {
+ *         	Segment.connectedTo(S1, S2);
+ *         	neg find connectedTo(S2, S1);
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class ConnectedToNotSymmetric extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the modes3.queries.connectedToNotSymmetric 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 Segment fS1; + + private Segment fS2; + + private static List parameterNames = makeImmutableList("S1", "S2"); + + private Match(final Segment pS1, final Segment pS2) { + this.fS1 = pS1; + this.fS2 = pS2; + } + + @Override + public Object get(final String parameterName) { + switch(parameterName) { + case "S1": return this.fS1; + case "S2": return this.fS2; + default: return null; + } + } + + @Override + public Object get(final int index) { + switch(index) { + case 0: return this.fS1; + case 1: return this.fS2; + default: return null; + } + } + + public Segment getS1() { + return this.fS1; + } + + public Segment 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 = (Segment) newValue; + return true; + } + if ("S2".equals(parameterName) ) { + this.fS2 = (Segment) newValue; + return true; + } + return false; + } + + public void setS1(final Segment pS1) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fS1 = pS1; + } + + public void setS2(final Segment pS2) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fS2 = pS2; + } + + @Override + public String patternName() { + return "modes3.queries.connectedToNotSymmetric"; + } + + @Override + public List parameterNames() { + return ConnectedToNotSymmetric.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fS1, fS2}; + } + + @Override + public ConnectedToNotSymmetric.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 ConnectedToNotSymmetric.Match)) { + ConnectedToNotSymmetric.Match other = (ConnectedToNotSymmetric.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 ConnectedToNotSymmetric specification() { + return ConnectedToNotSymmetric.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 ConnectedToNotSymmetric.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 ConnectedToNotSymmetric.Match newMutableMatch(final Segment pS1, final Segment 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 ConnectedToNotSymmetric.Match newMatch(final Segment pS1, final Segment pS2) { + return new Immutable(pS1, pS2); + } + + private static final class Mutable extends ConnectedToNotSymmetric.Match { + Mutable(final Segment pS1, final Segment pS2) { + super(pS1, pS2); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends ConnectedToNotSymmetric.Match { + Immutable(final Segment pS1, final Segment pS2) { + super(pS1, pS2); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the modes3.queries.connectedToNotSymmetric 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 = "connectedToNotSymmetric", severity = "error", key = { S1, S2 })
+   * pattern connectedToNotSymmetric(S1 : Segment, S2 : Segment) {
+   * 	Segment.connectedTo(S1, S2);
+   * 	neg find connectedTo(S2, S1);
+   * }
+   * 
+ * + * @see Match + * @see ConnectedToNotSymmetric + * + */ + 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 ConnectedToNotSymmetric.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 ConnectedToNotSymmetric.Matcher create() { + return new Matcher(); + } + + private static final int POSITION_S1 = 0; + + private static final int POSITION_S2 = 1; + + private static final Logger LOGGER = ViatraQueryLoggingUtil.getLogger(ConnectedToNotSymmetric.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 Segment pS1, final Segment 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 Segment pS1, final Segment 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 Segment pS1, final Segment 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 Segment pS1, final Segment 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 Segment pS1, final Segment 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 Segment pS1, final Segment 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 ConnectedToNotSymmetric.Match newMatch(final Segment pS1, final Segment pS2) { + return ConnectedToNotSymmetric.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(Segment.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 ConnectedToNotSymmetric.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 Segment 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 ConnectedToNotSymmetric.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 Segment 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(Segment.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 ConnectedToNotSymmetric.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 Segment 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 ConnectedToNotSymmetric.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 Segment pS1) { + return rawStreamAllValuesOfS2(new Object[]{pS1, null}).collect(Collectors.toSet()); + } + + @Override + protected ConnectedToNotSymmetric.Match tupleToMatch(final Tuple t) { + try { + return ConnectedToNotSymmetric.Match.newMatch((Segment) t.get(POSITION_S1), (Segment) t.get(POSITION_S2)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected ConnectedToNotSymmetric.Match arrayToMatch(final Object[] match) { + try { + return ConnectedToNotSymmetric.Match.newMatch((Segment) match[POSITION_S1], (Segment) match[POSITION_S2]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected ConnectedToNotSymmetric.Match arrayToMatchMutable(final Object[] match) { + try { + return ConnectedToNotSymmetric.Match.newMutableMatch((Segment) match[POSITION_S1], (Segment) 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 ConnectedToNotSymmetric.instance(); + } + } + + private ConnectedToNotSymmetric() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static ConnectedToNotSymmetric instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected ConnectedToNotSymmetric.Matcher instantiate(final ViatraQueryEngine engine) { + return ConnectedToNotSymmetric.Matcher.on(engine); + } + + @Override + public ConnectedToNotSymmetric.Matcher instantiate() { + return ConnectedToNotSymmetric.Matcher.create(); + } + + @Override + public ConnectedToNotSymmetric.Match newEmptyMatch() { + return ConnectedToNotSymmetric.Match.newEmptyMatch(); + } + + @Override + public ConnectedToNotSymmetric.Match newMatch(final Object... parameters) { + return ConnectedToNotSymmetric.Match.newMatch((modes3.Segment) parameters[0], (modes3.Segment) parameters[1]); + } + + /** + * Inner class allowing the singleton instance of {@link ConnectedToNotSymmetric} to be created + * not at the class load time of the outer class, + * but rather at the first call to {@link ConnectedToNotSymmetric#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private static final ConnectedToNotSymmetric INSTANCE = new ConnectedToNotSymmetric(); + + /** + * 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 static final Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private static final ConnectedToNotSymmetric.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_S1 = new PParameter("S1", "modes3.Segment", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("http://www.ece.mcgill.ca/wcet/modes3", "Segment")), PParameterDirection.INOUT); + + private final PParameter parameter_S2 = new PParameter("S2", "modes3.Segment", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("http://www.ece.mcgill.ca/wcet/modes3", "Segment")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_S1, parameter_S2); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "modes3.queries.connectedToNotSymmetric"; + } + + @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("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_S2), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_S1, parameter_S1), + new ExportedParameter(body, var_S2, parameter_S2) + )); + // Segment.connectedTo(S1, S2) + new TypeConstraint(body, Tuples.flatTupleOf(var_S1), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_S1, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment", "connectedTo"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + new Equality(body, var__virtual_0_, var_S2); + // neg find connectedTo(S2, S1) + new NegativePatternCall(body, Tuples.flatTupleOf(var_S2, var_S1), ConnectedTo.instance().getInternalQueryRepresentation()); + bodies.add(body); + } + { + PAnnotation annotation = new PAnnotation("Constraint"); + annotation.addAttribute("message", "connectedToNotSymmetric"); + annotation.addAttribute("severity", "error"); + annotation.addAttribute("key", Arrays.asList(new Object[] { + new ParameterReference("S1"), + new ParameterReference("S2") + })); + addAnnotation(annotation); + } + return bodies; + } + } +} diff --git a/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/ConnectedToReflexive.java b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/ConnectedToReflexive.java new file mode 100644 index 00000000..948fec73 --- /dev/null +++ b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/ConnectedToReflexive.java @@ -0,0 +1,563 @@ +/** + * Generated from platform:/resource/ca.mcgill.rtgmrt.example.modes3/src/modes3/queries/Modes3Queries.vql + */ +package modes3.queries; + +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 modes3.Segment; +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 = "connectedToReflexive", severity = "error", key = { S })
+ *         pattern connectedToReflexive(S : Segment) {
+ *         	Segment.connectedTo(S, S);
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class ConnectedToReflexive extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the modes3.queries.connectedToReflexive 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 Segment fS; + + private static List parameterNames = makeImmutableList("S"); + + private Match(final Segment pS) { + this.fS = pS; + } + + @Override + public Object get(final String parameterName) { + switch(parameterName) { + case "S": return this.fS; + default: return null; + } + } + + @Override + public Object get(final int index) { + switch(index) { + case 0: return this.fS; + default: return null; + } + } + + public Segment 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 = (Segment) newValue; + return true; + } + return false; + } + + public void setS(final Segment pS) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fS = pS; + } + + @Override + public String patternName() { + return "modes3.queries.connectedToReflexive"; + } + + @Override + public List parameterNames() { + return ConnectedToReflexive.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fS}; + } + + @Override + public ConnectedToReflexive.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 ConnectedToReflexive.Match)) { + ConnectedToReflexive.Match other = (ConnectedToReflexive.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 ConnectedToReflexive specification() { + return ConnectedToReflexive.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 ConnectedToReflexive.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 ConnectedToReflexive.Match newMutableMatch(final Segment 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 ConnectedToReflexive.Match newMatch(final Segment pS) { + return new Immutable(pS); + } + + private static final class Mutable extends ConnectedToReflexive.Match { + Mutable(final Segment pS) { + super(pS); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends ConnectedToReflexive.Match { + Immutable(final Segment pS) { + super(pS); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the modes3.queries.connectedToReflexive 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 = "connectedToReflexive", severity = "error", key = { S })
+   * pattern connectedToReflexive(S : Segment) {
+   * 	Segment.connectedTo(S, S);
+   * }
+   * 
+ * + * @see Match + * @see ConnectedToReflexive + * + */ + 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 ConnectedToReflexive.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 ConnectedToReflexive.Matcher create() { + return new Matcher(); + } + + private static final int POSITION_S = 0; + + private static final Logger LOGGER = ViatraQueryLoggingUtil.getLogger(ConnectedToReflexive.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 Segment 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 Segment 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 Segment 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 Segment 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 Segment 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 Segment 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 ConnectedToReflexive.Match newMatch(final Segment pS) { + return ConnectedToReflexive.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(Segment.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 ConnectedToReflexive.Match tupleToMatch(final Tuple t) { + try { + return ConnectedToReflexive.Match.newMatch((Segment) t.get(POSITION_S)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected ConnectedToReflexive.Match arrayToMatch(final Object[] match) { + try { + return ConnectedToReflexive.Match.newMatch((Segment) match[POSITION_S]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected ConnectedToReflexive.Match arrayToMatchMutable(final Object[] match) { + try { + return ConnectedToReflexive.Match.newMutableMatch((Segment) 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 ConnectedToReflexive.instance(); + } + } + + private ConnectedToReflexive() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static ConnectedToReflexive instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected ConnectedToReflexive.Matcher instantiate(final ViatraQueryEngine engine) { + return ConnectedToReflexive.Matcher.on(engine); + } + + @Override + public ConnectedToReflexive.Matcher instantiate() { + return ConnectedToReflexive.Matcher.create(); + } + + @Override + public ConnectedToReflexive.Match newEmptyMatch() { + return ConnectedToReflexive.Match.newEmptyMatch(); + } + + @Override + public ConnectedToReflexive.Match newMatch(final Object... parameters) { + return ConnectedToReflexive.Match.newMatch((modes3.Segment) parameters[0]); + } + + /** + * Inner class allowing the singleton instance of {@link ConnectedToReflexive} to be created + * not at the class load time of the outer class, + * but rather at the first call to {@link ConnectedToReflexive#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private static final ConnectedToReflexive INSTANCE = new ConnectedToReflexive(); + + /** + * 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 static final Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private static final ConnectedToReflexive.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_S = new PParameter("S", "modes3.Segment", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("http://www.ece.mcgill.ca/wcet/modes3", "Segment")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_S); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "modes3.queries.connectedToReflexive"; + } + + @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("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_S, parameter_S) + )); + // Segment.connectedTo(S, S) + new TypeConstraint(body, Tuples.flatTupleOf(var_S), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_S, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment", "connectedTo"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + new Equality(body, var__virtual_0_, var_S); + bodies.add(body); + } + { + PAnnotation annotation = new PAnnotation("Constraint"); + annotation.addAttribute("message", "connectedToReflexive"); + annotation.addAttribute("severity", "error"); + annotation.addAttribute("key", Arrays.asList(new Object[] { + new ParameterReference("S") + })); + addAnnotation(annotation); + } + return bodies; + } + } +} diff --git a/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/ExtraInputOfTurnout.java b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/ExtraInputOfTurnout.java new file mode 100644 index 00000000..62e2a54d --- /dev/null +++ b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/ExtraInputOfTurnout.java @@ -0,0 +1,730 @@ +/** + * Generated from platform:/resource/ca.mcgill.rtgmrt.example.modes3/src/modes3/queries/Modes3Queries.vql + */ +package modes3.queries; + +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 modes3.Segment; +import modes3.Turnout; +import modes3.queries.Output; +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.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 extraInputOfTurnout(T : Turnout, S : Segment) {
+ *         	Turnout.straight(T, Straight);
+ *         	Turnout.divergent(T, Divergent);
+ *         	find output(S, T);
+ *         	S != Straight;
+ *         	S != Divergent;
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class ExtraInputOfTurnout extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the modes3.queries.extraInputOfTurnout 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 Turnout fT; + + private Segment fS; + + private static List parameterNames = makeImmutableList("T", "S"); + + private Match(final Turnout pT, final Segment pS) { + this.fT = pT; + this.fS = pS; + } + + @Override + public Object get(final String parameterName) { + switch(parameterName) { + case "T": return this.fT; + case "S": return this.fS; + default: return null; + } + } + + @Override + public Object get(final int index) { + switch(index) { + case 0: return this.fT; + case 1: return this.fS; + default: return null; + } + } + + public Turnout getT() { + return this.fT; + } + + public Segment getS() { + return this.fS; + } + + @Override + public boolean set(final String parameterName, final Object newValue) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + if ("T".equals(parameterName) ) { + this.fT = (Turnout) newValue; + return true; + } + if ("S".equals(parameterName) ) { + this.fS = (Segment) newValue; + return true; + } + return false; + } + + public void setT(final Turnout pT) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fT = pT; + } + + public void setS(final Segment pS) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fS = pS; + } + + @Override + public String patternName() { + return "modes3.queries.extraInputOfTurnout"; + } + + @Override + public List parameterNames() { + return ExtraInputOfTurnout.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fT, fS}; + } + + @Override + public ExtraInputOfTurnout.Match toImmutable() { + return isMutable() ? newMatch(fT, fS) : this; + } + + @Override + public String prettyPrint() { + StringBuilder result = new StringBuilder(); + result.append("\"T\"=" + prettyPrintValue(fT) + ", "); + result.append("\"S\"=" + prettyPrintValue(fS)); + return result.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(fT, fS); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) { + return false; + } + if ((obj instanceof ExtraInputOfTurnout.Match)) { + ExtraInputOfTurnout.Match other = (ExtraInputOfTurnout.Match) obj; + return Objects.equals(fT, other.fT) && 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 ExtraInputOfTurnout specification() { + return ExtraInputOfTurnout.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 ExtraInputOfTurnout.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 pS the fixed value of pattern parameter S, or null if not bound. + * @return the new, mutable (partial) match object. + * + */ + public static ExtraInputOfTurnout.Match newMutableMatch(final Turnout pT, final Segment pS) { + return new Mutable(pT, 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 pT the fixed value of pattern parameter T, or null if not bound. + * @param pS the fixed value of pattern parameter S, or null if not bound. + * @return the (partial) match object. + * + */ + public static ExtraInputOfTurnout.Match newMatch(final Turnout pT, final Segment pS) { + return new Immutable(pT, pS); + } + + private static final class Mutable extends ExtraInputOfTurnout.Match { + Mutable(final Turnout pT, final Segment pS) { + super(pT, pS); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends ExtraInputOfTurnout.Match { + Immutable(final Turnout pT, final Segment pS) { + super(pT, pS); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the modes3.queries.extraInputOfTurnout 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 extraInputOfTurnout(T : Turnout, S : Segment) {
+   * 	Turnout.straight(T, Straight);
+   * 	Turnout.divergent(T, Divergent);
+   * 	find output(S, T);
+   * 	S != Straight;
+   * 	S != Divergent;
+   * }
+   * 
+ * + * @see Match + * @see ExtraInputOfTurnout + * + */ + 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 ExtraInputOfTurnout.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 ExtraInputOfTurnout.Matcher create() { + return new Matcher(); + } + + private static final int POSITION_T = 0; + + private static final int POSITION_S = 1; + + private static final Logger LOGGER = ViatraQueryLoggingUtil.getLogger(ExtraInputOfTurnout.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 pS the fixed value of pattern parameter S, or null if not bound. + * @return matches represented as a Match object. + * + */ + public Collection getAllMatches(final Turnout pT, final Segment pS) { + return rawStreamAllMatches(new Object[]{pT, 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 pT the fixed value of pattern parameter T, or null if not bound. + * @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 Turnout pT, final Segment pS) { + return rawStreamAllMatches(new Object[]{pT, 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 pT the fixed value of pattern parameter T, or null if not bound. + * @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 Turnout pT, final Segment pS) { + return rawGetOneArbitraryMatch(new Object[]{pT, 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 pT the fixed value of pattern parameter T, or null if not bound. + * @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 Turnout pT, final Segment pS) { + return rawHasMatch(new Object[]{pT, pS}); + } + + /** + * 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 pS the fixed value of pattern parameter S, or null if not bound. + * @return the number of pattern matches found. + * + */ + public int countMatches(final Turnout pT, final Segment pS) { + return rawCountMatches(new Object[]{pT, 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 pT the fixed value of pattern parameter T, or null if not bound. + * @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 Turnout pT, final Segment pS, final Consumer processor) { + return rawForOneArbitraryMatch(new Object[]{pT, 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 pT the fixed value of pattern parameter T, or null if not bound. + * @param pS the fixed value of pattern parameter S, or null if not bound. + * @return the (partial) match object. + * + */ + public ExtraInputOfTurnout.Match newMatch(final Turnout pT, final Segment pS) { + return ExtraInputOfTurnout.Match.newMatch(pT, pS); + } + + /** + * 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(Turnout.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 ExtraInputOfTurnout.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 Segment pS) { + return rawStreamAllValuesOfT(new Object[]{null, pS}); + } + + /** + * 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 ExtraInputOfTurnout.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 Segment pS) { + return rawStreamAllValuesOfT(new Object[]{null, pS}).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 + * + */ + protected Stream rawStreamAllValuesOfS(final Object[] parameters) { + return rawStreamAllValues(POSITION_S, parameters).map(Segment.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 ExtraInputOfTurnout.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 Turnout pT) { + return rawStreamAllValuesOfS(new Object[]{pT, null}); + } + + /** + * 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 ExtraInputOfTurnout.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 Turnout pT) { + return rawStreamAllValuesOfS(new Object[]{pT, null}).collect(Collectors.toSet()); + } + + @Override + protected ExtraInputOfTurnout.Match tupleToMatch(final Tuple t) { + try { + return ExtraInputOfTurnout.Match.newMatch((Turnout) t.get(POSITION_T), (Segment) t.get(POSITION_S)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected ExtraInputOfTurnout.Match arrayToMatch(final Object[] match) { + try { + return ExtraInputOfTurnout.Match.newMatch((Turnout) match[POSITION_T], (Segment) match[POSITION_S]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected ExtraInputOfTurnout.Match arrayToMatchMutable(final Object[] match) { + try { + return ExtraInputOfTurnout.Match.newMutableMatch((Turnout) match[POSITION_T], (Segment) 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 ExtraInputOfTurnout.instance(); + } + } + + private ExtraInputOfTurnout() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static ExtraInputOfTurnout instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected ExtraInputOfTurnout.Matcher instantiate(final ViatraQueryEngine engine) { + return ExtraInputOfTurnout.Matcher.on(engine); + } + + @Override + public ExtraInputOfTurnout.Matcher instantiate() { + return ExtraInputOfTurnout.Matcher.create(); + } + + @Override + public ExtraInputOfTurnout.Match newEmptyMatch() { + return ExtraInputOfTurnout.Match.newEmptyMatch(); + } + + @Override + public ExtraInputOfTurnout.Match newMatch(final Object... parameters) { + return ExtraInputOfTurnout.Match.newMatch((modes3.Turnout) parameters[0], (modes3.Segment) parameters[1]); + } + + /** + * Inner class allowing the singleton instance of {@link ExtraInputOfTurnout} to be created + * not at the class load time of the outer class, + * but rather at the first call to {@link ExtraInputOfTurnout#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private static final ExtraInputOfTurnout INSTANCE = new ExtraInputOfTurnout(); + + /** + * 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 static final Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private static final ExtraInputOfTurnout.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_T = new PParameter("T", "modes3.Turnout", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("http://www.ece.mcgill.ca/wcet/modes3", "Turnout")), PParameterDirection.INOUT); + + private final PParameter parameter_S = new PParameter("S", "modes3.Segment", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("http://www.ece.mcgill.ca/wcet/modes3", "Segment")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_T, parameter_S); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "modes3.queries.extraInputOfTurnout"; + } + + @Override + public List getParameterNames() { + return Arrays.asList("T","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_T = body.getOrCreateVariableByName("T"); + PVariable var_S = body.getOrCreateVariableByName("S"); + PVariable var_Straight = body.getOrCreateVariableByName("Straight"); + PVariable var_Divergent = body.getOrCreateVariableByName("Divergent"); + new TypeConstraint(body, Tuples.flatTupleOf(var_T), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Turnout"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_S), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_T, parameter_T), + new ExportedParameter(body, var_S, parameter_S) + )); + // Turnout.straight(T, Straight) + new TypeConstraint(body, Tuples.flatTupleOf(var_T), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Turnout"))); + PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_T, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Turnout", "straight"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + new Equality(body, var__virtual_0_, var_Straight); + // Turnout.divergent(T, Divergent) + new TypeConstraint(body, Tuples.flatTupleOf(var_T), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Turnout"))); + PVariable var__virtual_1_ = body.getOrCreateVariableByName(".virtual{1}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_T, var__virtual_1_), new EStructuralFeatureInstancesKey(getFeatureLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Turnout", "divergent"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_1_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + new Equality(body, var__virtual_1_, var_Divergent); + // find output(S, T) + new PositivePatternCall(body, Tuples.flatTupleOf(var_S, var_T), Output.instance().getInternalQueryRepresentation()); + // S != Straight + new Inequality(body, var_S, var_Straight); + // S != Divergent + new Inequality(body, var_S, var_Divergent); + bodies.add(body); + } + return bodies; + } + } +} diff --git a/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/Modes3Queries.java b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/Modes3Queries.java new file mode 100644 index 00000000..01ec77a1 --- /dev/null +++ b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/Modes3Queries.java @@ -0,0 +1,229 @@ +/** + * Generated from platform:/resource/ca.mcgill.rtgmrt.example.modes3/src/modes3/queries/Modes3Queries.vql + */ +package modes3.queries; + +import modes3.queries.Adjacent; +import modes3.queries.ConnectedTo; +import modes3.queries.ConnectedToNotSymmetric; +import modes3.queries.ConnectedToReflexive; +import modes3.queries.ExtraInputOfTurnout; +import modes3.queries.NoExtraInputOfTurnout; +import modes3.queries.Output; +import modes3.queries.OutputReflexive; +import modes3.queries.Reachable; +import modes3.queries.TooManyExtraInputsOfTurnout; +import modes3.queries.TooManyInputsOfSegment; +import modes3.queries.Turnout; +import modes3.queries.TurnoutConnectedToBothOutputs; +import modes3.queries.TurnoutInSegments; +import modes3.queries.TurnoutOutput; +import modes3.queries.TurnoutOutputsAreSame; +import modes3.queries.Unreachable; +import org.eclipse.viatra.query.runtime.api.ViatraQueryEngine; +import org.eclipse.viatra.query.runtime.api.impl.BaseGeneratedPatternGroup; + +/** + * A pattern group formed of all public patterns defined in Modes3Queries.vql. + * + *

Use the static instance as any {@link interface org.eclipse.viatra.query.runtime.api.IQueryGroup}, to conveniently prepare + * a VIATRA Query engine for matching all patterns originally defined in file Modes3Queries.vql, + * in order to achieve better performance than one-by-one on-demand matcher initialization. + * + *

From package modes3.queries, the group contains the definition of the following patterns:

    + *
  • turnoutInSegments
  • + *
  • connectedTo
  • + *
  • connectedToNotSymmetric
  • + *
  • connectedToReflexive
  • + *
  • turnoutOutput
  • + *
  • outputReflexive
  • + *
  • turnoutOutputsAreSame
  • + *
  • turnout
  • + *
  • output
  • + *
  • tooManyInputsOfSegment
  • + *
  • turnoutConnectedToBothOutputs
  • + *
  • extraInputOfTurnout
  • + *
  • noExtraInputOfTurnout
  • + *
  • tooManyExtraInputsOfTurnout
  • + *
  • adjacent
  • + *
  • reachable
  • + *
  • unreachable
  • + *
+ * + * @see IQueryGroup + * + */ +@SuppressWarnings("all") +public final class Modes3Queries extends BaseGeneratedPatternGroup { + /** + * Access the pattern group. + * + * @return the singleton instance of the group + * @throws ViatraQueryRuntimeException if there was an error loading the generated code of pattern specifications + * + */ + public static Modes3Queries instance() { + if (INSTANCE == null) { + INSTANCE = new Modes3Queries(); + } + return INSTANCE; + } + + private static Modes3Queries INSTANCE; + + private Modes3Queries() { + querySpecifications.add(TurnoutInSegments.instance()); + querySpecifications.add(ConnectedTo.instance()); + querySpecifications.add(ConnectedToNotSymmetric.instance()); + querySpecifications.add(ConnectedToReflexive.instance()); + querySpecifications.add(TurnoutOutput.instance()); + querySpecifications.add(OutputReflexive.instance()); + querySpecifications.add(TurnoutOutputsAreSame.instance()); + querySpecifications.add(Turnout.instance()); + querySpecifications.add(Output.instance()); + querySpecifications.add(TooManyInputsOfSegment.instance()); + querySpecifications.add(TurnoutConnectedToBothOutputs.instance()); + querySpecifications.add(ExtraInputOfTurnout.instance()); + querySpecifications.add(NoExtraInputOfTurnout.instance()); + querySpecifications.add(TooManyExtraInputsOfTurnout.instance()); + querySpecifications.add(Adjacent.instance()); + querySpecifications.add(Reachable.instance()); + querySpecifications.add(Unreachable.instance()); + } + + public TurnoutInSegments getTurnoutInSegments() { + return TurnoutInSegments.instance(); + } + + public TurnoutInSegments.Matcher getTurnoutInSegments(final ViatraQueryEngine engine) { + return TurnoutInSegments.Matcher.on(engine); + } + + public ConnectedTo getConnectedTo() { + return ConnectedTo.instance(); + } + + public ConnectedTo.Matcher getConnectedTo(final ViatraQueryEngine engine) { + return ConnectedTo.Matcher.on(engine); + } + + public ConnectedToNotSymmetric getConnectedToNotSymmetric() { + return ConnectedToNotSymmetric.instance(); + } + + public ConnectedToNotSymmetric.Matcher getConnectedToNotSymmetric(final ViatraQueryEngine engine) { + return ConnectedToNotSymmetric.Matcher.on(engine); + } + + public ConnectedToReflexive getConnectedToReflexive() { + return ConnectedToReflexive.instance(); + } + + public ConnectedToReflexive.Matcher getConnectedToReflexive(final ViatraQueryEngine engine) { + return ConnectedToReflexive.Matcher.on(engine); + } + + public TurnoutOutput getTurnoutOutput() { + return TurnoutOutput.instance(); + } + + public TurnoutOutput.Matcher getTurnoutOutput(final ViatraQueryEngine engine) { + return TurnoutOutput.Matcher.on(engine); + } + + public OutputReflexive getOutputReflexive() { + return OutputReflexive.instance(); + } + + public OutputReflexive.Matcher getOutputReflexive(final ViatraQueryEngine engine) { + return OutputReflexive.Matcher.on(engine); + } + + public TurnoutOutputsAreSame getTurnoutOutputsAreSame() { + return TurnoutOutputsAreSame.instance(); + } + + public TurnoutOutputsAreSame.Matcher getTurnoutOutputsAreSame(final ViatraQueryEngine engine) { + return TurnoutOutputsAreSame.Matcher.on(engine); + } + + public Turnout getTurnout() { + return Turnout.instance(); + } + + public Turnout.Matcher getTurnout(final ViatraQueryEngine engine) { + return Turnout.Matcher.on(engine); + } + + public Output getOutput() { + return Output.instance(); + } + + public Output.Matcher getOutput(final ViatraQueryEngine engine) { + return Output.Matcher.on(engine); + } + + public TooManyInputsOfSegment getTooManyInputsOfSegment() { + return TooManyInputsOfSegment.instance(); + } + + public TooManyInputsOfSegment.Matcher getTooManyInputsOfSegment(final ViatraQueryEngine engine) { + return TooManyInputsOfSegment.Matcher.on(engine); + } + + public TurnoutConnectedToBothOutputs getTurnoutConnectedToBothOutputs() { + return TurnoutConnectedToBothOutputs.instance(); + } + + public TurnoutConnectedToBothOutputs.Matcher getTurnoutConnectedToBothOutputs(final ViatraQueryEngine engine) { + return TurnoutConnectedToBothOutputs.Matcher.on(engine); + } + + public ExtraInputOfTurnout getExtraInputOfTurnout() { + return ExtraInputOfTurnout.instance(); + } + + public ExtraInputOfTurnout.Matcher getExtraInputOfTurnout(final ViatraQueryEngine engine) { + return ExtraInputOfTurnout.Matcher.on(engine); + } + + public NoExtraInputOfTurnout getNoExtraInputOfTurnout() { + return NoExtraInputOfTurnout.instance(); + } + + public NoExtraInputOfTurnout.Matcher getNoExtraInputOfTurnout(final ViatraQueryEngine engine) { + return NoExtraInputOfTurnout.Matcher.on(engine); + } + + public TooManyExtraInputsOfTurnout getTooManyExtraInputsOfTurnout() { + return TooManyExtraInputsOfTurnout.instance(); + } + + public TooManyExtraInputsOfTurnout.Matcher getTooManyExtraInputsOfTurnout(final ViatraQueryEngine engine) { + return TooManyExtraInputsOfTurnout.Matcher.on(engine); + } + + public Adjacent getAdjacent() { + return Adjacent.instance(); + } + + public Adjacent.Matcher getAdjacent(final ViatraQueryEngine engine) { + return Adjacent.Matcher.on(engine); + } + + public Reachable getReachable() { + return Reachable.instance(); + } + + public Reachable.Matcher getReachable(final ViatraQueryEngine engine) { + return Reachable.Matcher.on(engine); + } + + public Unreachable getUnreachable() { + return Unreachable.instance(); + } + + public Unreachable.Matcher getUnreachable(final ViatraQueryEngine engine) { + return Unreachable.Matcher.on(engine); + } +} diff --git a/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/NoExtraInputOfTurnout.java b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/NoExtraInputOfTurnout.java new file mode 100644 index 00000000..621d736f --- /dev/null +++ b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/NoExtraInputOfTurnout.java @@ -0,0 +1,560 @@ +/** + * Generated from platform:/resource/ca.mcgill.rtgmrt.example.modes3/src/modes3/queries/Modes3Queries.vql + */ +package modes3.queries; + +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 modes3.Turnout; +import modes3.queries.ExtraInputOfTurnout; +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(message = "noExtraInputOfTurnout", severity = "error", key = { T })
+ *         pattern noExtraInputOfTurnout(T : Turnout) {
+ *         	neg find extraInputOfTurnout(T, _);
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class NoExtraInputOfTurnout extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the modes3.queries.noExtraInputOfTurnout 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 Turnout fT; + + private static List parameterNames = makeImmutableList("T"); + + private Match(final Turnout pT) { + this.fT = pT; + } + + @Override + public Object get(final String parameterName) { + switch(parameterName) { + case "T": return this.fT; + default: return null; + } + } + + @Override + public Object get(final int index) { + switch(index) { + case 0: return this.fT; + default: return null; + } + } + + public Turnout getT() { + return this.fT; + } + + @Override + public boolean set(final String parameterName, final Object newValue) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + if ("T".equals(parameterName) ) { + this.fT = (Turnout) newValue; + return true; + } + return false; + } + + public void setT(final Turnout pT) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fT = pT; + } + + @Override + public String patternName() { + return "modes3.queries.noExtraInputOfTurnout"; + } + + @Override + public List parameterNames() { + return NoExtraInputOfTurnout.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fT}; + } + + @Override + public NoExtraInputOfTurnout.Match toImmutable() { + return isMutable() ? newMatch(fT) : this; + } + + @Override + public String prettyPrint() { + StringBuilder result = new StringBuilder(); + result.append("\"T\"=" + prettyPrintValue(fT)); + return result.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(fT); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) { + return false; + } + if ((obj instanceof NoExtraInputOfTurnout.Match)) { + NoExtraInputOfTurnout.Match other = (NoExtraInputOfTurnout.Match) obj; + return Objects.equals(fT, other.fT); + } 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 NoExtraInputOfTurnout specification() { + return NoExtraInputOfTurnout.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 NoExtraInputOfTurnout.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 pT the fixed value of pattern parameter T, or null if not bound. + * @return the new, mutable (partial) match object. + * + */ + public static NoExtraInputOfTurnout.Match newMutableMatch(final Turnout pT) { + return new Mutable(pT); + } + + /** + * 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. + * @return the (partial) match object. + * + */ + public static NoExtraInputOfTurnout.Match newMatch(final Turnout pT) { + return new Immutable(pT); + } + + private static final class Mutable extends NoExtraInputOfTurnout.Match { + Mutable(final Turnout pT) { + super(pT); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends NoExtraInputOfTurnout.Match { + Immutable(final Turnout pT) { + super(pT); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the modes3.queries.noExtraInputOfTurnout 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 = "noExtraInputOfTurnout", severity = "error", key = { T })
+   * pattern noExtraInputOfTurnout(T : Turnout) {
+   * 	neg find extraInputOfTurnout(T, _);
+   * }
+   * 
+ * + * @see Match + * @see NoExtraInputOfTurnout + * + */ + 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 NoExtraInputOfTurnout.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 NoExtraInputOfTurnout.Matcher create() { + return new Matcher(); + } + + private static final int POSITION_T = 0; + + private static final Logger LOGGER = ViatraQueryLoggingUtil.getLogger(NoExtraInputOfTurnout.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. + * @return matches represented as a Match object. + * + */ + public Collection getAllMatches(final Turnout pT) { + return rawStreamAllMatches(new Object[]{pT}).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. + * @return a stream of matches represented as a Match object. + * + */ + public Stream streamAllMatches(final Turnout pT) { + return rawStreamAllMatches(new Object[]{pT}); + } + + /** + * 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. + * @return a match represented as a Match object, or null if no match is found. + * + */ + public Optional getOneArbitraryMatch(final Turnout pT) { + return rawGetOneArbitraryMatch(new Object[]{pT}); + } + + /** + * 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. + * @return true if the input is a valid (partial) match of the pattern. + * + */ + public boolean hasMatch(final Turnout pT) { + return rawHasMatch(new Object[]{pT}); + } + + /** + * 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. + * @return the number of pattern matches found. + * + */ + public int countMatches(final Turnout pT) { + return rawCountMatches(new Object[]{pT}); + } + + /** + * 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 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 Turnout pT, final Consumer processor) { + return rawForOneArbitraryMatch(new Object[]{pT}, 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. + * @return the (partial) match object. + * + */ + public NoExtraInputOfTurnout.Match newMatch(final Turnout pT) { + return NoExtraInputOfTurnout.Match.newMatch(pT); + } + + /** + * 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(Turnout.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()); + } + + @Override + protected NoExtraInputOfTurnout.Match tupleToMatch(final Tuple t) { + try { + return NoExtraInputOfTurnout.Match.newMatch((Turnout) t.get(POSITION_T)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected NoExtraInputOfTurnout.Match arrayToMatch(final Object[] match) { + try { + return NoExtraInputOfTurnout.Match.newMatch((Turnout) match[POSITION_T]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected NoExtraInputOfTurnout.Match arrayToMatchMutable(final Object[] match) { + try { + return NoExtraInputOfTurnout.Match.newMutableMatch((Turnout) match[POSITION_T]); + } 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 NoExtraInputOfTurnout.instance(); + } + } + + private NoExtraInputOfTurnout() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static NoExtraInputOfTurnout instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected NoExtraInputOfTurnout.Matcher instantiate(final ViatraQueryEngine engine) { + return NoExtraInputOfTurnout.Matcher.on(engine); + } + + @Override + public NoExtraInputOfTurnout.Matcher instantiate() { + return NoExtraInputOfTurnout.Matcher.create(); + } + + @Override + public NoExtraInputOfTurnout.Match newEmptyMatch() { + return NoExtraInputOfTurnout.Match.newEmptyMatch(); + } + + @Override + public NoExtraInputOfTurnout.Match newMatch(final Object... parameters) { + return NoExtraInputOfTurnout.Match.newMatch((modes3.Turnout) parameters[0]); + } + + /** + * Inner class allowing the singleton instance of {@link NoExtraInputOfTurnout} to be created + * not at the class load time of the outer class, + * but rather at the first call to {@link NoExtraInputOfTurnout#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private static final NoExtraInputOfTurnout INSTANCE = new NoExtraInputOfTurnout(); + + /** + * 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 static final Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private static final NoExtraInputOfTurnout.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_T = new PParameter("T", "modes3.Turnout", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("http://www.ece.mcgill.ca/wcet/modes3", "Turnout")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_T); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "modes3.queries.noExtraInputOfTurnout"; + } + + @Override + public List getParameterNames() { + return Arrays.asList("T"); + } + + @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___0_ = body.getOrCreateVariableByName("_<0>"); + new TypeConstraint(body, Tuples.flatTupleOf(var_T), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Turnout"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_T, parameter_T) + )); + // neg find extraInputOfTurnout(T, _) + new NegativePatternCall(body, Tuples.flatTupleOf(var_T, var___0_), ExtraInputOfTurnout.instance().getInternalQueryRepresentation()); + bodies.add(body); + } + { + PAnnotation annotation = new PAnnotation("Constraint"); + annotation.addAttribute("message", "noExtraInputOfTurnout"); + annotation.addAttribute("severity", "error"); + annotation.addAttribute("key", Arrays.asList(new Object[] { + new ParameterReference("T") + })); + addAnnotation(annotation); + } + return bodies; + } + } +} diff --git a/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/Output.java b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/Output.java new file mode 100644 index 00000000..615b33af --- /dev/null +++ b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/Output.java @@ -0,0 +1,724 @@ +/** + * Generated from platform:/resource/ca.mcgill.rtgmrt.example.modes3/src/modes3/queries/Modes3Queries.vql + */ +package modes3.queries; + +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 modes3.Segment; +import modes3.queries.TurnoutOutput; +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.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 output(S1 : Segment, S2 : Segment) {
+ *         	Segment.connectedTo(S1, S2);
+ *         } or {
+ *         	find turnoutOutput(S1, S2);
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class Output extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the modes3.queries.output 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 Segment fS1; + + private Segment fS2; + + private static List parameterNames = makeImmutableList("S1", "S2"); + + private Match(final Segment pS1, final Segment pS2) { + this.fS1 = pS1; + this.fS2 = pS2; + } + + @Override + public Object get(final String parameterName) { + switch(parameterName) { + case "S1": return this.fS1; + case "S2": return this.fS2; + default: return null; + } + } + + @Override + public Object get(final int index) { + switch(index) { + case 0: return this.fS1; + case 1: return this.fS2; + default: return null; + } + } + + public Segment getS1() { + return this.fS1; + } + + public Segment 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 = (Segment) newValue; + return true; + } + if ("S2".equals(parameterName) ) { + this.fS2 = (Segment) newValue; + return true; + } + return false; + } + + public void setS1(final Segment pS1) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fS1 = pS1; + } + + public void setS2(final Segment pS2) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fS2 = pS2; + } + + @Override + public String patternName() { + return "modes3.queries.output"; + } + + @Override + public List parameterNames() { + return Output.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fS1, fS2}; + } + + @Override + public Output.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 Output.Match)) { + Output.Match other = (Output.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 Output specification() { + return Output.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 Output.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 Output.Match newMutableMatch(final Segment pS1, final Segment 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 Output.Match newMatch(final Segment pS1, final Segment pS2) { + return new Immutable(pS1, pS2); + } + + private static final class Mutable extends Output.Match { + Mutable(final Segment pS1, final Segment pS2) { + super(pS1, pS2); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends Output.Match { + Immutable(final Segment pS1, final Segment pS2) { + super(pS1, pS2); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the modes3.queries.output 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 output(S1 : Segment, S2 : Segment) {
+   * 	Segment.connectedTo(S1, S2);
+   * } or {
+   * 	find turnoutOutput(S1, S2);
+   * }
+   * 
+ * + * @see Match + * @see Output + * + */ + 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 Output.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 Output.Matcher create() { + return new Matcher(); + } + + private static final int POSITION_S1 = 0; + + private static final int POSITION_S2 = 1; + + private static final Logger LOGGER = ViatraQueryLoggingUtil.getLogger(Output.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 Segment pS1, final Segment 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 Segment pS1, final Segment 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 Segment pS1, final Segment 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 Segment pS1, final Segment 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 Segment pS1, final Segment 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 Segment pS1, final Segment 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 Output.Match newMatch(final Segment pS1, final Segment pS2) { + return Output.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(Segment.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 Output.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 Segment 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 Output.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 Segment 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(Segment.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 Output.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 Segment 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 Output.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 Segment pS1) { + return rawStreamAllValuesOfS2(new Object[]{pS1, null}).collect(Collectors.toSet()); + } + + @Override + protected Output.Match tupleToMatch(final Tuple t) { + try { + return Output.Match.newMatch((Segment) t.get(POSITION_S1), (Segment) t.get(POSITION_S2)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected Output.Match arrayToMatch(final Object[] match) { + try { + return Output.Match.newMatch((Segment) match[POSITION_S1], (Segment) match[POSITION_S2]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected Output.Match arrayToMatchMutable(final Object[] match) { + try { + return Output.Match.newMutableMatch((Segment) match[POSITION_S1], (Segment) 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 Output.instance(); + } + } + + private Output() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static Output instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected Output.Matcher instantiate(final ViatraQueryEngine engine) { + return Output.Matcher.on(engine); + } + + @Override + public Output.Matcher instantiate() { + return Output.Matcher.create(); + } + + @Override + public Output.Match newEmptyMatch() { + return Output.Match.newEmptyMatch(); + } + + @Override + public Output.Match newMatch(final Object... parameters) { + return Output.Match.newMatch((modes3.Segment) parameters[0], (modes3.Segment) parameters[1]); + } + + /** + * Inner class allowing the singleton instance of {@link Output} to be created + * not at the class load time of the outer class, + * but rather at the first call to {@link Output#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private static final Output INSTANCE = new Output(); + + /** + * 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 static final Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private static final Output.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_S1 = new PParameter("S1", "modes3.Segment", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("http://www.ece.mcgill.ca/wcet/modes3", "Segment")), PParameterDirection.INOUT); + + private final PParameter parameter_S2 = new PParameter("S2", "modes3.Segment", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("http://www.ece.mcgill.ca/wcet/modes3", "Segment")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_S1, parameter_S2); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "modes3.queries.output"; + } + + @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("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_S2), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_S1, parameter_S1), + new ExportedParameter(body, var_S2, parameter_S2) + )); + // Segment.connectedTo(S1, S2) + new TypeConstraint(body, Tuples.flatTupleOf(var_S1), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_S1, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment", "connectedTo"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + new Equality(body, var__virtual_0_, var_S2); + bodies.add(body); + } + { + 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("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_S2), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_S1, parameter_S1), + new ExportedParameter(body, var_S2, parameter_S2) + )); + // find turnoutOutput(S1, S2) + new PositivePatternCall(body, Tuples.flatTupleOf(var_S1, var_S2), TurnoutOutput.instance().getInternalQueryRepresentation()); + bodies.add(body); + } + return bodies; + } + } +} diff --git a/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/OutputReflexive.java b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/OutputReflexive.java new file mode 100644 index 00000000..3d90ede5 --- /dev/null +++ b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/OutputReflexive.java @@ -0,0 +1,559 @@ +/** + * Generated from platform:/resource/ca.mcgill.rtgmrt.example.modes3/src/modes3/queries/Modes3Queries.vql + */ +package modes3.queries; + +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 modes3.Turnout; +import modes3.queries.TurnoutOutput; +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(message = "outputReflexive", severity = "error", key = { T })
+ *         pattern outputReflexive(T : Turnout) {
+ *         	find turnoutOutput(T, T);
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class OutputReflexive extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the modes3.queries.outputReflexive 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 Turnout fT; + + private static List parameterNames = makeImmutableList("T"); + + private Match(final Turnout pT) { + this.fT = pT; + } + + @Override + public Object get(final String parameterName) { + switch(parameterName) { + case "T": return this.fT; + default: return null; + } + } + + @Override + public Object get(final int index) { + switch(index) { + case 0: return this.fT; + default: return null; + } + } + + public Turnout getT() { + return this.fT; + } + + @Override + public boolean set(final String parameterName, final Object newValue) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + if ("T".equals(parameterName) ) { + this.fT = (Turnout) newValue; + return true; + } + return false; + } + + public void setT(final Turnout pT) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fT = pT; + } + + @Override + public String patternName() { + return "modes3.queries.outputReflexive"; + } + + @Override + public List parameterNames() { + return OutputReflexive.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fT}; + } + + @Override + public OutputReflexive.Match toImmutable() { + return isMutable() ? newMatch(fT) : this; + } + + @Override + public String prettyPrint() { + StringBuilder result = new StringBuilder(); + result.append("\"T\"=" + prettyPrintValue(fT)); + return result.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(fT); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) { + return false; + } + if ((obj instanceof OutputReflexive.Match)) { + OutputReflexive.Match other = (OutputReflexive.Match) obj; + return Objects.equals(fT, other.fT); + } 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 OutputReflexive specification() { + return OutputReflexive.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 OutputReflexive.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 pT the fixed value of pattern parameter T, or null if not bound. + * @return the new, mutable (partial) match object. + * + */ + public static OutputReflexive.Match newMutableMatch(final Turnout pT) { + return new Mutable(pT); + } + + /** + * 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. + * @return the (partial) match object. + * + */ + public static OutputReflexive.Match newMatch(final Turnout pT) { + return new Immutable(pT); + } + + private static final class Mutable extends OutputReflexive.Match { + Mutable(final Turnout pT) { + super(pT); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends OutputReflexive.Match { + Immutable(final Turnout pT) { + super(pT); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the modes3.queries.outputReflexive 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 = "outputReflexive", severity = "error", key = { T })
+   * pattern outputReflexive(T : Turnout) {
+   * 	find turnoutOutput(T, T);
+   * }
+   * 
+ * + * @see Match + * @see OutputReflexive + * + */ + 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 OutputReflexive.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 OutputReflexive.Matcher create() { + return new Matcher(); + } + + private static final int POSITION_T = 0; + + private static final Logger LOGGER = ViatraQueryLoggingUtil.getLogger(OutputReflexive.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. + * @return matches represented as a Match object. + * + */ + public Collection getAllMatches(final Turnout pT) { + return rawStreamAllMatches(new Object[]{pT}).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. + * @return a stream of matches represented as a Match object. + * + */ + public Stream streamAllMatches(final Turnout pT) { + return rawStreamAllMatches(new Object[]{pT}); + } + + /** + * 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. + * @return a match represented as a Match object, or null if no match is found. + * + */ + public Optional getOneArbitraryMatch(final Turnout pT) { + return rawGetOneArbitraryMatch(new Object[]{pT}); + } + + /** + * 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. + * @return true if the input is a valid (partial) match of the pattern. + * + */ + public boolean hasMatch(final Turnout pT) { + return rawHasMatch(new Object[]{pT}); + } + + /** + * 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. + * @return the number of pattern matches found. + * + */ + public int countMatches(final Turnout pT) { + return rawCountMatches(new Object[]{pT}); + } + + /** + * 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 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 Turnout pT, final Consumer processor) { + return rawForOneArbitraryMatch(new Object[]{pT}, 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. + * @return the (partial) match object. + * + */ + public OutputReflexive.Match newMatch(final Turnout pT) { + return OutputReflexive.Match.newMatch(pT); + } + + /** + * 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(Turnout.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()); + } + + @Override + protected OutputReflexive.Match tupleToMatch(final Tuple t) { + try { + return OutputReflexive.Match.newMatch((Turnout) t.get(POSITION_T)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected OutputReflexive.Match arrayToMatch(final Object[] match) { + try { + return OutputReflexive.Match.newMatch((Turnout) match[POSITION_T]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected OutputReflexive.Match arrayToMatchMutable(final Object[] match) { + try { + return OutputReflexive.Match.newMutableMatch((Turnout) match[POSITION_T]); + } 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 OutputReflexive.instance(); + } + } + + private OutputReflexive() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static OutputReflexive instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected OutputReflexive.Matcher instantiate(final ViatraQueryEngine engine) { + return OutputReflexive.Matcher.on(engine); + } + + @Override + public OutputReflexive.Matcher instantiate() { + return OutputReflexive.Matcher.create(); + } + + @Override + public OutputReflexive.Match newEmptyMatch() { + return OutputReflexive.Match.newEmptyMatch(); + } + + @Override + public OutputReflexive.Match newMatch(final Object... parameters) { + return OutputReflexive.Match.newMatch((modes3.Turnout) parameters[0]); + } + + /** + * Inner class allowing the singleton instance of {@link OutputReflexive} to be created + * not at the class load time of the outer class, + * but rather at the first call to {@link OutputReflexive#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private static final OutputReflexive INSTANCE = new OutputReflexive(); + + /** + * 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 static final Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private static final OutputReflexive.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_T = new PParameter("T", "modes3.Turnout", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("http://www.ece.mcgill.ca/wcet/modes3", "Turnout")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_T); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "modes3.queries.outputReflexive"; + } + + @Override + public List getParameterNames() { + return Arrays.asList("T"); + } + + @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"); + new TypeConstraint(body, Tuples.flatTupleOf(var_T), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Turnout"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_T, parameter_T) + )); + // find turnoutOutput(T, T) + new PositivePatternCall(body, Tuples.flatTupleOf(var_T, var_T), TurnoutOutput.instance().getInternalQueryRepresentation()); + bodies.add(body); + } + { + PAnnotation annotation = new PAnnotation("Constraint"); + annotation.addAttribute("message", "outputReflexive"); + annotation.addAttribute("severity", "error"); + annotation.addAttribute("key", Arrays.asList(new Object[] { + new ParameterReference("T") + })); + addAnnotation(annotation); + } + return bodies; + } + } +} diff --git a/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/Reachable.java b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/Reachable.java new file mode 100644 index 00000000..93d43c21 --- /dev/null +++ b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/Reachable.java @@ -0,0 +1,719 @@ +/** + * Generated from platform:/resource/ca.mcgill.rtgmrt.example.modes3/src/modes3/queries/Modes3Queries.vql + */ +package modes3.queries; + +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 modes3.Segment; +import modes3.queries.Adjacent; +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.Equality; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicdeferred.ExportedParameter; +import org.eclipse.viatra.query.runtime.matchers.psystem.basicenumerables.BinaryTransitiveClosure; +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 reachable(S1 : Segment, S2 : Segment) {
+ *         	S1 == S2;
+ *         } or {
+ *         	find adjacent+(S1, S2);
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class Reachable extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the modes3.queries.reachable 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 Segment fS1; + + private Segment fS2; + + private static List parameterNames = makeImmutableList("S1", "S2"); + + private Match(final Segment pS1, final Segment pS2) { + this.fS1 = pS1; + this.fS2 = pS2; + } + + @Override + public Object get(final String parameterName) { + switch(parameterName) { + case "S1": return this.fS1; + case "S2": return this.fS2; + default: return null; + } + } + + @Override + public Object get(final int index) { + switch(index) { + case 0: return this.fS1; + case 1: return this.fS2; + default: return null; + } + } + + public Segment getS1() { + return this.fS1; + } + + public Segment 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 = (Segment) newValue; + return true; + } + if ("S2".equals(parameterName) ) { + this.fS2 = (Segment) newValue; + return true; + } + return false; + } + + public void setS1(final Segment pS1) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fS1 = pS1; + } + + public void setS2(final Segment pS2) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fS2 = pS2; + } + + @Override + public String patternName() { + return "modes3.queries.reachable"; + } + + @Override + public List parameterNames() { + return Reachable.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fS1, fS2}; + } + + @Override + public Reachable.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 Reachable.Match)) { + Reachable.Match other = (Reachable.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 Reachable specification() { + return Reachable.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 Reachable.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 Reachable.Match newMutableMatch(final Segment pS1, final Segment 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 Reachable.Match newMatch(final Segment pS1, final Segment pS2) { + return new Immutable(pS1, pS2); + } + + private static final class Mutable extends Reachable.Match { + Mutable(final Segment pS1, final Segment pS2) { + super(pS1, pS2); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends Reachable.Match { + Immutable(final Segment pS1, final Segment pS2) { + super(pS1, pS2); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the modes3.queries.reachable 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 reachable(S1 : Segment, S2 : Segment) {
+   * 	S1 == S2;
+   * } or {
+   * 	find adjacent+(S1, S2);
+   * }
+   * 
+ * + * @see Match + * @see Reachable + * + */ + 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 Reachable.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 Reachable.Matcher create() { + return new Matcher(); + } + + private static final int POSITION_S1 = 0; + + private static final int POSITION_S2 = 1; + + private static final Logger LOGGER = ViatraQueryLoggingUtil.getLogger(Reachable.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 Segment pS1, final Segment 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 Segment pS1, final Segment 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 Segment pS1, final Segment 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 Segment pS1, final Segment 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 Segment pS1, final Segment 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 Segment pS1, final Segment 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 Reachable.Match newMatch(final Segment pS1, final Segment pS2) { + return Reachable.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(Segment.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 Reachable.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 Segment 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 Reachable.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 Segment 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(Segment.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 Reachable.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 Segment 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 Reachable.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 Segment pS1) { + return rawStreamAllValuesOfS2(new Object[]{pS1, null}).collect(Collectors.toSet()); + } + + @Override + protected Reachable.Match tupleToMatch(final Tuple t) { + try { + return Reachable.Match.newMatch((Segment) t.get(POSITION_S1), (Segment) t.get(POSITION_S2)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected Reachable.Match arrayToMatch(final Object[] match) { + try { + return Reachable.Match.newMatch((Segment) match[POSITION_S1], (Segment) match[POSITION_S2]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected Reachable.Match arrayToMatchMutable(final Object[] match) { + try { + return Reachable.Match.newMutableMatch((Segment) match[POSITION_S1], (Segment) 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 Reachable.instance(); + } + } + + private Reachable() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static Reachable instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected Reachable.Matcher instantiate(final ViatraQueryEngine engine) { + return Reachable.Matcher.on(engine); + } + + @Override + public Reachable.Matcher instantiate() { + return Reachable.Matcher.create(); + } + + @Override + public Reachable.Match newEmptyMatch() { + return Reachable.Match.newEmptyMatch(); + } + + @Override + public Reachable.Match newMatch(final Object... parameters) { + return Reachable.Match.newMatch((modes3.Segment) parameters[0], (modes3.Segment) parameters[1]); + } + + /** + * Inner class allowing the singleton instance of {@link Reachable} to be created + * not at the class load time of the outer class, + * but rather at the first call to {@link Reachable#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private static final Reachable INSTANCE = new Reachable(); + + /** + * 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 static final Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private static final Reachable.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_S1 = new PParameter("S1", "modes3.Segment", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("http://www.ece.mcgill.ca/wcet/modes3", "Segment")), PParameterDirection.INOUT); + + private final PParameter parameter_S2 = new PParameter("S2", "modes3.Segment", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("http://www.ece.mcgill.ca/wcet/modes3", "Segment")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_S1, parameter_S2); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "modes3.queries.reachable"; + } + + @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("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_S2), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_S1, parameter_S1), + new ExportedParameter(body, var_S2, parameter_S2) + )); + // S1 == S2 + new Equality(body, var_S1, var_S2); + bodies.add(body); + } + { + 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("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_S2), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_S1, parameter_S1), + new ExportedParameter(body, var_S2, parameter_S2) + )); + // find adjacent+(S1, S2) + new BinaryTransitiveClosure(body, Tuples.flatTupleOf(var_S1, var_S2), Adjacent.instance().getInternalQueryRepresentation()); + bodies.add(body); + } + return bodies; + } + } +} diff --git a/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/TooManyExtraInputsOfTurnout.java b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/TooManyExtraInputsOfTurnout.java new file mode 100644 index 00000000..9f417795 --- /dev/null +++ b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/TooManyExtraInputsOfTurnout.java @@ -0,0 +1,570 @@ +/** + * Generated from platform:/resource/ca.mcgill.rtgmrt.example.modes3/src/modes3/queries/Modes3Queries.vql + */ +package modes3.queries; + +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 modes3.Turnout; +import modes3.queries.ExtraInputOfTurnout; +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.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(message = "tooManyExtraInputsOfTurnout", severity = "error", key = { T })
+ *         pattern tooManyExtraInputsOfTurnout(T : Turnout) {
+ *         	find extraInputOfTurnout(T, I1);
+ *         	find extraInputOfTurnout(T, I2);
+ *         	I1 != I2;
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class TooManyExtraInputsOfTurnout extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the modes3.queries.tooManyExtraInputsOfTurnout 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 Turnout fT; + + private static List parameterNames = makeImmutableList("T"); + + private Match(final Turnout pT) { + this.fT = pT; + } + + @Override + public Object get(final String parameterName) { + switch(parameterName) { + case "T": return this.fT; + default: return null; + } + } + + @Override + public Object get(final int index) { + switch(index) { + case 0: return this.fT; + default: return null; + } + } + + public Turnout getT() { + return this.fT; + } + + @Override + public boolean set(final String parameterName, final Object newValue) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + if ("T".equals(parameterName) ) { + this.fT = (Turnout) newValue; + return true; + } + return false; + } + + public void setT(final Turnout pT) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fT = pT; + } + + @Override + public String patternName() { + return "modes3.queries.tooManyExtraInputsOfTurnout"; + } + + @Override + public List parameterNames() { + return TooManyExtraInputsOfTurnout.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fT}; + } + + @Override + public TooManyExtraInputsOfTurnout.Match toImmutable() { + return isMutable() ? newMatch(fT) : this; + } + + @Override + public String prettyPrint() { + StringBuilder result = new StringBuilder(); + result.append("\"T\"=" + prettyPrintValue(fT)); + return result.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(fT); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) { + return false; + } + if ((obj instanceof TooManyExtraInputsOfTurnout.Match)) { + TooManyExtraInputsOfTurnout.Match other = (TooManyExtraInputsOfTurnout.Match) obj; + return Objects.equals(fT, other.fT); + } 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 TooManyExtraInputsOfTurnout specification() { + return TooManyExtraInputsOfTurnout.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 TooManyExtraInputsOfTurnout.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 pT the fixed value of pattern parameter T, or null if not bound. + * @return the new, mutable (partial) match object. + * + */ + public static TooManyExtraInputsOfTurnout.Match newMutableMatch(final Turnout pT) { + return new Mutable(pT); + } + + /** + * 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. + * @return the (partial) match object. + * + */ + public static TooManyExtraInputsOfTurnout.Match newMatch(final Turnout pT) { + return new Immutable(pT); + } + + private static final class Mutable extends TooManyExtraInputsOfTurnout.Match { + Mutable(final Turnout pT) { + super(pT); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends TooManyExtraInputsOfTurnout.Match { + Immutable(final Turnout pT) { + super(pT); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the modes3.queries.tooManyExtraInputsOfTurnout 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 = "tooManyExtraInputsOfTurnout", severity = "error", key = { T })
+   * pattern tooManyExtraInputsOfTurnout(T : Turnout) {
+   * 	find extraInputOfTurnout(T, I1);
+   * 	find extraInputOfTurnout(T, I2);
+   * 	I1 != I2;
+   * }
+   * 
+ * + * @see Match + * @see TooManyExtraInputsOfTurnout + * + */ + 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 TooManyExtraInputsOfTurnout.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 TooManyExtraInputsOfTurnout.Matcher create() { + return new Matcher(); + } + + private static final int POSITION_T = 0; + + private static final Logger LOGGER = ViatraQueryLoggingUtil.getLogger(TooManyExtraInputsOfTurnout.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. + * @return matches represented as a Match object. + * + */ + public Collection getAllMatches(final Turnout pT) { + return rawStreamAllMatches(new Object[]{pT}).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. + * @return a stream of matches represented as a Match object. + * + */ + public Stream streamAllMatches(final Turnout pT) { + return rawStreamAllMatches(new Object[]{pT}); + } + + /** + * 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. + * @return a match represented as a Match object, or null if no match is found. + * + */ + public Optional getOneArbitraryMatch(final Turnout pT) { + return rawGetOneArbitraryMatch(new Object[]{pT}); + } + + /** + * 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. + * @return true if the input is a valid (partial) match of the pattern. + * + */ + public boolean hasMatch(final Turnout pT) { + return rawHasMatch(new Object[]{pT}); + } + + /** + * 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. + * @return the number of pattern matches found. + * + */ + public int countMatches(final Turnout pT) { + return rawCountMatches(new Object[]{pT}); + } + + /** + * 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 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 Turnout pT, final Consumer processor) { + return rawForOneArbitraryMatch(new Object[]{pT}, 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. + * @return the (partial) match object. + * + */ + public TooManyExtraInputsOfTurnout.Match newMatch(final Turnout pT) { + return TooManyExtraInputsOfTurnout.Match.newMatch(pT); + } + + /** + * 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(Turnout.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()); + } + + @Override + protected TooManyExtraInputsOfTurnout.Match tupleToMatch(final Tuple t) { + try { + return TooManyExtraInputsOfTurnout.Match.newMatch((Turnout) t.get(POSITION_T)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected TooManyExtraInputsOfTurnout.Match arrayToMatch(final Object[] match) { + try { + return TooManyExtraInputsOfTurnout.Match.newMatch((Turnout) match[POSITION_T]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected TooManyExtraInputsOfTurnout.Match arrayToMatchMutable(final Object[] match) { + try { + return TooManyExtraInputsOfTurnout.Match.newMutableMatch((Turnout) match[POSITION_T]); + } 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 TooManyExtraInputsOfTurnout.instance(); + } + } + + private TooManyExtraInputsOfTurnout() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static TooManyExtraInputsOfTurnout instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected TooManyExtraInputsOfTurnout.Matcher instantiate(final ViatraQueryEngine engine) { + return TooManyExtraInputsOfTurnout.Matcher.on(engine); + } + + @Override + public TooManyExtraInputsOfTurnout.Matcher instantiate() { + return TooManyExtraInputsOfTurnout.Matcher.create(); + } + + @Override + public TooManyExtraInputsOfTurnout.Match newEmptyMatch() { + return TooManyExtraInputsOfTurnout.Match.newEmptyMatch(); + } + + @Override + public TooManyExtraInputsOfTurnout.Match newMatch(final Object... parameters) { + return TooManyExtraInputsOfTurnout.Match.newMatch((modes3.Turnout) parameters[0]); + } + + /** + * Inner class allowing the singleton instance of {@link TooManyExtraInputsOfTurnout} to be created + * not at the class load time of the outer class, + * but rather at the first call to {@link TooManyExtraInputsOfTurnout#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private static final TooManyExtraInputsOfTurnout INSTANCE = new TooManyExtraInputsOfTurnout(); + + /** + * 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 static final Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private static final TooManyExtraInputsOfTurnout.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_T = new PParameter("T", "modes3.Turnout", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("http://www.ece.mcgill.ca/wcet/modes3", "Turnout")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_T); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "modes3.queries.tooManyExtraInputsOfTurnout"; + } + + @Override + public List getParameterNames() { + return Arrays.asList("T"); + } + + @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_I1 = body.getOrCreateVariableByName("I1"); + PVariable var_I2 = body.getOrCreateVariableByName("I2"); + new TypeConstraint(body, Tuples.flatTupleOf(var_T), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Turnout"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_T, parameter_T) + )); + // find extraInputOfTurnout(T, I1) + new PositivePatternCall(body, Tuples.flatTupleOf(var_T, var_I1), ExtraInputOfTurnout.instance().getInternalQueryRepresentation()); + // find extraInputOfTurnout(T, I2) + new PositivePatternCall(body, Tuples.flatTupleOf(var_T, var_I2), ExtraInputOfTurnout.instance().getInternalQueryRepresentation()); + // I1 != I2 + new Inequality(body, var_I1, var_I2); + bodies.add(body); + } + { + PAnnotation annotation = new PAnnotation("Constraint"); + annotation.addAttribute("message", "tooManyExtraInputsOfTurnout"); + annotation.addAttribute("severity", "error"); + annotation.addAttribute("key", Arrays.asList(new Object[] { + new ParameterReference("T") + })); + addAnnotation(annotation); + } + return bodies; + } + } +} diff --git a/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/TooManyInputsOfSegment.java b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/TooManyInputsOfSegment.java new file mode 100644 index 00000000..e5e8827c --- /dev/null +++ b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/TooManyInputsOfSegment.java @@ -0,0 +1,601 @@ +/** + * Generated from platform:/resource/ca.mcgill.rtgmrt.example.modes3/src/modes3/queries/Modes3Queries.vql + */ +package modes3.queries; + +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 modes3.Segment; +import modes3.queries.Output; +import modes3.queries.Turnout; +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.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(message = "noInputOfSegment", severity = "error", key = { S })
+ *         //pattern noInputOfSegment(S : Segment) {
+ *         //	neg find turnout(S);
+ *         //	neg find output(_, S);
+ *         //}
+ *         
+ *         {@literal @}Constraint(message = "tooManyInputsOfSegment", severity = "error", key = { S })
+ *         pattern tooManyInputsOfSegment(S : Segment) {
+ *         	neg find turnout(S);
+ *         	find output(I1, S);
+ *         	find output(I2, S);
+ *         	find output(I3, S);
+ *         	I1 != I2;
+ *         	I1 != I3;
+ *         	I2 != I3;
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class TooManyInputsOfSegment extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the modes3.queries.tooManyInputsOfSegment 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 Segment fS; + + private static List parameterNames = makeImmutableList("S"); + + private Match(final Segment pS) { + this.fS = pS; + } + + @Override + public Object get(final String parameterName) { + switch(parameterName) { + case "S": return this.fS; + default: return null; + } + } + + @Override + public Object get(final int index) { + switch(index) { + case 0: return this.fS; + default: return null; + } + } + + public Segment 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 = (Segment) newValue; + return true; + } + return false; + } + + public void setS(final Segment pS) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fS = pS; + } + + @Override + public String patternName() { + return "modes3.queries.tooManyInputsOfSegment"; + } + + @Override + public List parameterNames() { + return TooManyInputsOfSegment.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fS}; + } + + @Override + public TooManyInputsOfSegment.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 TooManyInputsOfSegment.Match)) { + TooManyInputsOfSegment.Match other = (TooManyInputsOfSegment.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 TooManyInputsOfSegment specification() { + return TooManyInputsOfSegment.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 TooManyInputsOfSegment.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 TooManyInputsOfSegment.Match newMutableMatch(final Segment 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 TooManyInputsOfSegment.Match newMatch(final Segment pS) { + return new Immutable(pS); + } + + private static final class Mutable extends TooManyInputsOfSegment.Match { + Mutable(final Segment pS) { + super(pS); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends TooManyInputsOfSegment.Match { + Immutable(final Segment pS) { + super(pS); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the modes3.queries.tooManyInputsOfSegment 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 = "noInputOfSegment", severity = "error", key = { S })
+   * //pattern noInputOfSegment(S : Segment) {
+   * //	neg find turnout(S);
+   * //	neg find output(_, S);
+   * //}
+   * 
+   * {@literal @}Constraint(message = "tooManyInputsOfSegment", severity = "error", key = { S })
+   * pattern tooManyInputsOfSegment(S : Segment) {
+   * 	neg find turnout(S);
+   * 	find output(I1, S);
+   * 	find output(I2, S);
+   * 	find output(I3, S);
+   * 	I1 != I2;
+   * 	I1 != I3;
+   * 	I2 != I3;
+   * }
+   * 
+ * + * @see Match + * @see TooManyInputsOfSegment + * + */ + 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 TooManyInputsOfSegment.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 TooManyInputsOfSegment.Matcher create() { + return new Matcher(); + } + + private static final int POSITION_S = 0; + + private static final Logger LOGGER = ViatraQueryLoggingUtil.getLogger(TooManyInputsOfSegment.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 Segment 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 Segment 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 Segment 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 Segment 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 Segment 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 Segment 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 TooManyInputsOfSegment.Match newMatch(final Segment pS) { + return TooManyInputsOfSegment.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(Segment.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 TooManyInputsOfSegment.Match tupleToMatch(final Tuple t) { + try { + return TooManyInputsOfSegment.Match.newMatch((Segment) t.get(POSITION_S)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected TooManyInputsOfSegment.Match arrayToMatch(final Object[] match) { + try { + return TooManyInputsOfSegment.Match.newMatch((Segment) match[POSITION_S]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected TooManyInputsOfSegment.Match arrayToMatchMutable(final Object[] match) { + try { + return TooManyInputsOfSegment.Match.newMutableMatch((Segment) 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 TooManyInputsOfSegment.instance(); + } + } + + private TooManyInputsOfSegment() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static TooManyInputsOfSegment instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected TooManyInputsOfSegment.Matcher instantiate(final ViatraQueryEngine engine) { + return TooManyInputsOfSegment.Matcher.on(engine); + } + + @Override + public TooManyInputsOfSegment.Matcher instantiate() { + return TooManyInputsOfSegment.Matcher.create(); + } + + @Override + public TooManyInputsOfSegment.Match newEmptyMatch() { + return TooManyInputsOfSegment.Match.newEmptyMatch(); + } + + @Override + public TooManyInputsOfSegment.Match newMatch(final Object... parameters) { + return TooManyInputsOfSegment.Match.newMatch((modes3.Segment) parameters[0]); + } + + /** + * Inner class allowing the singleton instance of {@link TooManyInputsOfSegment} to be created + * not at the class load time of the outer class, + * but rather at the first call to {@link TooManyInputsOfSegment#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private static final TooManyInputsOfSegment INSTANCE = new TooManyInputsOfSegment(); + + /** + * 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 static final Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private static final TooManyInputsOfSegment.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_S = new PParameter("S", "modes3.Segment", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("http://www.ece.mcgill.ca/wcet/modes3", "Segment")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_S); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "modes3.queries.tooManyInputsOfSegment"; + } + + @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_I1 = body.getOrCreateVariableByName("I1"); + PVariable var_I2 = body.getOrCreateVariableByName("I2"); + PVariable var_I3 = body.getOrCreateVariableByName("I3"); + new TypeConstraint(body, Tuples.flatTupleOf(var_S), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_S, parameter_S) + )); + // neg find turnout(S) + new NegativePatternCall(body, Tuples.flatTupleOf(var_S), Turnout.instance().getInternalQueryRepresentation()); + // find output(I1, S) + new PositivePatternCall(body, Tuples.flatTupleOf(var_I1, var_S), Output.instance().getInternalQueryRepresentation()); + // find output(I2, S) + new PositivePatternCall(body, Tuples.flatTupleOf(var_I2, var_S), Output.instance().getInternalQueryRepresentation()); + // find output(I3, S) + new PositivePatternCall(body, Tuples.flatTupleOf(var_I3, var_S), Output.instance().getInternalQueryRepresentation()); + // I1 != I2 + new Inequality(body, var_I1, var_I2); + // I1 != I3 + new Inequality(body, var_I1, var_I3); + // I2 != I3 + new Inequality(body, var_I2, var_I3); + bodies.add(body); + } + { + PAnnotation annotation = new PAnnotation("Constraint"); + annotation.addAttribute("message", "tooManyInputsOfSegment"); + annotation.addAttribute("severity", "error"); + annotation.addAttribute("key", Arrays.asList(new Object[] { + new ParameterReference("S") + })); + addAnnotation(annotation); + } + return bodies; + } + } +} diff --git a/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/Turnout.java b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/Turnout.java new file mode 100644 index 00000000..34c7631c --- /dev/null +++ b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/Turnout.java @@ -0,0 +1,543 @@ +/** + * Generated from platform:/resource/ca.mcgill.rtgmrt.example.modes3/src/modes3/queries/Modes3Queries.vql + */ +package modes3.queries; + +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.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 turnout(T : Turnout) {
+ *         	Turnout(T);
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class Turnout extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the modes3.queries.turnout 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 modes3.Turnout fT; + + private static List parameterNames = makeImmutableList("T"); + + private Match(final modes3.Turnout pT) { + this.fT = pT; + } + + @Override + public Object get(final String parameterName) { + switch(parameterName) { + case "T": return this.fT; + default: return null; + } + } + + @Override + public Object get(final int index) { + switch(index) { + case 0: return this.fT; + default: return null; + } + } + + public modes3.Turnout getT() { + return this.fT; + } + + @Override + public boolean set(final String parameterName, final Object newValue) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + if ("T".equals(parameterName) ) { + this.fT = (modes3.Turnout) newValue; + return true; + } + return false; + } + + public void setT(final modes3.Turnout pT) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fT = pT; + } + + @Override + public String patternName() { + return "modes3.queries.turnout"; + } + + @Override + public List parameterNames() { + return Turnout.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fT}; + } + + @Override + public Turnout.Match toImmutable() { + return isMutable() ? newMatch(fT) : this; + } + + @Override + public String prettyPrint() { + StringBuilder result = new StringBuilder(); + result.append("\"T\"=" + prettyPrintValue(fT)); + return result.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(fT); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) { + return false; + } + if ((obj instanceof Turnout.Match)) { + Turnout.Match other = (Turnout.Match) obj; + return Objects.equals(fT, other.fT); + } 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 Turnout specification() { + return Turnout.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 Turnout.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 pT the fixed value of pattern parameter T, or null if not bound. + * @return the new, mutable (partial) match object. + * + */ + public static Turnout.Match newMutableMatch(final modes3.Turnout pT) { + return new Mutable(pT); + } + + /** + * 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. + * @return the (partial) match object. + * + */ + public static Turnout.Match newMatch(final modes3.Turnout pT) { + return new Immutable(pT); + } + + private static final class Mutable extends Turnout.Match { + Mutable(final modes3.Turnout pT) { + super(pT); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends Turnout.Match { + Immutable(final modes3.Turnout pT) { + super(pT); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the modes3.queries.turnout 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 turnout(T : Turnout) {
+   * 	Turnout(T);
+   * }
+   * 
+ * + * @see Match + * @see Turnout + * + */ + 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 Turnout.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 Turnout.Matcher create() { + return new Matcher(); + } + + private static final int POSITION_T = 0; + + private static final Logger LOGGER = ViatraQueryLoggingUtil.getLogger(Turnout.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. + * @return matches represented as a Match object. + * + */ + public Collection getAllMatches(final modes3.Turnout pT) { + return rawStreamAllMatches(new Object[]{pT}).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. + * @return a stream of matches represented as a Match object. + * + */ + public Stream streamAllMatches(final modes3.Turnout pT) { + return rawStreamAllMatches(new Object[]{pT}); + } + + /** + * 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. + * @return a match represented as a Match object, or null if no match is found. + * + */ + public Optional getOneArbitraryMatch(final modes3.Turnout pT) { + return rawGetOneArbitraryMatch(new Object[]{pT}); + } + + /** + * 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. + * @return true if the input is a valid (partial) match of the pattern. + * + */ + public boolean hasMatch(final modes3.Turnout pT) { + return rawHasMatch(new Object[]{pT}); + } + + /** + * 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. + * @return the number of pattern matches found. + * + */ + public int countMatches(final modes3.Turnout pT) { + return rawCountMatches(new Object[]{pT}); + } + + /** + * 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 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 modes3.Turnout pT, final Consumer processor) { + return rawForOneArbitraryMatch(new Object[]{pT}, 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. + * @return the (partial) match object. + * + */ + public Turnout.Match newMatch(final modes3.Turnout pT) { + return Turnout.Match.newMatch(pT); + } + + /** + * 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(modes3.Turnout.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()); + } + + @Override + protected Turnout.Match tupleToMatch(final Tuple t) { + try { + return Turnout.Match.newMatch((modes3.Turnout) t.get(POSITION_T)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected Turnout.Match arrayToMatch(final Object[] match) { + try { + return Turnout.Match.newMatch((modes3.Turnout) match[POSITION_T]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected Turnout.Match arrayToMatchMutable(final Object[] match) { + try { + return Turnout.Match.newMutableMatch((modes3.Turnout) match[POSITION_T]); + } 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 Turnout.instance(); + } + } + + private Turnout() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static Turnout instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected Turnout.Matcher instantiate(final ViatraQueryEngine engine) { + return Turnout.Matcher.on(engine); + } + + @Override + public Turnout.Matcher instantiate() { + return Turnout.Matcher.create(); + } + + @Override + public Turnout.Match newEmptyMatch() { + return Turnout.Match.newEmptyMatch(); + } + + @Override + public Turnout.Match newMatch(final Object... parameters) { + return Turnout.Match.newMatch((modes3.Turnout) parameters[0]); + } + + /** + * Inner class allowing the singleton instance of {@link Turnout} to be created + * not at the class load time of the outer class, + * but rather at the first call to {@link Turnout#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private static final Turnout INSTANCE = new Turnout(); + + /** + * 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 static final Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private static final Turnout.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_T = new PParameter("T", "modes3.Turnout", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("http://www.ece.mcgill.ca/wcet/modes3", "Turnout")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_T); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "modes3.queries.turnout"; + } + + @Override + public List getParameterNames() { + return Arrays.asList("T"); + } + + @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"); + new TypeConstraint(body, Tuples.flatTupleOf(var_T), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Turnout"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_T, parameter_T) + )); + // Turnout(T) + new TypeConstraint(body, Tuples.flatTupleOf(var_T), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Turnout"))); + bodies.add(body); + } + return bodies; + } + } +} diff --git a/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/TurnoutConnectedToBothOutputs.java b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/TurnoutConnectedToBothOutputs.java new file mode 100644 index 00000000..674bb275 --- /dev/null +++ b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/TurnoutConnectedToBothOutputs.java @@ -0,0 +1,589 @@ +/** + * Generated from platform:/resource/ca.mcgill.rtgmrt.example.modes3/src/modes3/queries/Modes3Queries.vql + */ +package modes3.queries; + +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 modes3.Turnout; +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 = "turnoutConnectedToBothOutputs", severity = "error", key = { T })
+ *         pattern turnoutConnectedToBothOutputs(T : Turnout) {
+ *         	Turnout.straight(T, Straight);
+ *         	Turnout.divergent(T, Divergent);
+ *         	Segment.connectedTo(T, Straight);
+ *         	Segment.connectedTo(T, Divergent);
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class TurnoutConnectedToBothOutputs extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the modes3.queries.turnoutConnectedToBothOutputs 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 Turnout fT; + + private static List parameterNames = makeImmutableList("T"); + + private Match(final Turnout pT) { + this.fT = pT; + } + + @Override + public Object get(final String parameterName) { + switch(parameterName) { + case "T": return this.fT; + default: return null; + } + } + + @Override + public Object get(final int index) { + switch(index) { + case 0: return this.fT; + default: return null; + } + } + + public Turnout getT() { + return this.fT; + } + + @Override + public boolean set(final String parameterName, final Object newValue) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + if ("T".equals(parameterName) ) { + this.fT = (Turnout) newValue; + return true; + } + return false; + } + + public void setT(final Turnout pT) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fT = pT; + } + + @Override + public String patternName() { + return "modes3.queries.turnoutConnectedToBothOutputs"; + } + + @Override + public List parameterNames() { + return TurnoutConnectedToBothOutputs.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fT}; + } + + @Override + public TurnoutConnectedToBothOutputs.Match toImmutable() { + return isMutable() ? newMatch(fT) : this; + } + + @Override + public String prettyPrint() { + StringBuilder result = new StringBuilder(); + result.append("\"T\"=" + prettyPrintValue(fT)); + return result.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(fT); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) { + return false; + } + if ((obj instanceof TurnoutConnectedToBothOutputs.Match)) { + TurnoutConnectedToBothOutputs.Match other = (TurnoutConnectedToBothOutputs.Match) obj; + return Objects.equals(fT, other.fT); + } 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 TurnoutConnectedToBothOutputs specification() { + return TurnoutConnectedToBothOutputs.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 TurnoutConnectedToBothOutputs.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 pT the fixed value of pattern parameter T, or null if not bound. + * @return the new, mutable (partial) match object. + * + */ + public static TurnoutConnectedToBothOutputs.Match newMutableMatch(final Turnout pT) { + return new Mutable(pT); + } + + /** + * 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. + * @return the (partial) match object. + * + */ + public static TurnoutConnectedToBothOutputs.Match newMatch(final Turnout pT) { + return new Immutable(pT); + } + + private static final class Mutable extends TurnoutConnectedToBothOutputs.Match { + Mutable(final Turnout pT) { + super(pT); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends TurnoutConnectedToBothOutputs.Match { + Immutable(final Turnout pT) { + super(pT); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the modes3.queries.turnoutConnectedToBothOutputs 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 = "turnoutConnectedToBothOutputs", severity = "error", key = { T })
+   * pattern turnoutConnectedToBothOutputs(T : Turnout) {
+   * 	Turnout.straight(T, Straight);
+   * 	Turnout.divergent(T, Divergent);
+   * 	Segment.connectedTo(T, Straight);
+   * 	Segment.connectedTo(T, Divergent);
+   * }
+   * 
+ * + * @see Match + * @see TurnoutConnectedToBothOutputs + * + */ + 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 TurnoutConnectedToBothOutputs.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 TurnoutConnectedToBothOutputs.Matcher create() { + return new Matcher(); + } + + private static final int POSITION_T = 0; + + private static final Logger LOGGER = ViatraQueryLoggingUtil.getLogger(TurnoutConnectedToBothOutputs.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. + * @return matches represented as a Match object. + * + */ + public Collection getAllMatches(final Turnout pT) { + return rawStreamAllMatches(new Object[]{pT}).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. + * @return a stream of matches represented as a Match object. + * + */ + public Stream streamAllMatches(final Turnout pT) { + return rawStreamAllMatches(new Object[]{pT}); + } + + /** + * 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. + * @return a match represented as a Match object, or null if no match is found. + * + */ + public Optional getOneArbitraryMatch(final Turnout pT) { + return rawGetOneArbitraryMatch(new Object[]{pT}); + } + + /** + * 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. + * @return true if the input is a valid (partial) match of the pattern. + * + */ + public boolean hasMatch(final Turnout pT) { + return rawHasMatch(new Object[]{pT}); + } + + /** + * 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. + * @return the number of pattern matches found. + * + */ + public int countMatches(final Turnout pT) { + return rawCountMatches(new Object[]{pT}); + } + + /** + * 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 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 Turnout pT, final Consumer processor) { + return rawForOneArbitraryMatch(new Object[]{pT}, 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. + * @return the (partial) match object. + * + */ + public TurnoutConnectedToBothOutputs.Match newMatch(final Turnout pT) { + return TurnoutConnectedToBothOutputs.Match.newMatch(pT); + } + + /** + * 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(Turnout.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()); + } + + @Override + protected TurnoutConnectedToBothOutputs.Match tupleToMatch(final Tuple t) { + try { + return TurnoutConnectedToBothOutputs.Match.newMatch((Turnout) t.get(POSITION_T)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected TurnoutConnectedToBothOutputs.Match arrayToMatch(final Object[] match) { + try { + return TurnoutConnectedToBothOutputs.Match.newMatch((Turnout) match[POSITION_T]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected TurnoutConnectedToBothOutputs.Match arrayToMatchMutable(final Object[] match) { + try { + return TurnoutConnectedToBothOutputs.Match.newMutableMatch((Turnout) match[POSITION_T]); + } 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 TurnoutConnectedToBothOutputs.instance(); + } + } + + private TurnoutConnectedToBothOutputs() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static TurnoutConnectedToBothOutputs instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected TurnoutConnectedToBothOutputs.Matcher instantiate(final ViatraQueryEngine engine) { + return TurnoutConnectedToBothOutputs.Matcher.on(engine); + } + + @Override + public TurnoutConnectedToBothOutputs.Matcher instantiate() { + return TurnoutConnectedToBothOutputs.Matcher.create(); + } + + @Override + public TurnoutConnectedToBothOutputs.Match newEmptyMatch() { + return TurnoutConnectedToBothOutputs.Match.newEmptyMatch(); + } + + @Override + public TurnoutConnectedToBothOutputs.Match newMatch(final Object... parameters) { + return TurnoutConnectedToBothOutputs.Match.newMatch((modes3.Turnout) parameters[0]); + } + + /** + * Inner class allowing the singleton instance of {@link TurnoutConnectedToBothOutputs} to be created + * not at the class load time of the outer class, + * but rather at the first call to {@link TurnoutConnectedToBothOutputs#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private static final TurnoutConnectedToBothOutputs INSTANCE = new TurnoutConnectedToBothOutputs(); + + /** + * 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 static final Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private static final TurnoutConnectedToBothOutputs.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_T = new PParameter("T", "modes3.Turnout", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("http://www.ece.mcgill.ca/wcet/modes3", "Turnout")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_T); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "modes3.queries.turnoutConnectedToBothOutputs"; + } + + @Override + public List getParameterNames() { + return Arrays.asList("T"); + } + + @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_Straight = body.getOrCreateVariableByName("Straight"); + PVariable var_Divergent = body.getOrCreateVariableByName("Divergent"); + new TypeConstraint(body, Tuples.flatTupleOf(var_T), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Turnout"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_T, parameter_T) + )); + // Turnout.straight(T, Straight) + new TypeConstraint(body, Tuples.flatTupleOf(var_T), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Turnout"))); + PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_T, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Turnout", "straight"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + new Equality(body, var__virtual_0_, var_Straight); + // Turnout.divergent(T, Divergent) + new TypeConstraint(body, Tuples.flatTupleOf(var_T), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Turnout"))); + PVariable var__virtual_1_ = body.getOrCreateVariableByName(".virtual{1}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_T, var__virtual_1_), new EStructuralFeatureInstancesKey(getFeatureLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Turnout", "divergent"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_1_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + new Equality(body, var__virtual_1_, var_Divergent); + // Segment.connectedTo(T, Straight) + new TypeConstraint(body, Tuples.flatTupleOf(var_T), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + PVariable var__virtual_2_ = body.getOrCreateVariableByName(".virtual{2}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_T, var__virtual_2_), new EStructuralFeatureInstancesKey(getFeatureLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment", "connectedTo"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_2_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + new Equality(body, var__virtual_2_, var_Straight); + // Segment.connectedTo(T, Divergent) + new TypeConstraint(body, Tuples.flatTupleOf(var_T), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + PVariable var__virtual_3_ = body.getOrCreateVariableByName(".virtual{3}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_T, var__virtual_3_), new EStructuralFeatureInstancesKey(getFeatureLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment", "connectedTo"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_3_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + new Equality(body, var__virtual_3_, var_Divergent); + bodies.add(body); + } + { + PAnnotation annotation = new PAnnotation("Constraint"); + annotation.addAttribute("message", "turnoutConnectedToBothOutputs"); + annotation.addAttribute("severity", "error"); + annotation.addAttribute("key", Arrays.asList(new Object[] { + new ParameterReference("T") + })); + addAnnotation(annotation); + } + return bodies; + } + } +} diff --git a/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/TurnoutInSegments.java b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/TurnoutInSegments.java new file mode 100644 index 00000000..9c9a5d18 --- /dev/null +++ b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/TurnoutInSegments.java @@ -0,0 +1,564 @@ +/** + * Generated from platform:/resource/ca.mcgill.rtgmrt.example.modes3/src/modes3/queries/Modes3Queries.vql + */ +package modes3.queries; + +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 modes3.Turnout; +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 = "turnoutInSegments", severity = "error", key = { T })
+ *         pattern turnoutInSegments(T : Turnout) {
+ *         	Modes3ModelRoot.segments(_, T);
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class TurnoutInSegments extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the modes3.queries.turnoutInSegments 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 Turnout fT; + + private static List parameterNames = makeImmutableList("T"); + + private Match(final Turnout pT) { + this.fT = pT; + } + + @Override + public Object get(final String parameterName) { + switch(parameterName) { + case "T": return this.fT; + default: return null; + } + } + + @Override + public Object get(final int index) { + switch(index) { + case 0: return this.fT; + default: return null; + } + } + + public Turnout getT() { + return this.fT; + } + + @Override + public boolean set(final String parameterName, final Object newValue) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + if ("T".equals(parameterName) ) { + this.fT = (Turnout) newValue; + return true; + } + return false; + } + + public void setT(final Turnout pT) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fT = pT; + } + + @Override + public String patternName() { + return "modes3.queries.turnoutInSegments"; + } + + @Override + public List parameterNames() { + return TurnoutInSegments.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fT}; + } + + @Override + public TurnoutInSegments.Match toImmutable() { + return isMutable() ? newMatch(fT) : this; + } + + @Override + public String prettyPrint() { + StringBuilder result = new StringBuilder(); + result.append("\"T\"=" + prettyPrintValue(fT)); + return result.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(fT); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) { + return false; + } + if ((obj instanceof TurnoutInSegments.Match)) { + TurnoutInSegments.Match other = (TurnoutInSegments.Match) obj; + return Objects.equals(fT, other.fT); + } 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 TurnoutInSegments specification() { + return TurnoutInSegments.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 TurnoutInSegments.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 pT the fixed value of pattern parameter T, or null if not bound. + * @return the new, mutable (partial) match object. + * + */ + public static TurnoutInSegments.Match newMutableMatch(final Turnout pT) { + return new Mutable(pT); + } + + /** + * 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. + * @return the (partial) match object. + * + */ + public static TurnoutInSegments.Match newMatch(final Turnout pT) { + return new Immutable(pT); + } + + private static final class Mutable extends TurnoutInSegments.Match { + Mutable(final Turnout pT) { + super(pT); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends TurnoutInSegments.Match { + Immutable(final Turnout pT) { + super(pT); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the modes3.queries.turnoutInSegments 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 = "turnoutInSegments", severity = "error", key = { T })
+   * pattern turnoutInSegments(T : Turnout) {
+   * 	Modes3ModelRoot.segments(_, T);
+   * }
+   * 
+ * + * @see Match + * @see TurnoutInSegments + * + */ + 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 TurnoutInSegments.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 TurnoutInSegments.Matcher create() { + return new Matcher(); + } + + private static final int POSITION_T = 0; + + private static final Logger LOGGER = ViatraQueryLoggingUtil.getLogger(TurnoutInSegments.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. + * @return matches represented as a Match object. + * + */ + public Collection getAllMatches(final Turnout pT) { + return rawStreamAllMatches(new Object[]{pT}).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. + * @return a stream of matches represented as a Match object. + * + */ + public Stream streamAllMatches(final Turnout pT) { + return rawStreamAllMatches(new Object[]{pT}); + } + + /** + * 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. + * @return a match represented as a Match object, or null if no match is found. + * + */ + public Optional getOneArbitraryMatch(final Turnout pT) { + return rawGetOneArbitraryMatch(new Object[]{pT}); + } + + /** + * 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. + * @return true if the input is a valid (partial) match of the pattern. + * + */ + public boolean hasMatch(final Turnout pT) { + return rawHasMatch(new Object[]{pT}); + } + + /** + * 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. + * @return the number of pattern matches found. + * + */ + public int countMatches(final Turnout pT) { + return rawCountMatches(new Object[]{pT}); + } + + /** + * 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 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 Turnout pT, final Consumer processor) { + return rawForOneArbitraryMatch(new Object[]{pT}, 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. + * @return the (partial) match object. + * + */ + public TurnoutInSegments.Match newMatch(final Turnout pT) { + return TurnoutInSegments.Match.newMatch(pT); + } + + /** + * 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(Turnout.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()); + } + + @Override + protected TurnoutInSegments.Match tupleToMatch(final Tuple t) { + try { + return TurnoutInSegments.Match.newMatch((Turnout) t.get(POSITION_T)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected TurnoutInSegments.Match arrayToMatch(final Object[] match) { + try { + return TurnoutInSegments.Match.newMatch((Turnout) match[POSITION_T]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected TurnoutInSegments.Match arrayToMatchMutable(final Object[] match) { + try { + return TurnoutInSegments.Match.newMutableMatch((Turnout) match[POSITION_T]); + } 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 TurnoutInSegments.instance(); + } + } + + private TurnoutInSegments() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static TurnoutInSegments instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected TurnoutInSegments.Matcher instantiate(final ViatraQueryEngine engine) { + return TurnoutInSegments.Matcher.on(engine); + } + + @Override + public TurnoutInSegments.Matcher instantiate() { + return TurnoutInSegments.Matcher.create(); + } + + @Override + public TurnoutInSegments.Match newEmptyMatch() { + return TurnoutInSegments.Match.newEmptyMatch(); + } + + @Override + public TurnoutInSegments.Match newMatch(final Object... parameters) { + return TurnoutInSegments.Match.newMatch((modes3.Turnout) parameters[0]); + } + + /** + * Inner class allowing the singleton instance of {@link TurnoutInSegments} to be created + * not at the class load time of the outer class, + * but rather at the first call to {@link TurnoutInSegments#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private static final TurnoutInSegments INSTANCE = new TurnoutInSegments(); + + /** + * 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 static final Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private static final TurnoutInSegments.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_T = new PParameter("T", "modes3.Turnout", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("http://www.ece.mcgill.ca/wcet/modes3", "Turnout")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_T); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "modes3.queries.turnoutInSegments"; + } + + @Override + public List getParameterNames() { + return Arrays.asList("T"); + } + + @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___0_ = body.getOrCreateVariableByName("_<0>"); + new TypeConstraint(body, Tuples.flatTupleOf(var_T), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Turnout"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_T, parameter_T) + )); + // Modes3ModelRoot.segments(_, T) + new TypeConstraint(body, Tuples.flatTupleOf(var___0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Modes3ModelRoot"))); + PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); + new TypeConstraint(body, Tuples.flatTupleOf(var___0_, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Modes3ModelRoot", "segments"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + new Equality(body, var__virtual_0_, var_T); + bodies.add(body); + } + { + PAnnotation annotation = new PAnnotation("Constraint"); + annotation.addAttribute("message", "turnoutInSegments"); + annotation.addAttribute("severity", "error"); + annotation.addAttribute("key", Arrays.asList(new Object[] { + new ParameterReference("T") + })); + addAnnotation(annotation); + } + return bodies; + } + } +} diff --git a/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/TurnoutOutput.java b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/TurnoutOutput.java new file mode 100644 index 00000000..87cccfde --- /dev/null +++ b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/TurnoutOutput.java @@ -0,0 +1,727 @@ +/** + * Generated from platform:/resource/ca.mcgill.rtgmrt.example.modes3/src/modes3/queries/Modes3Queries.vql + */ +package modes3.queries; + +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 modes3.Segment; +import modes3.Turnout; +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 turnoutOutput(T : Turnout, S : Segment) {
+ *         	Turnout.straight(T, S);
+ *         } or {
+ *         	Turnout.divergent(T, S);
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class TurnoutOutput extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the modes3.queries.turnoutOutput 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 Turnout fT; + + private Segment fS; + + private static List parameterNames = makeImmutableList("T", "S"); + + private Match(final Turnout pT, final Segment pS) { + this.fT = pT; + this.fS = pS; + } + + @Override + public Object get(final String parameterName) { + switch(parameterName) { + case "T": return this.fT; + case "S": return this.fS; + default: return null; + } + } + + @Override + public Object get(final int index) { + switch(index) { + case 0: return this.fT; + case 1: return this.fS; + default: return null; + } + } + + public Turnout getT() { + return this.fT; + } + + public Segment getS() { + return this.fS; + } + + @Override + public boolean set(final String parameterName, final Object newValue) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + if ("T".equals(parameterName) ) { + this.fT = (Turnout) newValue; + return true; + } + if ("S".equals(parameterName) ) { + this.fS = (Segment) newValue; + return true; + } + return false; + } + + public void setT(final Turnout pT) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fT = pT; + } + + public void setS(final Segment pS) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fS = pS; + } + + @Override + public String patternName() { + return "modes3.queries.turnoutOutput"; + } + + @Override + public List parameterNames() { + return TurnoutOutput.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fT, fS}; + } + + @Override + public TurnoutOutput.Match toImmutable() { + return isMutable() ? newMatch(fT, fS) : this; + } + + @Override + public String prettyPrint() { + StringBuilder result = new StringBuilder(); + result.append("\"T\"=" + prettyPrintValue(fT) + ", "); + result.append("\"S\"=" + prettyPrintValue(fS)); + return result.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(fT, fS); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) { + return false; + } + if ((obj instanceof TurnoutOutput.Match)) { + TurnoutOutput.Match other = (TurnoutOutput.Match) obj; + return Objects.equals(fT, other.fT) && 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 TurnoutOutput specification() { + return TurnoutOutput.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 TurnoutOutput.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 pS the fixed value of pattern parameter S, or null if not bound. + * @return the new, mutable (partial) match object. + * + */ + public static TurnoutOutput.Match newMutableMatch(final Turnout pT, final Segment pS) { + return new Mutable(pT, 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 pT the fixed value of pattern parameter T, or null if not bound. + * @param pS the fixed value of pattern parameter S, or null if not bound. + * @return the (partial) match object. + * + */ + public static TurnoutOutput.Match newMatch(final Turnout pT, final Segment pS) { + return new Immutable(pT, pS); + } + + private static final class Mutable extends TurnoutOutput.Match { + Mutable(final Turnout pT, final Segment pS) { + super(pT, pS); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends TurnoutOutput.Match { + Immutable(final Turnout pT, final Segment pS) { + super(pT, pS); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the modes3.queries.turnoutOutput 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 turnoutOutput(T : Turnout, S : Segment) {
+   * 	Turnout.straight(T, S);
+   * } or {
+   * 	Turnout.divergent(T, S);
+   * }
+   * 
+ * + * @see Match + * @see TurnoutOutput + * + */ + 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 TurnoutOutput.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 TurnoutOutput.Matcher create() { + return new Matcher(); + } + + private static final int POSITION_T = 0; + + private static final int POSITION_S = 1; + + private static final Logger LOGGER = ViatraQueryLoggingUtil.getLogger(TurnoutOutput.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 pS the fixed value of pattern parameter S, or null if not bound. + * @return matches represented as a Match object. + * + */ + public Collection getAllMatches(final Turnout pT, final Segment pS) { + return rawStreamAllMatches(new Object[]{pT, 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 pT the fixed value of pattern parameter T, or null if not bound. + * @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 Turnout pT, final Segment pS) { + return rawStreamAllMatches(new Object[]{pT, 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 pT the fixed value of pattern parameter T, or null if not bound. + * @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 Turnout pT, final Segment pS) { + return rawGetOneArbitraryMatch(new Object[]{pT, 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 pT the fixed value of pattern parameter T, or null if not bound. + * @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 Turnout pT, final Segment pS) { + return rawHasMatch(new Object[]{pT, pS}); + } + + /** + * 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 pS the fixed value of pattern parameter S, or null if not bound. + * @return the number of pattern matches found. + * + */ + public int countMatches(final Turnout pT, final Segment pS) { + return rawCountMatches(new Object[]{pT, 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 pT the fixed value of pattern parameter T, or null if not bound. + * @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 Turnout pT, final Segment pS, final Consumer processor) { + return rawForOneArbitraryMatch(new Object[]{pT, 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 pT the fixed value of pattern parameter T, or null if not bound. + * @param pS the fixed value of pattern parameter S, or null if not bound. + * @return the (partial) match object. + * + */ + public TurnoutOutput.Match newMatch(final Turnout pT, final Segment pS) { + return TurnoutOutput.Match.newMatch(pT, pS); + } + + /** + * 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(Turnout.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 TurnoutOutput.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 Segment pS) { + return rawStreamAllValuesOfT(new Object[]{null, pS}); + } + + /** + * 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 TurnoutOutput.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 Segment pS) { + return rawStreamAllValuesOfT(new Object[]{null, pS}).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 + * + */ + protected Stream rawStreamAllValuesOfS(final Object[] parameters) { + return rawStreamAllValues(POSITION_S, parameters).map(Segment.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 TurnoutOutput.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 Turnout pT) { + return rawStreamAllValuesOfS(new Object[]{pT, null}); + } + + /** + * 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 TurnoutOutput.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 Turnout pT) { + return rawStreamAllValuesOfS(new Object[]{pT, null}).collect(Collectors.toSet()); + } + + @Override + protected TurnoutOutput.Match tupleToMatch(final Tuple t) { + try { + return TurnoutOutput.Match.newMatch((Turnout) t.get(POSITION_T), (Segment) t.get(POSITION_S)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected TurnoutOutput.Match arrayToMatch(final Object[] match) { + try { + return TurnoutOutput.Match.newMatch((Turnout) match[POSITION_T], (Segment) match[POSITION_S]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected TurnoutOutput.Match arrayToMatchMutable(final Object[] match) { + try { + return TurnoutOutput.Match.newMutableMatch((Turnout) match[POSITION_T], (Segment) 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 TurnoutOutput.instance(); + } + } + + private TurnoutOutput() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static TurnoutOutput instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected TurnoutOutput.Matcher instantiate(final ViatraQueryEngine engine) { + return TurnoutOutput.Matcher.on(engine); + } + + @Override + public TurnoutOutput.Matcher instantiate() { + return TurnoutOutput.Matcher.create(); + } + + @Override + public TurnoutOutput.Match newEmptyMatch() { + return TurnoutOutput.Match.newEmptyMatch(); + } + + @Override + public TurnoutOutput.Match newMatch(final Object... parameters) { + return TurnoutOutput.Match.newMatch((modes3.Turnout) parameters[0], (modes3.Segment) parameters[1]); + } + + /** + * Inner class allowing the singleton instance of {@link TurnoutOutput} to be created + * not at the class load time of the outer class, + * but rather at the first call to {@link TurnoutOutput#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private static final TurnoutOutput INSTANCE = new TurnoutOutput(); + + /** + * 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 static final Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private static final TurnoutOutput.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_T = new PParameter("T", "modes3.Turnout", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("http://www.ece.mcgill.ca/wcet/modes3", "Turnout")), PParameterDirection.INOUT); + + private final PParameter parameter_S = new PParameter("S", "modes3.Segment", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("http://www.ece.mcgill.ca/wcet/modes3", "Segment")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_T, parameter_S); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "modes3.queries.turnoutOutput"; + } + + @Override + public List getParameterNames() { + return Arrays.asList("T","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_T = body.getOrCreateVariableByName("T"); + PVariable var_S = body.getOrCreateVariableByName("S"); + new TypeConstraint(body, Tuples.flatTupleOf(var_T), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Turnout"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_S), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_T, parameter_T), + new ExportedParameter(body, var_S, parameter_S) + )); + // Turnout.straight(T, S) + new TypeConstraint(body, Tuples.flatTupleOf(var_T), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Turnout"))); + PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_T, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Turnout", "straight"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + new Equality(body, var__virtual_0_, var_S); + bodies.add(body); + } + { + PBody body = new PBody(this); + PVariable var_T = body.getOrCreateVariableByName("T"); + PVariable var_S = body.getOrCreateVariableByName("S"); + new TypeConstraint(body, Tuples.flatTupleOf(var_T), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Turnout"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_S), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_T, parameter_T), + new ExportedParameter(body, var_S, parameter_S) + )); + // Turnout.divergent(T, S) + new TypeConstraint(body, Tuples.flatTupleOf(var_T), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Turnout"))); + PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_T, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Turnout", "divergent"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + new Equality(body, var__virtual_0_, var_S); + bodies.add(body); + } + return bodies; + } + } +} diff --git a/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/TurnoutOutputsAreSame.java b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/TurnoutOutputsAreSame.java new file mode 100644 index 00000000..ba59d45c --- /dev/null +++ b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/TurnoutOutputsAreSame.java @@ -0,0 +1,572 @@ +/** + * Generated from platform:/resource/ca.mcgill.rtgmrt.example.modes3/src/modes3/queries/Modes3Queries.vql + */ +package modes3.queries; + +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 modes3.Turnout; +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 = "turnoutOutputsAreSame", severity = "error", key = { T })
+ *         pattern turnoutOutputsAreSame(T : Turnout) {
+ *         	Turnout.straight(T, S);
+ *         	Turnout.divergent(T, S);
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class TurnoutOutputsAreSame extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the modes3.queries.turnoutOutputsAreSame 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 Turnout fT; + + private static List parameterNames = makeImmutableList("T"); + + private Match(final Turnout pT) { + this.fT = pT; + } + + @Override + public Object get(final String parameterName) { + switch(parameterName) { + case "T": return this.fT; + default: return null; + } + } + + @Override + public Object get(final int index) { + switch(index) { + case 0: return this.fT; + default: return null; + } + } + + public Turnout getT() { + return this.fT; + } + + @Override + public boolean set(final String parameterName, final Object newValue) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + if ("T".equals(parameterName) ) { + this.fT = (Turnout) newValue; + return true; + } + return false; + } + + public void setT(final Turnout pT) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fT = pT; + } + + @Override + public String patternName() { + return "modes3.queries.turnoutOutputsAreSame"; + } + + @Override + public List parameterNames() { + return TurnoutOutputsAreSame.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fT}; + } + + @Override + public TurnoutOutputsAreSame.Match toImmutable() { + return isMutable() ? newMatch(fT) : this; + } + + @Override + public String prettyPrint() { + StringBuilder result = new StringBuilder(); + result.append("\"T\"=" + prettyPrintValue(fT)); + return result.toString(); + } + + @Override + public int hashCode() { + return Objects.hash(fT); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) + return true; + if (obj == null) { + return false; + } + if ((obj instanceof TurnoutOutputsAreSame.Match)) { + TurnoutOutputsAreSame.Match other = (TurnoutOutputsAreSame.Match) obj; + return Objects.equals(fT, other.fT); + } 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 TurnoutOutputsAreSame specification() { + return TurnoutOutputsAreSame.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 TurnoutOutputsAreSame.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 pT the fixed value of pattern parameter T, or null if not bound. + * @return the new, mutable (partial) match object. + * + */ + public static TurnoutOutputsAreSame.Match newMutableMatch(final Turnout pT) { + return new Mutable(pT); + } + + /** + * 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. + * @return the (partial) match object. + * + */ + public static TurnoutOutputsAreSame.Match newMatch(final Turnout pT) { + return new Immutable(pT); + } + + private static final class Mutable extends TurnoutOutputsAreSame.Match { + Mutable(final Turnout pT) { + super(pT); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends TurnoutOutputsAreSame.Match { + Immutable(final Turnout pT) { + super(pT); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the modes3.queries.turnoutOutputsAreSame 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 = "turnoutOutputsAreSame", severity = "error", key = { T })
+   * pattern turnoutOutputsAreSame(T : Turnout) {
+   * 	Turnout.straight(T, S);
+   * 	Turnout.divergent(T, S);
+   * }
+   * 
+ * + * @see Match + * @see TurnoutOutputsAreSame + * + */ + 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 TurnoutOutputsAreSame.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 TurnoutOutputsAreSame.Matcher create() { + return new Matcher(); + } + + private static final int POSITION_T = 0; + + private static final Logger LOGGER = ViatraQueryLoggingUtil.getLogger(TurnoutOutputsAreSame.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. + * @return matches represented as a Match object. + * + */ + public Collection getAllMatches(final Turnout pT) { + return rawStreamAllMatches(new Object[]{pT}).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. + * @return a stream of matches represented as a Match object. + * + */ + public Stream streamAllMatches(final Turnout pT) { + return rawStreamAllMatches(new Object[]{pT}); + } + + /** + * 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. + * @return a match represented as a Match object, or null if no match is found. + * + */ + public Optional getOneArbitraryMatch(final Turnout pT) { + return rawGetOneArbitraryMatch(new Object[]{pT}); + } + + /** + * 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. + * @return true if the input is a valid (partial) match of the pattern. + * + */ + public boolean hasMatch(final Turnout pT) { + return rawHasMatch(new Object[]{pT}); + } + + /** + * 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. + * @return the number of pattern matches found. + * + */ + public int countMatches(final Turnout pT) { + return rawCountMatches(new Object[]{pT}); + } + + /** + * 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 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 Turnout pT, final Consumer processor) { + return rawForOneArbitraryMatch(new Object[]{pT}, 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. + * @return the (partial) match object. + * + */ + public TurnoutOutputsAreSame.Match newMatch(final Turnout pT) { + return TurnoutOutputsAreSame.Match.newMatch(pT); + } + + /** + * 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(Turnout.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()); + } + + @Override + protected TurnoutOutputsAreSame.Match tupleToMatch(final Tuple t) { + try { + return TurnoutOutputsAreSame.Match.newMatch((Turnout) t.get(POSITION_T)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected TurnoutOutputsAreSame.Match arrayToMatch(final Object[] match) { + try { + return TurnoutOutputsAreSame.Match.newMatch((Turnout) match[POSITION_T]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected TurnoutOutputsAreSame.Match arrayToMatchMutable(final Object[] match) { + try { + return TurnoutOutputsAreSame.Match.newMutableMatch((Turnout) match[POSITION_T]); + } 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 TurnoutOutputsAreSame.instance(); + } + } + + private TurnoutOutputsAreSame() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static TurnoutOutputsAreSame instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected TurnoutOutputsAreSame.Matcher instantiate(final ViatraQueryEngine engine) { + return TurnoutOutputsAreSame.Matcher.on(engine); + } + + @Override + public TurnoutOutputsAreSame.Matcher instantiate() { + return TurnoutOutputsAreSame.Matcher.create(); + } + + @Override + public TurnoutOutputsAreSame.Match newEmptyMatch() { + return TurnoutOutputsAreSame.Match.newEmptyMatch(); + } + + @Override + public TurnoutOutputsAreSame.Match newMatch(final Object... parameters) { + return TurnoutOutputsAreSame.Match.newMatch((modes3.Turnout) parameters[0]); + } + + /** + * Inner class allowing the singleton instance of {@link TurnoutOutputsAreSame} to be created + * not at the class load time of the outer class, + * but rather at the first call to {@link TurnoutOutputsAreSame#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private static final TurnoutOutputsAreSame INSTANCE = new TurnoutOutputsAreSame(); + + /** + * 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 static final Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private static final TurnoutOutputsAreSame.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_T = new PParameter("T", "modes3.Turnout", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("http://www.ece.mcgill.ca/wcet/modes3", "Turnout")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_T); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "modes3.queries.turnoutOutputsAreSame"; + } + + @Override + public List getParameterNames() { + return Arrays.asList("T"); + } + + @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_S = body.getOrCreateVariableByName("S"); + new TypeConstraint(body, Tuples.flatTupleOf(var_T), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Turnout"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_T, parameter_T) + )); + // Turnout.straight(T, S) + new TypeConstraint(body, Tuples.flatTupleOf(var_T), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Turnout"))); + PVariable var__virtual_0_ = body.getOrCreateVariableByName(".virtual{0}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_T, var__virtual_0_), new EStructuralFeatureInstancesKey(getFeatureLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Turnout", "straight"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_0_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + new Equality(body, var__virtual_0_, var_S); + // Turnout.divergent(T, S) + new TypeConstraint(body, Tuples.flatTupleOf(var_T), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Turnout"))); + PVariable var__virtual_1_ = body.getOrCreateVariableByName(".virtual{1}"); + new TypeConstraint(body, Tuples.flatTupleOf(var_T, var__virtual_1_), new EStructuralFeatureInstancesKey(getFeatureLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Turnout", "divergent"))); + new TypeConstraint(body, Tuples.flatTupleOf(var__virtual_1_), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + new Equality(body, var__virtual_1_, var_S); + bodies.add(body); + } + { + PAnnotation annotation = new PAnnotation("Constraint"); + annotation.addAttribute("message", "turnoutOutputsAreSame"); + annotation.addAttribute("severity", "error"); + annotation.addAttribute("key", Arrays.asList(new Object[] { + new ParameterReference("T") + })); + addAnnotation(annotation); + } + return bodies; + } + } +} diff --git a/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/Unreachable.java b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/Unreachable.java new file mode 100644 index 00000000..a1b76f83 --- /dev/null +++ b/Domains/ca.mcgill.rtgmrt.example.modes3/vql-gen/modes3/queries/Unreachable.java @@ -0,0 +1,714 @@ +/** + * Generated from platform:/resource/ca.mcgill.rtgmrt.example.modes3/src/modes3/queries/Modes3Queries.vql + */ +package modes3.queries; + +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 modes3.Segment; +import modes3.queries.Reachable; +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(message = "unreachable", severity = "error", key = { S1, S2 })
+ *         pattern unreachable(S1 : Segment, S2 : Segment) {
+ *         	neg find reachable(S1, S2);
+ *         }
+ * 
+ * + * @see Matcher + * @see Match + * + */ +@SuppressWarnings("all") +public final class Unreachable extends BaseGeneratedEMFQuerySpecification { + /** + * Pattern-specific match representation of the modes3.queries.unreachable 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 Segment fS1; + + private Segment fS2; + + private static List parameterNames = makeImmutableList("S1", "S2"); + + private Match(final Segment pS1, final Segment pS2) { + this.fS1 = pS1; + this.fS2 = pS2; + } + + @Override + public Object get(final String parameterName) { + switch(parameterName) { + case "S1": return this.fS1; + case "S2": return this.fS2; + default: return null; + } + } + + @Override + public Object get(final int index) { + switch(index) { + case 0: return this.fS1; + case 1: return this.fS2; + default: return null; + } + } + + public Segment getS1() { + return this.fS1; + } + + public Segment 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 = (Segment) newValue; + return true; + } + if ("S2".equals(parameterName) ) { + this.fS2 = (Segment) newValue; + return true; + } + return false; + } + + public void setS1(final Segment pS1) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fS1 = pS1; + } + + public void setS2(final Segment pS2) { + if (!isMutable()) throw new java.lang.UnsupportedOperationException(); + this.fS2 = pS2; + } + + @Override + public String patternName() { + return "modes3.queries.unreachable"; + } + + @Override + public List parameterNames() { + return Unreachable.Match.parameterNames; + } + + @Override + public Object[] toArray() { + return new Object[]{fS1, fS2}; + } + + @Override + public Unreachable.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 Unreachable.Match)) { + Unreachable.Match other = (Unreachable.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 Unreachable specification() { + return Unreachable.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 Unreachable.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 Unreachable.Match newMutableMatch(final Segment pS1, final Segment 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 Unreachable.Match newMatch(final Segment pS1, final Segment pS2) { + return new Immutable(pS1, pS2); + } + + private static final class Mutable extends Unreachable.Match { + Mutable(final Segment pS1, final Segment pS2) { + super(pS1, pS2); + } + + @Override + public boolean isMutable() { + return true; + } + } + + private static final class Immutable extends Unreachable.Match { + Immutable(final Segment pS1, final Segment pS2) { + super(pS1, pS2); + } + + @Override + public boolean isMutable() { + return false; + } + } + } + + /** + * Generated pattern matcher API of the modes3.queries.unreachable 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 = "unreachable", severity = "error", key = { S1, S2 })
+   * pattern unreachable(S1 : Segment, S2 : Segment) {
+   * 	neg find reachable(S1, S2);
+   * }
+   * 
+ * + * @see Match + * @see Unreachable + * + */ + 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 Unreachable.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 Unreachable.Matcher create() { + return new Matcher(); + } + + private static final int POSITION_S1 = 0; + + private static final int POSITION_S2 = 1; + + private static final Logger LOGGER = ViatraQueryLoggingUtil.getLogger(Unreachable.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 Segment pS1, final Segment 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 Segment pS1, final Segment 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 Segment pS1, final Segment 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 Segment pS1, final Segment 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 Segment pS1, final Segment 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 Segment pS1, final Segment 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 Unreachable.Match newMatch(final Segment pS1, final Segment pS2) { + return Unreachable.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(Segment.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 Unreachable.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 Segment 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 Unreachable.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 Segment 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(Segment.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 Unreachable.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 Segment 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 Unreachable.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 Segment pS1) { + return rawStreamAllValuesOfS2(new Object[]{pS1, null}).collect(Collectors.toSet()); + } + + @Override + protected Unreachable.Match tupleToMatch(final Tuple t) { + try { + return Unreachable.Match.newMatch((Segment) t.get(POSITION_S1), (Segment) t.get(POSITION_S2)); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in tuple not properly typed!",e); + return null; + } + } + + @Override + protected Unreachable.Match arrayToMatch(final Object[] match) { + try { + return Unreachable.Match.newMatch((Segment) match[POSITION_S1], (Segment) match[POSITION_S2]); + } catch(ClassCastException e) { + LOGGER.error("Element(s) in array not properly typed!",e); + return null; + } + } + + @Override + protected Unreachable.Match arrayToMatchMutable(final Object[] match) { + try { + return Unreachable.Match.newMutableMatch((Segment) match[POSITION_S1], (Segment) 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 Unreachable.instance(); + } + } + + private Unreachable() { + super(GeneratedPQuery.INSTANCE); + } + + /** + * @return the singleton instance of the query specification + * @throws ViatraQueryRuntimeException if the pattern definition could not be loaded + * + */ + public static Unreachable instance() { + try{ + return LazyHolder.INSTANCE; + } catch (ExceptionInInitializerError err) { + throw processInitializerError(err); + } + } + + @Override + protected Unreachable.Matcher instantiate(final ViatraQueryEngine engine) { + return Unreachable.Matcher.on(engine); + } + + @Override + public Unreachable.Matcher instantiate() { + return Unreachable.Matcher.create(); + } + + @Override + public Unreachable.Match newEmptyMatch() { + return Unreachable.Match.newEmptyMatch(); + } + + @Override + public Unreachable.Match newMatch(final Object... parameters) { + return Unreachable.Match.newMatch((modes3.Segment) parameters[0], (modes3.Segment) parameters[1]); + } + + /** + * Inner class allowing the singleton instance of {@link Unreachable} to be created + * not at the class load time of the outer class, + * but rather at the first call to {@link Unreachable#instance()}. + * + *

This workaround is required e.g. to support recursion. + * + */ + private static class LazyHolder { + private static final Unreachable INSTANCE = new Unreachable(); + + /** + * 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 static final Object STATIC_INITIALIZER = ensureInitialized(); + + public static Object ensureInitialized() { + INSTANCE.ensureInitializedInternal(); + return null; + } + } + + private static class GeneratedPQuery extends BaseGeneratedEMFPQuery { + private static final Unreachable.GeneratedPQuery INSTANCE = new GeneratedPQuery(); + + private final PParameter parameter_S1 = new PParameter("S1", "modes3.Segment", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("http://www.ece.mcgill.ca/wcet/modes3", "Segment")), PParameterDirection.INOUT); + + private final PParameter parameter_S2 = new PParameter("S2", "modes3.Segment", new EClassTransitiveInstancesKey((EClass)getClassifierLiteralSafe("http://www.ece.mcgill.ca/wcet/modes3", "Segment")), PParameterDirection.INOUT); + + private final List parameters = Arrays.asList(parameter_S1, parameter_S2); + + private GeneratedPQuery() { + super(PVisibility.PUBLIC); + } + + @Override + public String getFullyQualifiedName() { + return "modes3.queries.unreachable"; + } + + @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("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + new TypeConstraint(body, Tuples.flatTupleOf(var_S2), new EClassTransitiveInstancesKey((EClass)getClassifierLiteral("http://www.ece.mcgill.ca/wcet/modes3", "Segment"))); + body.setSymbolicParameters(Arrays.asList( + new ExportedParameter(body, var_S1, parameter_S1), + new ExportedParameter(body, var_S2, parameter_S2) + )); + // neg find reachable(S1, S2) + new NegativePatternCall(body, Tuples.flatTupleOf(var_S1, var_S2), Reachable.instance().getInternalQueryRepresentation()); + bodies.add(body); + } + { + PAnnotation annotation = new PAnnotation("Constraint"); + annotation.addAttribute("message", "unreachable"); + annotation.addAttribute("severity", "error"); + annotation.addAttribute("key", Arrays.asList(new Object[] { + new ParameterReference("S1"), + new ParameterReference("S2") + })); + addAnnotation(annotation); + } + return bodies; + } + } +} -- cgit v1.2.3-54-g00ecf