Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

VIATRA/Query/UserDocumentation/AdvancedPatterns

Advanced query language topics in EMF-IncQuery

Working with EMaps in EMF-IncQuery

The eclipse.org EMF wiki gives a proper FAQ about the various modeling related issues, including the usage of EMap-s in your metamodel. With EMF-IncQuery you can even write your own queries to extract the key-value pairs from your instance model.

EMaps in your metamodel

  1. Creating the actual EMap type Create an EClass with the name [Type1]To[Type2]Map where [Type1] represents the key's type and the [Type2] represents the value's type.
  2. Set the Instance Type Name property of the newly created EClass to java.util.Map$Entry.
  3. Create an EAttribute or EReference named "key" and set the EDataType or EClass for it.
  4. Create an EAttribute or EReference called "value" and set the EDataType or EClass for it.

For example for an <EString, EString> EMap you would have an EClass named EStringToEStringMap if you follow the mentioned scheme.

To actually use this newly created type follow these steps:

  1. Create an EReference with its EClass set to be the map-entry class you created above.
  2. Set the Containment property of your EReference to be true.
  3. Set the upper-bound of your EReference to be -1 (unbounded).

For example an <EString, EString> map would result an EClass named EStringToEStringMap, if you follow the mentioned scheme.

EMaps in your instance model

The contents of the EMap instances can be modified like in every other instance model. One EStringToEstringMap instance will be used an a map entry (key-value pair).

Querying EMaps from EMF-IncQuery patterns

Here is an example query to extract the key-value pairs from an EMap

pattern emapPattern(K : EString, V : EString) {
   EMapTestElement(M);
   EMapTestElement.map(M, Map);
   EStringToEStringMap.key(Map, K);
   EStringToEStringMap.value(Map, V);
}

Parts of this overview are based on the http://wiki.eclipse.org/index.php/EMF-FAQ#How_do_i_create_a_Map_in_EMF.3F page.


Recursive queries in EMF-IncQuery

As explained on the query language introduction page, EMF-IncQuery supports pattern composition via the find keyword. Does it support recursive composition, i.e. patterns circularly referencing each other? Yes, it does, albeit with limits.

First of all, there are cases where recursion is plain nonsense, such as this query:

pattern meaningless(x) = { neg find meaningless(x); } 

For every choice of value of the variable x, it is a match of pattern meaningless if and only if it is not a match of the same pattern. It is easy to see that this is a contradiction - do not expect EMF-IncQuery to be useful for evaluating such queries. In fact, from this point, the discussion will be restricted to positive recursion, i.e. patterns referencing themselves or each other cyclically, solely by positive find pattern calls, never with negation (neg find) or aggregation (count find). Positively recursive queries are always meaningful - unfortunately, they still will not work in all cases.

Back to the top