atlanmod / Mogwai

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

Cannot run Train Benchmark query with 3 levels of collect #10

Closed agarciadom closed 8 years ago

agarciadom commented 8 years ago

I'm trying to run several queries that have multiply nested collect() calls. For instance, this simplified version of the Train Benchmark RouteSensor query:

import railway : 'platform:/resource/railway.neoemf/model/railway.ecore'

package railway
    context Route
    def:
    routeSensor : Bag(Sensor) = Route.allInstances()
        ->collect(route | route.follows
            ->collect(swP | swP.target
                ->collect(sw | sw.monitoredBy)
            )
        )
endpackage

However, this fails with the following error:

IN!<unnamed>
'swP'
Cannot set feature nextElement to value swP.target, inter-model references are forbidden. Configure launching options to allow them.
def metaRoute = g.getIndex("metaclasses",Vertex.class)[[name:"Route"]];
def metaRouteNode = metaRoute.next();
metaRouteNode.inE("kyanosInstanceOf").outV._().outE("follows").inV.([outE("target").inV] as  Set)._()._().outE("monitoredBy").inV._()._()._();

javax.script.ScriptException: groovy.lang.MissingMethodException: No signature of method: com.tinkerpop.gremlin.groovy.jsr223.GremlinGroovyScriptEngine.outE() is applicable for argument types: (java.lang.String) values: [target]
Possible solutions: get(java.lang.String), put(java.lang.String, java.lang.Object), dump(), use([Ljava.lang.Object;), eval(java.lang.String), getAt(java.lang.String)
    at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:333)
    at org.codehaus.groovy.jsr223.GroovyCompiledScript.eval(GroovyCompiledScript.java:41)
    at javax.script.CompiledScript.eval(CompiledScript.java:92)
    at fr.inria.atlanmod.mogwai.core.Mogwai.runQuery(Mogwai.java:60)
    at fr.inria.atlanmod.mogwai.core.Mogwai.performQuery(Mogwai.java:29)
    at fr.inria.atlanmod.mogwai.resources.MogwaiResourceImpl.query(MogwaiResourceImpl.java:36)
    at fr.inria.atlanmod.mogwai.resources.MogwaiResourceImpl.query(MogwaiResourceImpl.java:31)
    at mogwai.remoteQuery.app.Prototype.run(Prototype.java:103)
    at mogwai.remoteQuery.app.Prototype.main(Prototype.java:74)

It seems as if swP.target wasn't being transformed for some reason. Any ideas on what might be going wrong? If I limit it to the two outermost collect() calls it works fine.

gdaniel commented 8 years ago

Could you please send me/link me the metamodel you are using? I tried to use the one on your repository (https://github.com/bluezio/trainbenchmark) but it does not contain target and monitoredBy features which are used in your query.

I tested with a similar OCL query on my JDTAST metamodel but I was not able to reproduce the error in the translation, so I'd like to see the metamodel to find particular properties/features that make the transformation fail.

agarciadom commented 8 years ago

Sorry, I hadn't updated my fork with the exact version I'm using now. That should be correct now. In any case, I had to tweak it manually outside that repo to get NeoEMF to save the model, since all objects have an "id" EAttribute that Neo4j complains about. I've attached railway-modified.zip with the relevant .ecore and a sample .xmi file.

gdaniel commented 8 years ago

Thanks a lot!

I found the problem: the OCL parser creates some additional elements when collects concerning multi-valued references are nested (for some reasons it creates a CollectionLiteralExp and a CollectionItem containing the nested collect).

These elements are translated into CollectionDefinition by Mogwaï, that's where the strange ([outE("target").inV] as Set) came from.

I have to investigate a little to find precisely when those elements are created, however for now the transformation of the example produces the query below which looks like more correct :-)

def metaRoute = g.getIndex("metaclasses",Vertex.class)[[name:"Route"]]; def metaRouteNode = (metaRoute.hasNext() ? metaRoute.next() : null); metaRouteNode.inE("kyanosInstanceOf").outV._().outE("follows").inV._().outE("target").inV._().outE("monitoredBy").inV._()._()._();

agarciadom commented 8 years ago

That looks much better, thanks! Did you push your changes?

gdaniel commented 8 years ago

A quick remark: the new version of Mogwaï is now able to transform the query you gave here as an example. However, there are still some issues in the other queries you sent me by mail: the transformation does not handle collect iterator variable access for now, this should be fixed, I have open #11 to report it.