From 3cc0b53355b1e85ab89b9a96563ff349c55e0db8 Mon Sep 17 00:00:00 2001 From: nmacedo Date: Fri, 21 Mar 2014 10:49:55 +0000 Subject: [PATCH] atl developments --- .../metamodels/hsm2nhsm/NHSM.ecore | 14 +++-- .../models/hsm2nhsm/NHM_example.xmi | 9 +-- .../engine/alloy/AlloyEchoTranslator.java | 29 +++++++--- .../engine/alloy/EAlloyTransformation.java | 55 +++++++++++++++---- .../echo/engine/ast/EEngineRelation.java | 44 ++++++++------- .../engine/ast/EEngineTransformation.java | 7 ++- .../haslab/mde/transformation/ERelation.java | 5 +- .../transformation/atl/EATLModelDomain.java | 3 +- 8 files changed, 106 insertions(+), 60 deletions(-) diff --git a/examples/pt.uminho.haslab.echo.examples/metamodels/hsm2nhsm/NHSM.ecore b/examples/pt.uminho.haslab.echo.examples/metamodels/hsm2nhsm/NHSM.ecore index b943ec0..ac76b91 100644 --- a/examples/pt.uminho.haslab.echo.examples/metamodels/hsm2nhsm/NHSM.ecore +++ b/examples/pt.uminho.haslab.echo.examples/metamodels/hsm2nhsm/NHSM.ecore @@ -3,20 +3,22 @@ xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="NHSM" nsURI="NHSM" nsPrefix="nhsm"> + eType="ecore:EClass /pt.uminho.haslab.echo.examples/metamodels/hsm2nhsm/NHSM.ecore#//State" + containment="true" eOpposite="/pt.uminho.haslab.echo.examples/metamodels/hsm2nhsm/NHSM.ecore#//State/machine"/> + eType="ecore:EClass /pt.uminho.haslab.echo.examples/metamodels/hsm2nhsm/NHSM.ecore#//Transition" + containment="true"/> - + + eType="ecore:EClass /pt.uminho.haslab.echo.examples/metamodels/hsm2nhsm/NHSM.ecore#//State"/> + eType="ecore:EClass /pt.uminho.haslab.echo.examples/metamodels/hsm2nhsm/NHSM.ecore#//State"/> diff --git a/examples/pt.uminho.haslab.echo.examples/models/hsm2nhsm/NHM_example.xmi b/examples/pt.uminho.haslab.echo.examples/models/hsm2nhsm/NHM_example.xmi index 4e499df..38399df 100644 --- a/examples/pt.uminho.haslab.echo.examples/models/hsm2nhsm/NHM_example.xmi +++ b/examples/pt.uminho.haslab.echo.examples/models/hsm2nhsm/NHM_example.xmi @@ -6,12 +6,5 @@ xmlns:nhsm="NHSM" xsi:schemaLocation="NHSM /pt.uminho.haslab.echo.examples/metamodels/hsm2nhsm/NHSM.ecore" name="machine"> - - - - + diff --git a/plugins/pt.uminho.haslab.echo/src/pt/uminho/haslab/echo/engine/alloy/AlloyEchoTranslator.java b/plugins/pt.uminho.haslab.echo/src/pt/uminho/haslab/echo/engine/alloy/AlloyEchoTranslator.java index 6612dd2..8b1bdb2 100644 --- a/plugins/pt.uminho.haslab.echo/src/pt/uminho/haslab/echo/engine/alloy/AlloyEchoTranslator.java +++ b/plugins/pt.uminho.haslab.echo/src/pt/uminho/haslab/echo/engine/alloy/AlloyEchoTranslator.java @@ -32,6 +32,8 @@ import pt.uminho.haslab.mde.transformation.EModelDomain; import pt.uminho.haslab.mde.transformation.ERelation; import pt.uminho.haslab.mde.transformation.ETransformation; +import pt.uminho.haslab.mde.transformation.atl.EATLTransformation; +import pt.uminho.haslab.mde.transformation.qvt.EQVTTransformation; import java.util.ArrayList; import java.util.HashMap; @@ -138,15 +140,24 @@ public void remMetaModel(String metamodelID) { @Override public void translateTransformation(ETransformation constraint) throws EchoError { Map> deps = new HashMap>(); - for (ERelation r : constraint.getRelations()) { - List aux2 = new ArrayList(); - for (EModelDomain dom : r.getDomains()) { - List aux = new ArrayList(r.getDomains()); - aux.remove(dom); - aux2.add(new EDependency(dom,aux,null)); - } - deps.put(r.getName(),aux2); - } +// if (constraint instanceof EATLTransformation) +// for (ERelation r : constraint.getRelations()) { +// List aux2 = new ArrayList<>(); +// List aux = new ArrayList<>(); +// aux.add(r.getDomains().get(0)); +// aux2.add(new EDependency(r.getDomains().get(1),aux,null)); +// deps.put(r.getName(),aux2); +// } +// else + for (ERelation r : constraint.getRelations()) { + List aux2 = new ArrayList(); + for (EModelDomain dom : r.getDomains()) { + List aux = new ArrayList(r.getDomains()); + aux.remove(dom); + aux2.add(new EDependency(dom,aux,null)); + } + deps.put(r.getName(),aux2); + } translateTransformation(constraint,deps); } diff --git a/plugins/pt.uminho.haslab.echo/src/pt/uminho/haslab/echo/engine/alloy/EAlloyTransformation.java b/plugins/pt.uminho.haslab.echo/src/pt/uminho/haslab/echo/engine/alloy/EAlloyTransformation.java index 6f9efeb..7e61fc0 100644 --- a/plugins/pt.uminho.haslab.echo/src/pt/uminho/haslab/echo/engine/alloy/EAlloyTransformation.java +++ b/plugins/pt.uminho.haslab.echo/src/pt/uminho/haslab/echo/engine/alloy/EAlloyTransformation.java @@ -8,6 +8,7 @@ import edu.mit.csail.sdg.alloy4compiler.ast.Sig.Field; import pt.uminho.haslab.echo.EchoError; import pt.uminho.haslab.echo.EchoReporter; +import pt.uminho.haslab.echo.ErrorUnsupported; import pt.uminho.haslab.echo.EchoRunner.Task; import pt.uminho.haslab.echo.ErrorInternalEngine; import pt.uminho.haslab.echo.engine.EchoHelper; @@ -15,10 +16,13 @@ import pt.uminho.haslab.echo.engine.ITContext; import pt.uminho.haslab.echo.engine.ast.Constants; import pt.uminho.haslab.echo.engine.ast.EEngineRelation; +import pt.uminho.haslab.echo.engine.ast.EEngineRelation.Mode; import pt.uminho.haslab.echo.engine.ast.EEngineTransformation; +import pt.uminho.haslab.echo.engine.ast.IDecl; import pt.uminho.haslab.echo.engine.ast.IExpression; import pt.uminho.haslab.echo.engine.ast.IFormula; import pt.uminho.haslab.mde.transformation.EDependency; +import pt.uminho.haslab.mde.transformation.EModelDomain; import pt.uminho.haslab.mde.transformation.EModelParameter; import pt.uminho.haslab.mde.transformation.ERelation; import pt.uminho.haslab.mde.transformation.ETransformation; @@ -47,6 +51,8 @@ class EAlloyTransformation extends EEngineTransformation { /** the Alloy functions defining top-relation constraints */ private Map topRelationConstraints; + + private Field trace; /** * the Alloy declarations denoting the transformation parameters used in the @@ -107,6 +113,15 @@ protected void processConstraint() throws ErrorAlloy { if (subRelationDefs != null) for (Func f : subRelationDefs.values()) fact = fact.and(f.call(vars)); + + if (subRelationFields != null && trace != null) { + Expr aux = Sig.NONE.product(Sig.NONE); + for (Func f : subRelationFields.values()) + aux = aux.plus(f.call(vars)); + fact = fact.and((vars[1].join(vars[0].join(trace))).equal(aux)); + } + + EchoReporter.getInstance().debug("Transformation: "+fact); // creates functions with transformation parameters try { @@ -125,7 +140,6 @@ protected void processConstraint() throws ErrorAlloy { protected AlloyFormula getConstraint(List modelIDs) { // calls constraint function with the model's state sig List sigs = new ArrayList(); - EchoReporter.getInstance().debug("qvt: "+func.getBody()); for (String modelID : modelIDs) { EAlloyModel mdl = (EAlloyModel) EchoTranslator.getInstance().getModel(modelID); sigs.add(mdl.getModelSig()); @@ -165,6 +179,15 @@ protected void addSubRelationField(EEngineRelation relation, IExpression exp) if (subRelationFields == null) subRelationFields = new HashMap(); + if (relation.mode == Mode.TOP_TRACEABILITY) { + String op = EchoHelper.relationFieldName(relation.relation, relation.dependency.getSources().get(0)); + if (subRelationFields.get(op) != null) { + subRelationFields.put(EchoHelper.relationFieldName( + relation.relation, relation.dependency.target), subRelationFields.get(op)); + return; + } + } + // creates a function that calls the sub-relation field with appropriate // model parameters List decls = new ArrayList(); @@ -240,22 +263,34 @@ public AlloyFormula callRelation(ERelation n, ITContext context, } @Override - public IExpression callAllRelation(ITContext context, IExpression param) { - if (subRelationFields == null) return Constants.EMPTY(); - - // applies the model parameters to the relation function + public IExpression callAllRelation(ITContext context, IExpression param) throws ErrorAlloy, ErrorUnsupported { + + if (trace == null) addTrace(); + Expr[] vars = new Expr[context.getModelExpressions().size()]; for (int i = 0; i < context.getModelExpressions().size(); i++) vars[i] = ((AlloyExpression) context.getModelExpressions().get(i)).EXPR; - - Expr exp = Sig.NONE; - // retrieves the relation field - for (Func f : subRelationFields.values()) - exp = exp.plus(f.call(vars)); + + Expr exp = vars[1].join(vars[0].join(trace)); IExpression expp = new AlloyExpression(exp); return param.join(expp); } + + protected void addTrace() throws ErrorAlloy, ErrorUnsupported { + if (modelParamDecls.size() > 2) throw new ErrorUnsupported("Traces between more than 2 models not yet supported."); + try { + Sig s0 = (Sig) (modelParamDecls.get(0).expr.type().toExpr()); + Sig s1 = (Sig) (modelParamDecls.get(1).expr.type().toExpr()); + trace = s0.addField("trace", s1.product(Sig.UNIV.product(Sig.UNIV))); + } catch (Err a) { + throw new ErrorAlloy(ErrorInternalEngine.FAIL_CREATE_FIELD, + "Failed to create relation field representation: " + +"trace", a, + Task.TRANSLATE_TRANSFORMATION); + } + } + } diff --git a/plugins/pt.uminho.haslab.echo/src/pt/uminho/haslab/echo/engine/ast/EEngineRelation.java b/plugins/pt.uminho.haslab.echo/src/pt/uminho/haslab/echo/engine/ast/EEngineRelation.java index 76bdbbc..8059778 100644 --- a/plugins/pt.uminho.haslab.echo/src/pt/uminho/haslab/echo/engine/ast/EEngineRelation.java +++ b/plugins/pt.uminho.haslab.echo/src/pt/uminho/haslab/echo/engine/ast/EEngineRelation.java @@ -44,14 +44,14 @@ public abstract class EEngineRelation { /** the engine declarations of the root variables * null if top call */ - protected Map rootVar2engineDecl = new HashMap<>(); - protected Map rootVarS2engineDecl = new HashMap<>(); - protected Map rootVarT2engineDecl = new HashMap<>(); + protected Map rootVar2engineDecl = new LinkedHashMap<>(); + protected Map rootVarS2engineDecl = new LinkedHashMap<>(); + protected Map rootVarT2engineDecl = new LinkedHashMap<>(); /** the root variables of the relation being translated*/ - private Map rootvariables = new HashMap<>(); - private Map rootvariablesS = new HashMap<>(); - private Map rootvariablesT = new HashMap<>(); + private Map rootvariables = new LinkedHashMap<>(); + private Map rootvariablesS = new LinkedHashMap<>(); + private Map rootvariablesT = new LinkedHashMap<>(); /** the target relation domain */ private EModelDomain targetdomain; @@ -61,15 +61,15 @@ public abstract class EEngineRelation { /** the engine declarations of the variables occurring in the when constraint * if non-top relation, does not contain root variables*/ - private Map whenVar2engineDecl = new HashMap<>(); + private Map whenVar2engineDecl = new LinkedHashMap<>(); /** the engine declarations of the variables occurring in the source domain but not in the when constraint * if non-top relation, does not contain root variables*/ - private Map sourceVar2engineDecl = new HashMap<>(); + private Map sourceVar2engineDecl = new LinkedHashMap<>(); /** the engine declarations of the variables occurring in the target domain and where constraint but not in the source domains and the when constraint constraint * if non-top relation, does not contain root variables*/ - private Map targetVar2engineDecl = new HashMap<>(); + private Map targetVar2engineDecl = new LinkedHashMap<>(); public final IFormula constraint; @@ -93,7 +93,7 @@ public EEngineRelation (ERelation relation, EEngineRelation parentRelation) thro * @throws EchoError */ public EEngineRelation (ERelation relation, EDependency dependency, EEngineTransformation transformation, boolean trace) throws EchoError { - this (relation,trace?Mode.TOP_TRACEABILITY:Mode.TOP_QUANTIFIER,dependency,null,transformation); + this (relation,trace?(relation.isTop()?Mode.TOP_TRACEABILITY:Mode.SUB_TRACEABILITY):Mode.TOP_QUANTIFIER,dependency,null,transformation); } /** @@ -147,9 +147,9 @@ private void initVariableLists() throws EchoError { manageModelParams(); // retrieve the variables occurring in the predicates and assign them owning domains (if possible) - Map preVar2model = new HashMap(); - Map sourceVar2model = new HashMap(); - Map targetVar2model = new HashMap(); + Map preVar2model = new LinkedHashMap(); + Map sourceVar2model = new LinkedHashMap(); + Map targetVar2model = new LinkedHashMap(); for (EModelDomain dom : relation.getDomains()) { rootvariables.put(dom.getRootVariable(),dom.getModel().getName()); @@ -217,11 +217,11 @@ private void initVariableLists() throws EchoError { } } - EchoReporter.getInstance().debug("rootvarsS: "+rootvariablesS); - EchoReporter.getInstance().debug("rootvarsT: "+rootvariablesT); - EchoReporter.getInstance().debug("srcvars: "+sourceVar2model); - EchoReporter.getInstance().debug("trgvars: "+targetVar2model); - EchoReporter.getInstance().debug("prevars: "+preVar2model); +// EchoReporter.getInstance().debug("rootvarsS: "+rootvariablesS); +// EchoReporter.getInstance().debug("rootvarsT: "+rootvariablesT); +// EchoReporter.getInstance().debug("srcvars: "+sourceVar2model); +// EchoReporter.getInstance().debug("trgvars: "+targetVar2model); +// EchoReporter.getInstance().debug("prevars: "+preVar2model); // embed retrieved variable in engine representation sourceVar2engineDecl = createVarDecls(sourceVar2model,true); @@ -315,7 +315,7 @@ else if (sourceVar2engineDecl.size() > 1) { return formula; } - + /** * Translates a predicate to an engine formula. * @param predicate the predicate to be translated @@ -344,14 +344,16 @@ private IFormula translateCondition(EPredicate predicate) throws EchoError { protected Map createVarDecls( Map var2model, boolean addContext) throws EchoError { + if (addContext) for (EVariable s : var2model.keySet()) context.setVarModel(s.getName(), var2model.get(s)); - Map ivars = new HashMap<>(); + Map ivars = new LinkedHashMap<>(); for (EVariable var : var2model.keySet()) ivars.put(var.getName(), context.getDecl(var, addContext)); + EchoReporter.getInstance().debug("Created vars: "+ivars); return ivars; } @@ -376,7 +378,7 @@ private void addRelationDef(IExpression field) throws EchoError { if (relation.getDomains().size() > 2) throw new ErrorUnsupported("Calls between more than 2 models not yet supported."); IDecl fst = rootVar2engineDecl.get(relation.getDomains().get(0).getRootVariable().getName()); IDecl snd = rootVar2engineDecl.get(relation.getDomains().get(1).getRootVariable().getName()); - System.out.println(constraint.comprehension(fst,snd)); + EchoReporter.getInstance().debug(relation.getName() + " defined by comprehension."); IFormula e = field.eq(constraint.comprehension(fst,snd)); transformation.defineSubRelationField(this,e); } diff --git a/plugins/pt.uminho.haslab.echo/src/pt/uminho/haslab/echo/engine/ast/EEngineTransformation.java b/plugins/pt.uminho.haslab.echo/src/pt/uminho/haslab/echo/engine/ast/EEngineTransformation.java index 64a144e..cb8ead0 100644 --- a/plugins/pt.uminho.haslab.echo/src/pt/uminho/haslab/echo/engine/ast/EEngineTransformation.java +++ b/plugins/pt.uminho.haslab.echo/src/pt/uminho/haslab/echo/engine/ast/EEngineTransformation.java @@ -4,7 +4,9 @@ import pt.uminho.haslab.echo.EchoReporter; import pt.uminho.haslab.echo.EchoRunner.Task; import pt.uminho.haslab.echo.ErrorInternalEngine; +import pt.uminho.haslab.echo.ErrorUnsupported; import pt.uminho.haslab.echo.engine.ITContext; +import pt.uminho.haslab.echo.engine.alloy.ErrorAlloy; import pt.uminho.haslab.mde.transformation.EDependency; import pt.uminho.haslab.mde.transformation.ERelation; import pt.uminho.haslab.mde.transformation.ETransformation; @@ -46,8 +48,9 @@ protected EEngineTransformation(ETransformation transformation, initModelParams(); // translates each top relation + // in ATL all transformations (including lazy ones) must be translated at top-level due to implicit calls for (ERelation rel : transformation.getRelations()) { - if (rel.isTop()) + if (rel.isTop()||trace) for (EDependency dep : dependencies.get(rel.getName())) createRelation(rel, dep, trace); } @@ -147,6 +150,6 @@ public abstract IFormula callRelation(ERelation rel, ITContext context, List params); public abstract IExpression callAllRelation(ITContext context, - IExpression param); + IExpression param) throws ErrorAlloy, ErrorUnsupported; } diff --git a/plugins/pt.uminho.haslab.echo/src/pt/uminho/haslab/mde/transformation/ERelation.java b/plugins/pt.uminho.haslab.echo/src/pt/uminho/haslab/mde/transformation/ERelation.java index 9e5ea36..4f2d6ed 100644 --- a/plugins/pt.uminho.haslab.echo/src/pt/uminho/haslab/mde/transformation/ERelation.java +++ b/plugins/pt.uminho.haslab.echo/src/pt/uminho/haslab/mde/transformation/ERelation.java @@ -23,9 +23,6 @@ public interface ERelation { * @throws EchoError */ public ETransformation getTransformation() throws ErrorUnsupported, ErrorParser, EchoError; - /** if the relation is top level */ - public boolean isTop(); - /** the relation name */ public String getName(); @@ -38,5 +35,7 @@ public interface ERelation { /** the pre-condition */ public EPredicate getPre(); + /** if the relation is top level */ + public boolean isTop(); } diff --git a/plugins/pt.uminho.haslab.echo/src/pt/uminho/haslab/mde/transformation/atl/EATLModelDomain.java b/plugins/pt.uminho.haslab.echo/src/pt/uminho/haslab/mde/transformation/atl/EATLModelDomain.java index 474a5e6..5f94eaf 100644 --- a/plugins/pt.uminho.haslab.echo/src/pt/uminho/haslab/mde/transformation/atl/EATLModelDomain.java +++ b/plugins/pt.uminho.haslab.echo/src/pt/uminho/haslab/mde/transformation/atl/EATLModelDomain.java @@ -60,7 +60,8 @@ public EATLPredicate getCondition() { EATLPredicate x = new EATLPredicate(); if (domain.eClass().getName().equals("InPattern")) { EObject filter = (EObject) domain.eGet(domain.eClass().getEStructuralFeature("filter")); - x.addCondition(filter); + if (filter != null) + x.addCondition(filter); } // else if (domain.eClass().getName().equals("OutPattern")) { // EStructuralFeature elems = domain.eClass().getEStructuralFeature("elements");