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");