How to include a path in the result set and not only a single reference (i.e. transitive closure)?

31 views
Skip to first unread message

Jan Reimann

unread,
Oct 18, 2012, 5:11:11 AM10/18/12
to incquer...@googlegroups.com
Hello guys,
I have a new puzzle for you ;) I attached a modified example and my modified query file. The query file was modified with respect to Ábels solution of my last question. The prefix "PH_" of the roles means "PlaceHolder". In this regard, I can include the subclasses in the result set, too.
But what I want to know now is, how can I query an arbitrary long path in a pattern? Have a look at my attached example. You might see it better in the ecorediag model. Between the metaclasses "OrigContainer" and "Extract" you'll find an added path via the metaclass "ExtractBetween". The path OrigContainer <>-extractsBetween-> ExtractBetween <>-betweenExtracts-> Extract should be an alternative for the original path OrigContainer <>-extracts-> Extract which has a length of only 1. For this purpose I added the transitive closure operator "+" to the following part of my pattern:

find eAllContainments+(PH_OrigCont,extracts);
ETypedElement.eType(extracts,PH_Extract);

But I still get only one result which respects only the path of length 1. How can I build up my query to cover this case?

best regards,
Jan

P.S.: I still get the 340 error when trying to post a message with attached files so I add them in textual form here

---------------- TestExtractXWRefClass3.ecore ----------------

<?xml version="1.0" encoding="UTF-8"?>
<ecore:EPackage xmi:version="2.0"
    xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="testextractxwrefclass"
    nsURI="http://testextractxwrefclass/1.0" nsPrefix="testextractxwrefclass">
  <eClassifiers xsi:type="ecore:EClass" name="OrigContainer">
    <eStructuralFeatures xsi:type="ecore:EReference" name="referer" eType="#//MovedReference"
        containment="true"/>
    <eStructuralFeatures xsi:type="ecore:EReference" name="extracts" eType="#//Extract"
        containment="true"/>
    <eStructuralFeatures xsi:type="ecore:EReference" name="extractsBetween" eType="#//ExtractBetween"
        containment="true"/>
  </eClassifiers>
  <eClassifiers xsi:type="ecore:EClass" name="Extract"/>
  <eClassifiers xsi:type="ecore:EClass" name="NewContainer">
    <eStructuralFeatures xsi:type="ecore:EReference" name="moved" eType="#//Extract"
        containment="true"/>
  </eClassifiers>
  <eClassifiers xsi:type="ecore:EClass" name="ContainerContainer">
    <eStructuralFeatures xsi:type="ecore:EReference" name="source" eType="#//OrigContainer"
        containment="true"/>
    <eStructuralFeatures xsi:type="ecore:EReference" name="target" eType="#//NewContainer"
        containment="true"/>
  </eClassifiers>
  <eClassifiers xsi:type="ecore:EClass" name="MovedReference">
    <eStructuralFeatures xsi:type="ecore:EReference" name="containerRef" eType="#//NewContainer"/>
  </eClassifiers>
  <eClassifiers xsi:type="ecore:EClass" name="ExtractBetween">
    <eStructuralFeatures xsi:type="ecore:EReference" name="betweenExtracts" eType="#//Extract"
        containment="true"/>
  </eClassifiers>
</ecore:EPackage>

---------------- ExtractXWithReferencedClass.eiq ----------------

import "http://www.eclipse.org/emf/2002/Ecore"

pattern ExtractXWithRefClass(OrigCont: EClass, ContCont: EClass, Extract:EClass, NewCont:EClass,
    MovedRef:EClass, extracts:EReference, source:EReference, target:EReference, referer:EReference,
    moved:EReference, containerRef:EReference){

    find eAllContainments+(PH_OrigCont,extracts);
    ETypedElement.eType(extracts,PH_Extract);
   
    find eAllContainments(PH_ContCont,source);
    ETypedElement.eType(source,PH_OrigCont);
   
    find eAllContainments(PH_ContCont,target);
    ETypedElement.eType(target,PH_NewCont);
   
    find eAllContainments(PH_OrigCont,referer);
    ETypedElement.eType(referer,PH_MovedRef);
   
    find eAllContainments(PH_NewCont,moved);
    ETypedElement.eType(moved,PH_Extract);
   
    find eAllReferences(PH_MovedRef,containerRef);
    ETypedElement.eType(containerRef,PH_NewCont);
    neg find isAggregation(containerRef);

    find thisAndAllSuperTypes(OrigCont, PH_OrigCont);
    find thisAndAllSuperTypes(ContCont, PH_ContCont);
    find thisAndAllSuperTypes(MovedRef, PH_MovedRef);
    find thisAndAllSuperTypes(NewCont, PH_NewCont);
    find thisAndAllSuperTypes(Extract, PH_Extract);
   
    neg find isEcore(OrigCont);
    neg find isEcore(ContCont);
    neg find isEcore(NewCont);
    neg find isEcore(MovedRef);
    neg find isEcore(Extract);
}

@QueryExplorer(display = false)
pattern isEcore(Element){
    EClassifier.ePackage(Element,EP);
    EPackage(EP);
    EPackage.nsURI(EP,"http://www.eclipse.org/emf/2002/Ecore");
}

@QueryExplorer(display = false)
pattern isAggregation(ref:EReference){
    EReference.containment(ref,true);
}

// well-behaving ecore patterns

@QueryExplorer(display = false)
private pattern eStructuralFeatures(This : EClass, Target : EStructuralFeature){
    EClass.eStructuralFeatures(This, Target);
}

@QueryExplorer(display = false)
pattern eAttributes(This : EClass, Target : EAttribute){
    find eStructuralFeatures(This, Target);
}

@QueryExplorer(display = false)
pattern eReferences(This : EClass, Target : EReference){
    find eStructuralFeatures(This, Target);
}

@QueryExplorer(display = false)
private pattern eGenericSuperTypes(This : EClass, Target : EGenericType){
    EClass.eGenericSuperTypes(This, Target);
}

@QueryExplorer(display = false)
pattern eAllGenericSuperTypes(This : EClass, Target : EGenericType){
    find eSuperTypes+(This, Type);
    find eGenericSuperTypes(Type, Target);
} or {
    find eGenericSuperTypes(This, Target);
}

@QueryExplorer(display = false)
private pattern eRawType(This : EGenericType, Target : EClass){
    EGenericType.eRawType(This, Target);
}

@QueryExplorer(display = false)
pattern eSuperTypes(This : EClass, Target : EClass){
    find eGenericSuperTypes(This, GenericType);
    find eRawType(GenericType, Target);
}

@QueryExplorer(display = false)
pattern eAllSuperTypes(This : EClass, Target : EClass){
    find eAllGenericSuperTypes(This, GenericType);
    find eRawType(GenericType, Target);
}

@QueryExplorer(display = false)
private pattern thisAndAllSuperTypes(This : EClass, Target : EClass){
    find eAllSuperTypes(This, Target);
} or {
    This == Target;
}

@QueryExplorer(display = false)
pattern eAllStructuralFeatures(This : EClass, Target : EStructuralFeature){
    find thisAndAllSuperTypes(This, Type);
    find eStructuralFeatures(Type, Target);
}

@QueryExplorer(display = false)
pattern eAllAttributes(This : EClass, Target : EAttribute){
    find eAllStructuralFeatures(This, Target);
}

@QueryExplorer(display = false)
pattern eAllReferences(This : EClass, Target : EReference){
    find eAllStructuralFeatures(This, Target);
}

@QueryExplorer(display = false)
pattern eAllContainments(This : EClass, Target : EReference){
    find eAllReferences(This, Target);
    EReference.containment(Target, true);
}

@QueryExplorer(display = false)
private pattern eOperations(This : EClass, Target : EOperation){
    EClass.eOperations(This, Target);
}

@QueryExplorer(display = false)
pattern eAllOperations(This : EClass, Target : EOperation){
    find thisAndAllSuperTypes(This, Type);
    find eOperations(Type, Target);
}

// NOTE: EMF uses the first attribute with id = true from all supertypes...
@QueryExplorer(display = false)
pattern eIDAttribute(This : EClass, Target : EAttribute){
    find eAllAttributes(This, Target);
    EAttribute.iD(Target, true);
}

---------------- TestExtractXWRefClass3.ecorediag ----------------

<?xml version="1.0" encoding="UTF-8"?>
<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmi:id="_ZV-HcBkAEeKmKZ23ogwu0g" type="EcoreTools" measurementUnit="Pixel">
  <children xmi:type="notation:Node" xmi:id="_ZXApQBkAEeKmKZ23ogwu0g" type="1001">
    <children xmi:type="notation:Node" xmi:id="_ZXApQxkAEeKmKZ23ogwu0g" type="4001"/>
    <children xmi:type="notation:Node" xmi:id="_ZXApRBkAEeKmKZ23ogwu0g" type="5001">
      <styles xmi:type="notation:DrawerStyle" xmi:id="_ZXApRRkAEeKmKZ23ogwu0g"/>
      <styles xmi:type="notation:SortingStyle" xmi:id="_ZXApRhkAEeKmKZ23ogwu0g"/>
      <styles xmi:type="notation:FilteringStyle" xmi:id="_ZXApRxkAEeKmKZ23ogwu0g"/>
    </children>
    <children xmi:type="notation:Node" xmi:id="_ZXApSBkAEeKmKZ23ogwu0g" type="5002">
      <styles xmi:type="notation:DrawerStyle" xmi:id="_ZXApSRkAEeKmKZ23ogwu0g"/>
      <styles xmi:type="notation:SortingStyle" xmi:id="_ZXApShkAEeKmKZ23ogwu0g"/>
      <styles xmi:type="notation:FilteringStyle" xmi:id="_ZXApSxkAEeKmKZ23ogwu0g"/>
    </children>
    <styles xmi:type="notation:ShapeStyle" xmi:id="_ZXApQRkAEeKmKZ23ogwu0g" fontColor="4210752" fontName="Segoe UI" fontHeight="10" fillColor="13761016" lineColor="8421504"/>
    <element xmi:type="ecore:EClass" href="TestExtractXWRefClass3.ecore#//OrigContainer"/>
    <layoutConstraint xmi:type="notation:Bounds" xmi:id="_ZXApQhkAEeKmKZ23ogwu0g" x="70" y="255"/>
  </children>
  <children xmi:type="notation:Node" xmi:id="_ZXApTBkAEeKmKZ23ogwu0g" type="1001">
    <children xmi:type="notation:Node" xmi:id="_ZXApTxkAEeKmKZ23ogwu0g" type="4001"/>
    <children xmi:type="notation:Node" xmi:id="_ZXApUBkAEeKmKZ23ogwu0g" type="5001">
      <styles xmi:type="notation:DrawerStyle" xmi:id="_ZXApURkAEeKmKZ23ogwu0g"/>
      <styles xmi:type="notation:SortingStyle" xmi:id="_ZXApUhkAEeKmKZ23ogwu0g"/>
      <styles xmi:type="notation:FilteringStyle" xmi:id="_ZXApUxkAEeKmKZ23ogwu0g"/>
    </children>
    <children xmi:type="notation:Node" xmi:id="_ZXApVBkAEeKmKZ23ogwu0g" type="5002">
      <styles xmi:type="notation:DrawerStyle" xmi:id="_ZXApVRkAEeKmKZ23ogwu0g"/>
      <styles xmi:type="notation:SortingStyle" xmi:id="_ZXApVhkAEeKmKZ23ogwu0g"/>
      <styles xmi:type="notation:FilteringStyle" xmi:id="_ZXApVxkAEeKmKZ23ogwu0g"/>
    </children>
    <styles xmi:type="notation:ShapeStyle" xmi:id="_ZXApTRkAEeKmKZ23ogwu0g" fontColor="4210752" fontName="Segoe UI" fontHeight="10" fillColor="13761016" lineColor="8421504"/>
    <element xmi:type="ecore:EClass" href="TestExtractXWRefClass3.ecore#//Extract"/>
    <layoutConstraint xmi:type="notation:Bounds" xmi:id="_ZXApThkAEeKmKZ23ogwu0g" x="425" y="260"/>
  </children>
  <children xmi:type="notation:Node" xmi:id="_ZXApWBkAEeKmKZ23ogwu0g" type="1001">
    <children xmi:type="notation:Node" xmi:id="_ZXApWxkAEeKmKZ23ogwu0g" type="4001"/>
    <children xmi:type="notation:Node" xmi:id="_ZXApXBkAEeKmKZ23ogwu0g" type="5001">
      <styles xmi:type="notation:DrawerStyle" xmi:id="_ZXApXRkAEeKmKZ23ogwu0g"/>
      <styles xmi:type="notation:SortingStyle" xmi:id="_ZXApXhkAEeKmKZ23ogwu0g"/>
      <styles xmi:type="notation:FilteringStyle" xmi:id="_ZXApXxkAEeKmKZ23ogwu0g"/>
    </children>
    <children xmi:type="notation:Node" xmi:id="_ZXApYBkAEeKmKZ23ogwu0g" type="5002">
      <styles xmi:type="notation:DrawerStyle" xmi:id="_ZXApYRkAEeKmKZ23ogwu0g"/>
      <styles xmi:type="notation:SortingStyle" xmi:id="_ZXApYhkAEeKmKZ23ogwu0g"/>
      <styles xmi:type="notation:FilteringStyle" xmi:id="_ZXApYxkAEeKmKZ23ogwu0g"/>
    </children>
    <styles xmi:type="notation:ShapeStyle" xmi:id="_ZXApWRkAEeKmKZ23ogwu0g" fontColor="4210752" fontName="Segoe UI" fontHeight="10" fillColor="13761016" lineColor="8421504"/>
    <element xmi:type="ecore:EClass" href="TestExtractXWRefClass3.ecore#//NewContainer"/>
    <layoutConstraint xmi:type="notation:Bounds" xmi:id="_ZXApWhkAEeKmKZ23ogwu0g" x="670" y="250"/>
  </children>
  <children xmi:type="notation:Node" xmi:id="_ZXApZBkAEeKmKZ23ogwu0g" type="1001">
    <children xmi:type="notation:Node" xmi:id="_ZXApZxkAEeKmKZ23ogwu0g" type="4001"/>
    <children xmi:type="notation:Node" xmi:id="_ZXApaBkAEeKmKZ23ogwu0g" type="5001">
      <styles xmi:type="notation:DrawerStyle" xmi:id="_ZXApaRkAEeKmKZ23ogwu0g"/>
      <styles xmi:type="notation:SortingStyle" xmi:id="_ZXApahkAEeKmKZ23ogwu0g"/>
      <styles xmi:type="notation:FilteringStyle" xmi:id="_ZXApaxkAEeKmKZ23ogwu0g"/>
    </children>
    <children xmi:type="notation:Node" xmi:id="_ZXKaQBkAEeKmKZ23ogwu0g" type="5002">
      <styles xmi:type="notation:DrawerStyle" xmi:id="_ZXKaQRkAEeKmKZ23ogwu0g"/>
      <styles xmi:type="notation:SortingStyle" xmi:id="_ZXKaQhkAEeKmKZ23ogwu0g"/>
      <styles xmi:type="notation:FilteringStyle" xmi:id="_ZXKaQxkAEeKmKZ23ogwu0g"/>
    </children>
    <styles xmi:type="notation:ShapeStyle" xmi:id="_ZXApZRkAEeKmKZ23ogwu0g" fontColor="4210752" fontName="Segoe UI" fontHeight="10" fillColor="13761016" lineColor="8421504"/>
    <element xmi:type="ecore:EClass" href="TestExtractXWRefClass3.ecore#//ContainerContainer"/>
    <layoutConstraint xmi:type="notation:Bounds" xmi:id="_ZXApZhkAEeKmKZ23ogwu0g" x="415" y="140"/>
  </children>
  <children xmi:type="notation:Node" xmi:id="_ZXKaRBkAEeKmKZ23ogwu0g" type="1001">
    <children xmi:type="notation:Node" xmi:id="_ZXKaRxkAEeKmKZ23ogwu0g" type="4001"/>
    <children xmi:type="notation:Node" xmi:id="_ZXKaSBkAEeKmKZ23ogwu0g" type="5001">
      <styles xmi:type="notation:DrawerStyle" xmi:id="_ZXKaSRkAEeKmKZ23ogwu0g"/>
      <styles xmi:type="notation:SortingStyle" xmi:id="_ZXKaShkAEeKmKZ23ogwu0g"/>
      <styles xmi:type="notation:FilteringStyle" xmi:id="_ZXKaSxkAEeKmKZ23ogwu0g"/>
    </children>
    <children xmi:type="notation:Node" xmi:id="_ZXKaTBkAEeKmKZ23ogwu0g" type="5002">
      <styles xmi:type="notation:DrawerStyle" xmi:id="_ZXKaTRkAEeKmKZ23ogwu0g"/>
      <styles xmi:type="notation:SortingStyle" xmi:id="_ZXKaThkAEeKmKZ23ogwu0g"/>
      <styles xmi:type="notation:FilteringStyle" xmi:id="_ZXKaTxkAEeKmKZ23ogwu0g"/>
    </children>
    <styles xmi:type="notation:ShapeStyle" xmi:id="_ZXKaRRkAEeKmKZ23ogwu0g" fontColor="4210752" fontName="Segoe UI" fontHeight="10" fillColor="13761016" lineColor="8421504"/>
    <element xmi:type="ecore:EClass" href="TestExtractXWRefClass3.ecore#//MovedReference"/>
    <layoutConstraint xmi:type="notation:Bounds" xmi:id="_ZXKaRhkAEeKmKZ23ogwu0g" x="425" y="445"/>
  </children>
  <children xmi:type="notation:Node" xmi:id="_yC1p0BkAEeKmKZ23ogwu0g" type="1001">
    <children xmi:type="notation:Node" xmi:id="_yC1p0xkAEeKmKZ23ogwu0g" type="4001"/>
    <children xmi:type="notation:Node" xmi:id="_yC1p1BkAEeKmKZ23ogwu0g" type="5001">
      <styles xmi:type="notation:DrawerStyle" xmi:id="_yC1p1RkAEeKmKZ23ogwu0g"/>
      <styles xmi:type="notation:SortingStyle" xmi:id="_yC1p1hkAEeKmKZ23ogwu0g"/>
      <styles xmi:type="notation:FilteringStyle" xmi:id="_yC1p1xkAEeKmKZ23ogwu0g"/>
    </children>
    <children xmi:type="notation:Node" xmi:id="_yC1p2BkAEeKmKZ23ogwu0g" type="5002">
      <styles xmi:type="notation:DrawerStyle" xmi:id="_yC1p2RkAEeKmKZ23ogwu0g"/>
      <styles xmi:type="notation:SortingStyle" xmi:id="_yC1p2hkAEeKmKZ23ogwu0g"/>
      <styles xmi:type="notation:FilteringStyle" xmi:id="_yC1p2xkAEeKmKZ23ogwu0g"/>
    </children>
    <styles xmi:type="notation:ShapeStyle" xmi:id="_yC1p0RkAEeKmKZ23ogwu0g" fontColor="4210752" fontName="Segoe UI" fontHeight="10" fillColor="13761016" lineColor="8421504"/>
    <element xmi:type="ecore:EClass" href="TestExtractXWRefClass3.ecore#//ExtractBetween"/>
    <layoutConstraint xmi:type="notation:Bounds" xmi:id="_yC1p0hkAEeKmKZ23ogwu0g" x="250" y="335"/>
  </children>
  <styles xmi:type="notation:DiagramStyle" xmi:id="_ZV-HcRkAEeKmKZ23ogwu0g"/>
  <element xmi:type="ecore:EPackage" href="TestExtractXWRefClass3.ecore#/"/>
  <edges xmi:type="notation:Edge" xmi:id="_ZXKaaBkAEeKmKZ23ogwu0g" type="3002" source="_ZXApQBkAEeKmKZ23ogwu0g" target="_ZXKaRBkAEeKmKZ23ogwu0g">
    <children xmi:type="notation:Node" xmi:id="_ZXKabBkAEeKmKZ23ogwu0g" type="4011">
      <layoutConstraint xmi:type="notation:Location" xmi:id="_ZXKabRkAEeKmKZ23ogwu0g" x="-10" y="-10"/>
    </children>
    <children xmi:type="notation:Node" xmi:id="_ZXKabhkAEeKmKZ23ogwu0g" type="4012">
      <layoutConstraint xmi:type="notation:Location" xmi:id="_ZXKabxkAEeKmKZ23ogwu0g" x="10" y="10"/>
    </children>
    <styles xmi:type="notation:ConnectorStyle" xmi:id="_ZXKaaRkAEeKmKZ23ogwu0g" routing="Rectilinear" lineColor="4210752"/>
    <styles xmi:type="notation:FontStyle" xmi:id="_ZXKaahkAEeKmKZ23ogwu0g" fontColor="4210752" fontName="Segoe UI" fontHeight="10"/>
    <element xmi:type="ecore:EReference" href="TestExtractXWRefClass3.ecore#//OrigContainer/referer"/>
    <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_ZXKaaxkAEeKmKZ23ogwu0g" points="[26, 41, -393, -190]$[26, 210, -393, -21]$[331, 210, -88, -21]"/>
    <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_ZZFs4BkAEeKmKZ23ogwu0g" id="(0.24271844660194175,0.0)"/>
    <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_ZZFs4RkAEeKmKZ23ogwu0g" id="(0.75,1.0)"/>
  </edges>
  <edges xmi:type="notation:Edge" xmi:id="_ZXKacBkAEeKmKZ23ogwu0g" type="3002" source="_ZXApQBkAEeKmKZ23ogwu0g" target="_ZXApTBkAEeKmKZ23ogwu0g">
    <children xmi:type="notation:Node" xmi:id="_ZXKadBkAEeKmKZ23ogwu0g" type="4011">
      <layoutConstraint xmi:type="notation:Location" xmi:id="_ZXKadRkAEeKmKZ23ogwu0g" x="-10" y="-10"/>
    </children>
    <children xmi:type="notation:Node" xmi:id="_ZXKadhkAEeKmKZ23ogwu0g" type="4012">
      <layoutConstraint xmi:type="notation:Location" xmi:id="_ZXKadxkAEeKmKZ23ogwu0g" x="10" y="10"/>
    </children>
    <styles xmi:type="notation:ConnectorStyle" xmi:id="_ZXKacRkAEeKmKZ23ogwu0g" routing="Rectilinear" lineColor="4210752"/>
    <styles xmi:type="notation:FontStyle" xmi:id="_ZXKachkAEeKmKZ23ogwu0g" fontColor="4210752" fontName="Segoe UI" fontHeight="10"/>
    <element xmi:type="ecore:EReference" href="TestExtractXWRefClass3.ecore#//OrigContainer/extracts"/>
    <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_ZXKacxkAEeKmKZ23ogwu0g" points="[51, 20, -189, -26]$[190, 20, -50, -26]"/>
    <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_ZZ1TyhkAEeKmKZ23ogwu0g" id="(0.49514563106796117,0.0)"/>
    <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_ZZ1TyxkAEeKmKZ23ogwu0g" id="(0.5,1.0)"/>
  </edges>
  <edges xmi:type="notation:Edge" xmi:id="_ZXKaeBkAEeKmKZ23ogwu0g" type="3002" source="_ZXApWBkAEeKmKZ23ogwu0g" target="_ZXApTBkAEeKmKZ23ogwu0g">
    <children xmi:type="notation:Node" xmi:id="_ZXKafBkAEeKmKZ23ogwu0g" type="4011">
      <layoutConstraint xmi:type="notation:Location" xmi:id="_ZXKafRkAEeKmKZ23ogwu0g" x="-10" y="-10"/>
    </children>
    <children xmi:type="notation:Node" xmi:id="_ZXKafhkAEeKmKZ23ogwu0g" type="4012">
      <layoutConstraint xmi:type="notation:Location" xmi:id="_ZXKafxkAEeKmKZ23ogwu0g" x="10" y="10"/>
    </children>
    <styles xmi:type="notation:ConnectorStyle" xmi:id="_ZXKaeRkAEeKmKZ23ogwu0g" routing="Rectilinear" lineColor="4210752"/>
    <styles xmi:type="notation:FontStyle" xmi:id="_ZXKaehkAEeKmKZ23ogwu0g" fontColor="4210752" fontName="Segoe UI" fontHeight="10"/>
    <element xmi:type="ecore:EReference" href="TestExtractXWRefClass3.ecore#//NewContainer/moved"/>
    <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_ZXKaexkAEeKmKZ23ogwu0g" points="[-50, 25, 221, -26]$[-195, 25, 76, -26]"/>
    <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_ZZ1TxhkAEeKmKZ23ogwu0g" id="(0.49514563106796117,0.0)"/>
    <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_ZZ1TxxkAEeKmKZ23ogwu0g" id="(0.24509803921568626,1.0)"/>
  </edges>
  <edges xmi:type="notation:Edge" xmi:id="_ZXTkMBkAEeKmKZ23ogwu0g" type="3002" source="_ZXApZBkAEeKmKZ23ogwu0g" target="_ZXApQBkAEeKmKZ23ogwu0g">
    <children xmi:type="notation:Node" xmi:id="_ZXTkNBkAEeKmKZ23ogwu0g" type="4011">
      <layoutConstraint xmi:type="notation:Location" xmi:id="_ZXTkNRkAEeKmKZ23ogwu0g" x="-10" y="-10"/>
    </children>
    <children xmi:type="notation:Node" xmi:id="_ZXTkNhkAEeKmKZ23ogwu0g" type="4012">
      <layoutConstraint xmi:type="notation:Location" xmi:id="_ZXTkNxkAEeKmKZ23ogwu0g" x="10" y="10"/>
    </children>
    <styles xmi:type="notation:ConnectorStyle" xmi:id="_ZXTkMRkAEeKmKZ23ogwu0g" routing="Rectilinear" lineColor="4210752"/>
    <styles xmi:type="notation:FontStyle" xmi:id="_ZXTkMhkAEeKmKZ23ogwu0g" fontColor="4210752" fontName="Segoe UI" fontHeight="10"/>
    <element xmi:type="ecore:EReference" href="TestExtractXWRefClass3.ecore#//ContainerContainer/source"/>
    <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_ZXTkMxkAEeKmKZ23ogwu0g" points="[-97, 21, 206, -135]$[-276, 21, 27, -135]$[-276, 115, 27, -41]"/>
    <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_ZZ1TwBkAEeKmKZ23ogwu0g" id="(0.7443609022556391,0.0)"/>
    <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_ZZ1TwRkAEeKmKZ23ogwu0g" id="(0.24271844660194175,1.0)"/>
  </edges>
  <edges xmi:type="notation:Edge" xmi:id="_ZXTkOBkAEeKmKZ23ogwu0g" type="3002" source="_ZXApZBkAEeKmKZ23ogwu0g" target="_ZXApWBkAEeKmKZ23ogwu0g">
    <children xmi:type="notation:Node" xmi:id="_ZXTkPBkAEeKmKZ23ogwu0g" type="4011">
      <layoutConstraint xmi:type="notation:Location" xmi:id="_ZXTkPRkAEeKmKZ23ogwu0g" x="-10" y="-10"/>
    </children>
    <children xmi:type="notation:Node" xmi:id="_ZXTkPhkAEeKmKZ23ogwu0g" type="4012">
      <layoutConstraint xmi:type="notation:Location" xmi:id="_ZXTkPxkAEeKmKZ23ogwu0g" x="10" y="10"/>
    </children>
    <styles xmi:type="notation:ConnectorStyle" xmi:id="_ZXTkORkAEeKmKZ23ogwu0g" routing="Rectilinear" lineColor="4210752"/>
    <styles xmi:type="notation:FontStyle" xmi:id="_ZXTkOhkAEeKmKZ23ogwu0g" fontColor="4210752" fontName="Segoe UI" fontHeight="10"/>
    <element xmi:type="ecore:EReference" href="TestExtractXWRefClass3.ecore#//ContainerContainer/target"/>
    <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_ZXTkOxkAEeKmKZ23ogwu0g" points="[66, 20, -148, -131]$[245, 20, 31, -131]$[245, 110, 31, -41]"/>
    <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_ZZ1TzBkAEeKmKZ23ogwu0g" id="(0.49624060150375937,0.0)"/>
    <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_ZZ1TzRkAEeKmKZ23ogwu0g" id="(0.24271844660194175,1.0)"/>
  </edges>
  <edges xmi:type="notation:Edge" xmi:id="_ZXTkQBkAEeKmKZ23ogwu0g" type="3002" source="_ZXKaRBkAEeKmKZ23ogwu0g" target="_ZXApWBkAEeKmKZ23ogwu0g">
    <children xmi:type="notation:Node" xmi:id="_ZXTkRBkAEeKmKZ23ogwu0g" type="4011">
      <layoutConstraint xmi:type="notation:Location" xmi:id="_ZXTkRRkAEeKmKZ23ogwu0g" x="-10" y="-10"/>
    </children>
    <children xmi:type="notation:Node" xmi:id="_ZXTkRhkAEeKmKZ23ogwu0g" type="4012">
      <layoutConstraint xmi:type="notation:Location" xmi:id="_ZXTkRxkAEeKmKZ23ogwu0g" x="10" y="10"/>
    </children>
    <styles xmi:type="notation:ConnectorStyle" xmi:id="_ZXTkQRkAEeKmKZ23ogwu0g" routing="Rectilinear" lineColor="4210752"/>
    <styles xmi:type="notation:FontStyle" xmi:id="_ZXTkQhkAEeKmKZ23ogwu0g" fontColor="4210752" fontName="Segoe UI" fontHeight="10"/>
    <element xmi:type="ecore:EReference" href="TestExtractXWRefClass3.ecore#//MovedReference/containerRef"/>
    <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_ZXTkQxkAEeKmKZ23ogwu0g" points="[92, 20, -177, 174]$[276, 20, 7, 174]$[276, -154, 7, 0]"/>
    <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_ZZ1TyBkAEeKmKZ23ogwu0g" id="(0.225,0.0)"/>
    <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_ZZ1TyRkAEeKmKZ23ogwu0g" id="(0.49514563106796117,1.0)"/>
  </edges>
  <edges xmi:type="notation:Edge" xmi:id="_09_MUBkAEeKmKZ23ogwu0g" type="3002" source="_ZXApQBkAEeKmKZ23ogwu0g" target="_yC1p0BkAEeKmKZ23ogwu0g">
    <children xmi:type="notation:Node" xmi:id="_09_MVBkAEeKmKZ23ogwu0g" type="4011">
      <layoutConstraint xmi:type="notation:Location" xmi:id="_09_MVRkAEeKmKZ23ogwu0g" x="-10" y="-10"/>
    </children>
    <children xmi:type="notation:Node" xmi:id="_09_MVhkAEeKmKZ23ogwu0g" type="4012">
      <layoutConstraint xmi:type="notation:Location" xmi:id="_09_MVxkAEeKmKZ23ogwu0g" x="10" y="10"/>
    </children>
    <styles xmi:type="notation:ConnectorStyle" xmi:id="_09_MURkAEeKmKZ23ogwu0g" routing="Rectilinear" lineColor="4210752"/>
    <styles xmi:type="notation:FontStyle" xmi:id="_09_MUhkAEeKmKZ23ogwu0g" fontColor="4210752" fontName="Segoe UI" fontHeight="10"/>
    <element xmi:type="ecore:EReference" href="TestExtractXWRefClass3.ecore#//OrigContainer/extractsBetween"/>
    <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_09_MUxkAEeKmKZ23ogwu0g" points="[16, 10, -106, -62]$[123, 90, 1, 18]"/>
    <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_09_MWBkAEeKmKZ23ogwu0g" id="(0.6893203883495146,0.7674418604651163)"/>
    <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_09_MWRkAEeKmKZ23ogwu0g" id="(0.11009174311926606,0.5813953488372093)"/>
  </edges>
  <edges xmi:type="notation:Edge" xmi:id="_3aWhEBkAEeKmKZ23ogwu0g" type="3002" source="_yC1p0BkAEeKmKZ23ogwu0g" target="_ZXApTBkAEeKmKZ23ogwu0g">
    <children xmi:type="notation:Node" xmi:id="_3aWhFBkAEeKmKZ23ogwu0g" type="4011">
      <layoutConstraint xmi:type="notation:Location" xmi:id="_3aWhFRkAEeKmKZ23ogwu0g" x="-10" y="-10"/>
    </children>
    <children xmi:type="notation:Node" xmi:id="_3aWhFhkAEeKmKZ23ogwu0g" type="4012">
      <layoutConstraint xmi:type="notation:Location" xmi:id="_3aWhFxkAEeKmKZ23ogwu0g" x="10" y="10"/>
    </children>
    <styles xmi:type="notation:ConnectorStyle" xmi:id="_3aWhERkAEeKmKZ23ogwu0g" routing="Rectilinear" lineColor="4210752"/>
    <styles xmi:type="notation:FontStyle" xmi:id="_3aWhEhkAEeKmKZ23ogwu0g" fontColor="4210752" fontName="Segoe UI" fontHeight="10"/>
    <element xmi:type="ecore:EReference" href="TestExtractXWRefClass3.ecore#//ExtractBetween/betweenExtracts"/>
    <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_3aWhExkAEeKmKZ23ogwu0g" points="[15, -7, -114, 51]$[130, -50, 1, 8]"/>
    <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_3aWhGBkAEeKmKZ23ogwu0g" id="(0.8623853211009175,0.3953488372093023)"/>
    <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_3aWhGRkAEeKmKZ23ogwu0g" id="(0.46078431372549017,0.813953488372093)"/>
  </edges>
</notation:Diagram>



Ujhelyi Zoltán

unread,
Oct 18, 2012, 6:15:54 AM10/18/12
to EMF-IncQuery Users on behalf of Jan Reimann
Hi,

I checked your model and code. If I understand your requirement correctly, you want to calculate the EClasses reachable using containment references. If not, or my solution is not clear enough, feel free to ask for clarification.

Basically, transitive closure only works if the both the source and target elements are of a comparable type, e.g. both are EClasses. In your case, you tried to call the transitive closure of the eAllContainments pattern that would result the following elements:
eAllContainments(Cl, Ref1); eAllContainments(Ref1, Ref2); eAllContainments(Ref2, Ref3);

As Ref1 has the type of EReference, that trivially fails when calling it in place of an EClass. Alltogether, that is a place for a missing validator; I filled an issue about it into our tracker: https://github.com/ujhelyiz/EMF-IncQuery/issues/341

For a working transitive closure call see the following example, that collects all EClasses transitively that can be contained in a selected EClass:

pattern canTransitivelyContain(PH_OrigCont : EClass, extracts : EClass) {
find canContain+(PH_OrigCont,extracts);
}

pattern canContain(PH_OrigCont: EClass, contained : EClass) {
find eAllContainments(PH_OrigCont,extracts);
EReference.eType(extracts, contained);
}

However, if you not only want to calculate the potentially contained EClasses but also the connection references, it becomes much harder to do. One way to do it would be to use recursive patterns - however, several uses of recursive patterns can result in hard-to-debug incorrect match sets. Because of this, I do not recommend taking this way.

On the other hand, you could use the previously used canTransitivelyContain pattern to get all required EClasses, and then with another pattern you can also gather the corresponding references using another pattern:

pattern allSubContainmentRelations(PH_OrigCont: EClass, ref : EReference) {
find eAllContainments(PH_OrigCont, ref);
} or {
find canContain(PH_OrigCont, ContainedClass);
find eAllContainments(ContainedClass, ref);
}



Another tip: it makes the debugging of queries much easier if you try to create small, reusable queries as in my examples. In this case you can use the Query Explorer to check for changes between the various patterns easily and understand the differences.

Cheers,
Zoltán
-- Zoltán Ujhelyi
https://www.inf.mit.bme.hu/en/members/ujhelyiz

Fault Tolerant Systems Research Group
Budapest University of Technology and Economics
> --
> You received this message because you are subscribed to the Google Groups "EMF-IncQuery Users" group.
> To post to this group, send email to incquer...@googlegroups.com.
> To unsubscribe from this group, send email to incquery-user...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msg/incquery-users/-/QhyMezJGfnMJ.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

Jan Reimann

unread,
Oct 18, 2012, 10:26:57 AM10/18/12
to incquer...@googlegroups.com
Hi Zoltán,
thanks for your helpful response! The pattern canTransitivelyContain(EClass, EClass) works as expected. But now I have two new problems. What I really want is to not only find the EClasses being transitively contained but the path of references (and thus the EClasses along this path) between source and target. So, canTransitivelyContain should get somehow a new parameter which is a list of EReference. But I assume that's not possible. Is there a possibility to get the path programmatically because in the end I want to invoke such a query only programmatically and analyse the found results. If that was possible I'm totally fine with it.
The second problem is that canTransitivelyContain as is contains reflexive results, too. That means EClass1 is transitively contained in EClass1. I want to reject those results and tried to modify your canTransitivelyContain pattern as follows:

pattern canTransitivelyContain(PH_
OrigCont : EClass, extracts : EClass) {
        HowManyReferences == count find canContain+(PH_OrigCont,extracts);
        // TODO: check anyhow  if HowManyReferences is greater than 0
}

If the counted references are 0 than it's the reflexive case. If it is greater than one EClass1 is transitively contained in EClass1 can be true in the case, e.g., when EClass1 has a reference to itself. So, these results would be correct.

Am I understandable and can you help me?

best regards,
Jan

Ujhelyi Zoltán

unread,
Oct 18, 2012, 11:17:38 AM10/18/12
to EMF-IncQuery Users on behalf of Jan Reimann
Hi,

sadly, it is not possible to extract the entire containment path using EMF-IncQuery pattern code as it would need much more powerful reasoning engine (stronger that first-order logic).

However, you could write yourself some helper patterns that get all EClasses that are connected to both the source and target EClass in the hierarchy with a pattern similar to the following:

pattern containmentPath(Start, X, End){
find canTransitivelyContain(Start, End);
find canTransitivelyContain(Start, X);
find canTransitivelyContain(X, End);
}

In that pattern, the variable X represents an EClass that is connected to both the Start and End nodes using containment references. With a little bit of tweaking it should also be possible for X to be equal to the Start or End classes as well.

However, ordering and single path information is missing, and is not possible to calculate using EMF-IncQuery; however, based on this partial results it may be possible to do it more efficiently in Java code.



About your second question about reflexivity, you can create another helper pattern that excludes that:

pattern canTransitivelyContainButNotReflexively(PH_OrigCont : EClass, extracts : EClass) {
find canContain+(PH_OrigCont,extracts);
neg find canContain(PH_OrigCont, extracts);
}

Alternatively, you can include numeric comparisons in a check expression:

pattern canTransitivelyContain(PH_
OrigCont : EClass, extracts : EClass) {
HowManyReferences == count find canContain+(PH_OrigCont,extracts);
check(HowManyReferences > 0);
}

Warning, be careful with check expressions: don't use it to traverse the model, and only use attributes already referenced in the patterns. Otherwise your pattern will not work incrementally.

Cheers,
Zoltán
-- Zoltán Ujhelyi
https://www.inf.mit.bme.hu/en/members/ujhelyiz

Fault Tolerant Systems Research Group
Budapest University of Technology and Economics

> --
> You received this message because you are subscribed to the Google Groups "EMF-IncQuery Users" group.
> To post to this group, send email to incquer...@googlegroups.com.
> To unsubscribe from this group, send email to incquery-user...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msg/incquery-users/-/jGQtMOg6cmQJ.

berg...@mit.bme.hu

unread,
Oct 18, 2012, 11:38:59 AM10/18/12
to incquer...@googlegroups.com
Hi,

I would like to clarify our answers a bit:

-----EMF-IncQuery Users on behalf of Zoltán Ujhelyi <incquer...@googlegroups.com> ezt írta: -----
pattern canTransitivelyContainButNotReflexively(PH_OrigCont : EClass, extracts : EClass) {
find canContain+(PH_OrigCont,extracts);
neg find canContain(PH_OrigCont, extracts);
}

I think the antireflexive case would be this:

pattern canTransitivelyContainButNotReflexively(PH_OrigCont : EClass, extracts : EClass) {
 find canContain+(PH_OrigCont,extracts);
 PH_OrigCont != extracts;
}



Alternatively, you can include numeric comparisons in a check expression:

pattern canTransitivelyContain(PH_
OrigCont : EClass, extracts : EClass) {
       HowManyReferences == count find canContain+(PH_OrigCont,extracts);
       check(HowManyReferences > 0);

Warning: none of these count-based solutions do what you want them to do, Jan. They have nothing to do with reflexivity.
"count" counts how many matcher a pattern has (under the given conditions), it has nothing to do with the length of the path in a transitive closure.
In this pattern, given a concrete value of PH_OrigCont and extracts, the result of counting may be either be 1 (there is at least one path between them using containments) or 0 (no such path). You can simply distinguish these cases by "find canContain+(PH_OrigCont,extracts);" or "neg find canTransitivelyContain(PH_OrigCont,extracts);", respectively. But none of these tell you anything about reflexivity.

Cheers,
Gábor
Reply all
Reply to author
Forward
0 new messages