Skip to content

Commit 9492912

Browse files
author
nmacedo
committed
support for iterator 'any' (close #179)
1 parent 4211ff1 commit 9492912

File tree

10 files changed

+305
-131
lines changed

10 files changed

+305
-131
lines changed

examples/pt.uminho.haslab.echo.examples/metamodels/hsm2nhsm/HSM.ecore

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,15 @@
2929
<eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
3030
<eStructuralFeatures xsi:type="ecore:EReference" name="container" eType="ecore:EClass /pt.uminho.haslab.echo.examples/metamodels/hsm2nhsm/HSM.ecore#//CompositeState"/>
3131
<eStructuralFeatures xsi:type="ecore:EReference" name="machine" lowerBound="1"
32-
eType="ecore:EClass /pt.uminho.haslab.echo.examples/metamodels/hsm2nhsm/HSM.ecore#//StateMachine"
33-
eOpposite="/pt.uminho.haslab.echo.examples/metamodels/hsm2nhsm/HSM.ecore#//StateMachine/states"/>
32+
eType="#//StateMachine" eOpposite="#//StateMachine/states"/>
3433
</eClassifiers>
35-
<eClassifiers xsi:type="ecore:EClass" name="CompositeState" eSuperTypes="/pt.uminho.haslab.echo.examples/metamodels/hsm2nhsm/HSM.ecore#//State"/>
34+
<eClassifiers xsi:type="ecore:EClass" name="CompositeState" eSuperTypes="#//State"/>
3635
<eClassifiers xsi:type="ecore:EClass" name="Transition">
3736
<eStructuralFeatures xsi:type="ecore:EReference" name="source" lowerBound="1"
3837
eType="ecore:EClass /pt.uminho.haslab.echo.examples/metamodels/hsm2nhsm/HSM.ecore#//State"/>
3938
<eStructuralFeatures xsi:type="ecore:EReference" name="target" lowerBound="1"
40-
eType="ecore:EClass /pt.uminho.haslab.echo.examples/metamodels/hsm2nhsm/HSM.ecore#//State"/>
39+
eType="#//State"/>
40+
<eStructuralFeatures xsi:type="ecore:EReference" name="machine" lowerBound="1"
41+
eType="#//StateMachine"/>
4142
</eClassifiers>
4243
</ecore:EPackage>

examples/pt.uminho.haslab.echo.examples/metamodels/hsm2nhsm/NHSM.ecore

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,14 @@
1212
</eClassifiers>
1313
<eClassifiers xsi:type="ecore:EClass" name="State">
1414
<eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
15-
<eStructuralFeatures xsi:type="ecore:EReference" name="machine" eType="ecore:EClass /pt.uminho.haslab.echo.examples/metamodels/hsm2nhsm/NHSM.ecore#//StateMachine"
16-
eOpposite="/pt.uminho.haslab.echo.examples/metamodels/hsm2nhsm/NHSM.ecore#//StateMachine/states"/>
15+
<eStructuralFeatures xsi:type="ecore:EReference" name="machine" eType="#//StateMachine"
16+
eOpposite="#//StateMachine/states"/>
1717
</eClassifiers>
1818
<eClassifiers xsi:type="ecore:EClass" name="Transition">
1919
<eStructuralFeatures xsi:type="ecore:EReference" name="source" lowerBound="1"
2020
eType="ecore:EClass /pt.uminho.haslab.echo.examples/metamodels/hsm2nhsm/NHSM.ecore#//State"/>
2121
<eStructuralFeatures xsi:type="ecore:EReference" name="target" lowerBound="1"
2222
eType="ecore:EClass /pt.uminho.haslab.echo.examples/metamodels/hsm2nhsm/NHSM.ecore#//State"/>
23+
<eStructuralFeatures xsi:type="ecore:EReference" name="machine" eType="#//StateMachine"/>
2324
</eClassifiers>
2425
</ecore:EPackage>
Lines changed: 27 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,36 @@
11
-- @atlcompiler atl2006
2-
-- @nsURI HSM=HSM.ecore
3-
-- @nsURI NHSM=NHSM.ecore
2+
-- @nsURI HSM='/pt.uminho.haslab.echo.examples/metamodels/hsm2nhsm/HSM.ecore'
3+
-- @nsURI NHSM='/pt.uminho.haslab.echo.examples/metamodels/hsm2nhsm/NHSM.ecore'
44

5-
module HSM2NHSM;
6-
create OUT : NHSM from IN : HSM;
5+
module hsm2nhsm;
6+
create nhm : NHSM from hsm : HSM;
77

8-
helper context HSM!State def :
9-
topcontainer : HSM!State =
10-
if self.owner->isEmpty() then self
11-
else self.container.topcontainer
12-
endif;
13-
14-
rule M2M {
15-
from
16-
c : HSM!StateMachine ()
17-
to
18-
t : NHSM!StateMachine (
19-
name <- c.name
20-
)
8+
rule M2M {
9+
from
10+
hm : HSM!StateMachine ()
11+
to
12+
nm : NHSM!StateMachine ( name <- hm.name )
2113
}
2214

23-
rule S2S{
24-
from
25-
c : HSM!State (c.owner->isEmpty())
26-
to
27-
t : NHSM!State (
28-
name <- c.name,
29-
machine <- c.machine
30-
)
15+
rule S2S {
16+
from
17+
hs : HSM!State ( hs.container->isEmpty() )
18+
to
19+
ns : NHSM!State (
20+
name <- hs.name,
21+
machine <- hs.machine
22+
)
3123
}
3224

3325
rule T2T {
34-
from
35-
c : HSM!Transition
36-
to
37-
s : NHSM!Transition(
38-
source <- c.source.topcontainer,
39-
target <- c.target.topcontainer
40-
)
26+
from
27+
ht : HSM!Transition
28+
to
29+
nt : NHSM!Transition (
30+
source <- ht.source->closure(x | x.container)->
31+
any(s | s.container->isEmpty()),
32+
target <- ht.target->closure(x | x.container)->
33+
any(s | s.container->isEmpty()),
34+
machine <- ht.machine
35+
)
4136
}

plugins/pt.uminho.haslab.echo/src/pt/uminho/haslab/echo/engine/IContext.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,9 @@ public interface IContext {
7575
* @param className the class name
7676
* @param propName the property name
7777
* @return the expression representing a property
78+
* @throws ErrorParser
7879
*/
79-
IExpression getPropExpression(String metaModelID, String className, String propName);
80+
IExpression getPropExpression(String metaModelID, String className, String propName) throws ErrorParser;
8081

8182
/**
8283
* Returns the expression representing a class call.

plugins/pt.uminho.haslab.echo/src/pt/uminho/haslab/echo/engine/OCLTranslator.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,10 @@ public INode translate(IteratorExp expr) throws EchoError {
303303
aux = (IFormula) body;
304304
aux = ((d.variable().in(src)).and(aux));
305305
res = aux.comprehension(d);
306+
} else if (expr.getReferredIteration().getName().equals("any")) {
307+
aux = (IFormula) body;
308+
aux = ((d.variable().in(src)).and(aux));
309+
res = aux.comprehension(d);
306310
} else if (expr.getReferredIteration().getName().equals("reject")) {
307311
aux = (IFormula) body;
308312
aux = ((d.variable().in(src)).and(aux.not()));
@@ -337,10 +341,18 @@ else if (expr.getReferredOperation().getName().equals("size")) {
337341
if (expr.getArgument().get(0).getType().getName().equals("Boolean"))
338342
res = ((IFormula) src).iff((IFormula) aux);
339343
else if (expr.getArgument().get(0).getType().getName()
340-
.equals("UnlimitedNatural"))
341-
res = ((IIntExpression) src).eq((IIntExpression) aux);
342-
else
343-
res = ((IExpression) src).eq((IExpression) aux);
344+
.equals("UnlimitedNatural")) {
345+
if (expr.getArgument().get(0) instanceof IteratorExp && ((IteratorExp) expr.getArgument().get(0)).getReferredIteration().getName().equals("any"))
346+
res = (((IIntExpression) src).in((IIntExpression) aux)).and(((IIntExpression) src).one());
347+
else
348+
res = ((IIntExpression) src).eq((IIntExpression) aux);
349+
}
350+
else {
351+
if (expr.getArgument().get(0) instanceof IteratorExp && ((IteratorExp) expr.getArgument().get(0)).getReferredIteration().getName().equals("any"))
352+
res = (((IExpression) src).in((IExpression) aux)).and(((IExpression) src).one());
353+
else
354+
res = ((IExpression) src).eq((IExpression) aux);
355+
}
344356
} else if (expr.getReferredOperation().getName().equals("<>")) {
345357
INode aux = translate(expr.getArgument().get(0));
346358
if (expr.getArgument().get(0).getType().getName().equals("Boolean"))

plugins/pt.uminho.haslab.echo/src/pt/uminho/haslab/echo/engine/alloy/ATLOCLTranslator.java

Lines changed: 103 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import org.eclipse.emf.ecore.EObject;
88
import org.eclipse.emf.ecore.EReference;
99
import org.eclipse.emf.ecore.EStructuralFeature;
10+
import org.eclipse.ocl.examples.pivot.IteratorExp;
1011

1112
import pt.uminho.haslab.echo.EchoError;
1213
import pt.uminho.haslab.echo.EchoOptionsSetup;
@@ -16,12 +17,14 @@
1617
import pt.uminho.haslab.echo.engine.EchoHelper;
1718
import pt.uminho.haslab.echo.engine.ITContext;
1819
import pt.uminho.haslab.echo.engine.ast.Constants;
20+
import pt.uminho.haslab.echo.engine.ast.IDecl;
1921
import pt.uminho.haslab.echo.engine.ast.IExpression;
2022
import pt.uminho.haslab.echo.engine.ast.IFormula;
2123
import pt.uminho.haslab.echo.engine.ast.IIntExpression;
2224
import pt.uminho.haslab.echo.engine.ast.INode;
2325
import pt.uminho.haslab.mde.MDEManager;
2426
import pt.uminho.haslab.mde.model.EMetamodel;
27+
import pt.uminho.haslab.mde.model.EVariable;
2528
import pt.uminho.haslab.mde.transformation.atl.EATLRelation;
2629
import pt.uminho.haslab.mde.transformation.atl.EATLTransformation;
2730

@@ -50,6 +53,8 @@ public INode translateAtlOcl(EObject expr) throws EchoError {
5053
return translateAtlOclBooleanLit(expr);
5154
} else if (expr.eClass().getName().equals("Binding")) {
5255
return translateAtlOclBinding(expr);
56+
} else if (expr.eClass().getName().equals("IteratorExp")) {
57+
return translateAtlOclIterator(expr);
5358
} else
5459
throw new ErrorUnsupported("OCL expression not supported: " + expr
5560
+ ".");
@@ -63,7 +68,9 @@ IExpression translateAtlOclVariable(EObject expr) {
6368
"varName");
6469
String varname = (String) vardecl.eGet(name);
6570
context.setCurrentModel(context.getVarModel(varname));
66-
return context.getVar(varname);
71+
IExpression res = context.getVar(varname);
72+
EchoReporter.getInstance().debug("Translated "+varname+" to "+res);
73+
return res;
6774
}
6875

6976
IFormula translateAtlOclBooleanLit(EObject expr) {
@@ -84,6 +91,7 @@ INode translateAtlOclAttribute(EObject expr) throws EchoError {
8491
context.setCurrentModel(null);
8592

8693
IExpression var = (IExpression) translateAtlOcl(sourceo);
94+
8795
EStructuralFeature oname = expr.eClass().getEStructuralFeature("name");
8896
IExpression aux = propertyToField((String) expr.eGet(oname), var);
8997

@@ -152,8 +160,12 @@ INode translateAtlOclBinding(EObject expr) throws EchoError {
152160
String nameo = feature.getEType().getName();
153161
if (nameo.equals("EBoolean"))
154162
res = ((IFormula) var.join(aux)).iff((IFormula) val);
155-
else
156-
res = var.join(aux).eq((IExpression) val);
163+
else {
164+
if (((EObject) expr.eGet(value)).eClass().getName().equals("IteratorExp") && ((EObject) expr.eGet(value)).eGet(((EObject) expr.eGet(value)).eClass().getEStructuralFeature("name")).equals("any"))
165+
res = var.join(aux).in((IExpression) val).and(var.join(aux).one());
166+
else
167+
res = var.join(aux).eq((IExpression) val);
168+
}
157169
return res;
158170
}
159171

@@ -178,8 +190,12 @@ else if (operatorname.equals("=")) {
178190
INode aux = translateAtlOcl(argumentso.get(0));
179191
if (src instanceof IFormula)
180192
res = ((IFormula) src).iff((IFormula) aux);
181-
else
182-
res = ((IExpression) src).eq((IExpression) aux);
193+
else {
194+
if (argumentso.get(0).eClass().getName().equals("IteratorExp") && argumentso.get(0).eGet(argumentso.get(0).eClass().getEStructuralFeature("name")).equals("any"))
195+
res = (((IExpression) src).in((IExpression) aux)).and(((IExpression) src).one());
196+
else
197+
res = ((IExpression) src).eq((IExpression) aux);
198+
}
183199
} else if (operatorname.equals("<>")) {
184200
INode aux = translateAtlOcl(argumentso.get(0));
185201
EStructuralFeature type = argumentso.get(0).eClass()
@@ -263,6 +279,86 @@ else if (((EATLTransformation) context.getCallerRel().transformation.transformat
263279

264280
return res;
265281
}
282+
283+
INode translateAtlOclIterator(EObject expr) throws EchoError {
284+
INode res = null;
285+
286+
EStructuralFeature source = expr.eClass().getEStructuralFeature(
287+
"source");
288+
IExpression src = (IExpression) translateAtlOcl((EObject) expr.eGet(source));
289+
EStructuralFeature iterator = expr.eClass().getEStructuralFeature("iterators");
290+
EVariable x = null;
291+
try {
292+
x = EVariable.getVariable(((EList<EObject>) expr.eGet(iterator)).get(0),((AlloyExpression) src).EXPR.type().toExpr().toString());
293+
} catch (Err e) {
294+
// TODO Auto-generated catch block
295+
e.printStackTrace();
296+
}
297+
IDecl d = context.getDecl(x, true);
298+
299+
// tries to determine owning model of the iterator variable
300+
for (String s : context.getVars()) {
301+
IExpression var = context.getVar(s);
302+
if (src.hasVar(var) && context.getVarModel(s) != null)
303+
context.addVar(d, context.getVarModel(s));
304+
else
305+
context.addVar(d);
306+
}
307+
308+
EStructuralFeature operat = expr.eClass().getEStructuralFeature(
309+
"name");
310+
String operatorname = (String) expr.eGet(operat);
311+
EStructuralFeature arguments = expr.eClass().getEStructuralFeature(
312+
"body");
313+
INode body = translateAtlOcl((EObject) expr.eGet(arguments));
314+
IFormula aux;
315+
316+
if (operatorname.equals("forAll")) {
317+
aux = (IFormula) body;
318+
aux = ((d.variable().in(src)).implies(aux));
319+
res = aux.forAll(d);
320+
}
321+
else if (operatorname.equals("exists")) {
322+
aux = (IFormula) body;
323+
aux = ((d.variable().in(src)).and(aux));
324+
res = aux.forSome(d);
325+
}
326+
else if (operatorname.equals("one")) {
327+
aux = (IFormula) body;
328+
aux = ((d.variable().in(src)).and(aux));
329+
res = aux.forOne(d);
330+
}
331+
else if (operatorname.equals("collect")) {
332+
aux = d.variable().in(src);
333+
res = src.join(aux.comprehension(d,
334+
((IExpression) body).oneOf("2_")));
335+
}
336+
else if (operatorname.equals("select")) {
337+
aux = (IFormula) body;
338+
aux = ((d.variable().in(src)).and(aux));
339+
res = aux.comprehension(d);
340+
}
341+
else if (operatorname.equals("any")) {
342+
aux = (IFormula) body;
343+
aux = ((d.variable().in(src)).and(aux));
344+
res = aux.comprehension(d);
345+
}
346+
else if (operatorname.equals("reject")) {
347+
aux = (IFormula) body;
348+
aux = ((d.variable().in(src)).and(aux.not()));
349+
res = aux.comprehension(d);
350+
}
351+
else if (operatorname.equals("closure")) {
352+
IDecl dd = ((IExpression) body).oneOf("2_");
353+
res = Constants.TRUE().comprehension(d, dd);
354+
res = src.join(((IExpression) res).closure());
355+
} else
356+
throw new ErrorUnsupported("OCL iterator not supported: "
357+
+ operatorname + ".");
358+
context.remove(d.name());
359+
360+
return res;
361+
}
266362

267363
// retrieves the Alloy field corresponding to an OCL property (attribute)
268364
IExpression propertyToField(String propn, IExpression var)
@@ -273,8 +369,8 @@ IExpression propertyToField(String propn, IExpression var)
273369
try {
274370
varsig = ((AlloyExpression) var).EXPR.type().toExpr().toString();
275371
metamodelID = EchoHelper.getMetamodelIDfromLabel(varsig);
276-
EMetamodel metamodel;
277-
metamodel = MDEManager.getInstance().getMetamodelID(metamodelID);
372+
EMetamodel metamodel = MDEManager.getInstance().getMetamodelID(metamodelID);
373+
278374
EStructuralFeature feature = ((EClass) metamodel.getEObject()
279375
.getEClassifier(EchoHelper.getClassifierName(varsig)))
280376
.getEStructuralFeature(propn);

plugins/pt.uminho.haslab.echo/src/pt/uminho/haslab/echo/engine/alloy/AlloyContext.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,9 @@ public AlloyDecl getDecl(EVariable var, boolean addContext) throws EchoError {
9393
try {
9494
// calculates the expression representing the type in the state
9595
Expr range = Sig.NONE;
96-
if (type.equals("String"))
96+
if (type == null)
97+
range = Sig.UNIV;
98+
else if (type.equals("String"))
9799
range = Sig.STRING;
98100
else if (type.equals("Int"))
99101
range = Sig.SIGINT;
@@ -116,10 +118,10 @@ else if (type.equals("Int"))
116118
}
117119
}
118120

119-
/** {@inheritDoc} */
121+
/** {@inheritDoc}
122+
* @throws ErrorParser */
120123
@Override
121-
public AlloyExpression getPropExpression(String metaModelID, String className, String fieldName) {
122-
EchoReporter.getInstance().debug("var models: "+varModel);
124+
public AlloyExpression getPropExpression(String metaModelID, String className, String fieldName) throws ErrorParser {
123125
EAlloyMetamodel ameta = AlloyEchoTranslator.getInstance().getMetamodel(metaModelID);
124126
AlloyExpression state = (AlloyExpression) Constants.EMPTY();
125127

@@ -131,6 +133,7 @@ public AlloyExpression getPropExpression(String metaModelID, String className, S
131133
// fetches the corresponding field
132134
EClass eclass = ((EClass) ameta.metamodel.getEObject().getEClassifier(className));
133135
EStructuralFeature feature = eclass.getEStructuralFeature(fieldName);
136+
if (feature == null) throw new ErrorParser("Field "+fieldName+" over "+className+" yielded null feature.");
134137
Field field = AlloyEchoTranslator.getInstance().getFieldFromFeature(metaModelID,feature);
135138

136139
// calculates the expression field.state

plugins/pt.uminho.haslab.echo/src/pt/uminho/haslab/mde/EMFParser.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -161,15 +161,15 @@ public static EObject loadATL(IPath atlPath) {
161161
InputStream f = resourceSet.getURIConverter().createInputStream(URI.createURI(atlPath.toOSString()));
162162
module = AtlParser.getDefault().parse(f);
163163

164-
// Resource resource = resourceSet.createResource(URI.createURI("/pt.uminho.haslab.echo.examples/adsateste.xmi"));
165-
// resource.getContents().add(module);
166-
// Map<Object,Object> options = new HashMap<Object,Object>();
167-
// options.put(XMLResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE);
168-
// try{
169-
// resource.save(options);
170-
// }catch (Exception e) {
171-
// throw new ErrorTransform(e.getMessage());
172-
// }
164+
Resource resource = resourceSet.createResource(URI.createURI("/pt.uminho.haslab.echo.examples/adsateste.xmi"));
165+
resource.getContents().add(module);
166+
Map<Object,Object> options = new HashMap<Object,Object>();
167+
options.put(XMLResource.OPTION_SCHEMA_LOCATION, Boolean.TRUE);
168+
try{
169+
resource.save(options);
170+
}catch (Exception e) {
171+
throw new ErrorTransform(e.getMessage());
172+
}
173173

174174
EchoReporter.getInstance().debug(module.eClass().toString());
175175
EchoReporter.getInstance().debug(module.eContents().toString());

0 commit comments

Comments
 (0)