atlanmod / Mogwai

Automatic translation from OCL to Gremlin
10 stars 6 forks source link

Collect iterator variables are not translated #11

Closed gdaniel closed 8 years ago

gdaniel commented 8 years ago

For now iterator variables in collect() body are not translated, meaning that it is not possible to access a collect iterator variable in its body.

Example (simplified from Train Benchmark):

OCL `package railway

context Sensor

def:
    connectedSegments : Bag(TrackElement) = Sensor.allInstances()->collect(sensor |
    sensor.monitors->collect(segment1 |
        segment1.connectsTo->select(segment2 |
            segment2.monitoredBy->includes(sensor))))

endpackage`

Gremlin

def metaSensor = g.getIndex("metaclasses",Vertex.class)[[name:"Sensor"]]; def metaSensorNode = (metaSensor.hasNext() ? metaSensor.next() : null); metaSensorNode.inE("kyanosInstanceOf").outV ._().outE("monitors").inV .**segment1**.outE("connectsTo").inV .filter{def segment2 = it;segment2.outE("monitoredBy").inV .gather.transform{it.contains(**sensor**);}.next();}._()._();

Two errors there:

gdaniel commented 8 years ago

For nowcollect() operations are basically ignored, and their body is directly translated and chained to the last step of the chain representing the collect's source expression.

For example the OCL query ClassDeclaration.allInstances()->collect(cd | cd.bodyDeclarations)

is mapped to the following traversal metaClassDeclarationNode.inE("kyanosInstanceOf").outV.outE("bodyDeclarations").inV

A solution to handle local iterator variable would be to use a transform step: metaClassDelcarationNode.inE("kyanosInstanceOf").outV.transform{def myVar = it; println(it); it._().outE("bodyDeclarations").inV}.scatter

In that case myVar corresponds to the current vertex processed (i.e. the value of the iterator in the collect)