Etude de cas : Transformation
SimplePDLToPetriNet
A.1 Code de la transformation SimplePDLToPetriNet
Ce code est accessible sur le d´epˆot officiel du projet Tom : https://gforge.inria.fr/
scm/?group_id=78. Pour plus d’informations sur le sujet, le lecteur pourra aussi se r´ef´erer
`
a la documentation en ligne accessible sur cette page :http://tom.loria.fr/wiki/index.
php5/Documentation:Playing_with_EMF.
1 import org.eclipse.emf.common.util.*; 2 import org.eclipse.emf.ecore.*; 3 import org.eclipse.emf.ecore.util.ECrossReferenceAdapter; 4 import org.eclipse.emf.ecore.xmi.*; 5 import org.eclipse.emf.ecore.xmi.impl.*; 6 7 import SimplePDLSemantics.DDMMSimplePDL.*; 8 import petrinetsemantics.DDMMPetriNet.*; 9 10 import SimplePDLSemantics.EDMMSimplePDL.*; 11 import petrinetsemantics.EDMMPetriNet.*; 12 import SimplePDLSemantics.SDMMSimplePDL.*; 13 import petrinetsemantics.SDMMPetriNet.*; 14 import SimplePDLSemantics.TM3SimplePDL.*; 15 import petrinetsemantics.TM3PetriNet.*; 16 17 import java.util.*; 18 import java.util.concurrent.ConcurrentMap; 19 import java.util.concurrent.ConcurrentHashMap; 20 import java.io.File; 21 import java.io.Writer; 22 import java.io.BufferedWriter; 23 import java.io.OutputStreamWriter; 24 import java.io.FileOutputStream; 25 import java.io.FileInputStream; 26 27 import tom.library.utils.ReferenceClass; 28 import tom.library.utils.LinkClass; 29 import tom.library.sl.*; 30 import tom.library.emf.*; 3132 public class SimplePDLToPetriNet {
33 34 %include{ sl.tom } 35 %include{ LinkClass.tom } 36 %include{ emf/ecore.tom } 37 38 %include{ mappings/DDMMPetriNetPackage.tom } 39 %include{ mappings/DDMMSimplePDLPackage.tom } 40 41 %include{ mappings/EDMMPetriNetPackage.tom } 42 %include{ mappings/EDMMSimplePDLPackage.tom } 43 %include{ mappings/SDMMPetriNetPackage.tom } 44 %include{ mappings/SDMMSimplePDLPackage.tom }
115
45 %include{ mappings/TM3PetriNetPackage.tom }
46 %include{ mappings/TM3SimplePDLPackage.tom }
47
48 %typeterm SimplePDLToPetriNet { implement { SimplePDLToPetriNet }}
49
50 private static Writer writer;
51 private static PetriNet pn = null;
52 private static LinkClass tom__linkClass;
53
54 public SimplePDLToPetriNet() {
55 this.tom__linkClass = new LinkClass();
56 }
57 58
59 %transformation SimplePDLToPetriNet(tom__linkClass:LinkClass,pn:PetriNet) : "metamodels/SimplePDLSemantics_updated.ecore" -> "metamodels/PetriNetSemantics_updated.ecore" {
60
61 definition P2PN traversal ‘TopDown(P2PN(tom__linkClass,pn)) {
62 p@Process[name=name] -> {
63 Place p_ready = ‘Place(name + "_ready", pn,ArcEList(), ArcEList(), 1);
64 Place p_running = ‘Place(name + "_running", pn,ArcEList(), ArcEList(), 0);
65 Place p_finished = ‘Place(name + "_finished", pn,ArcEList(), ArcEList(), 0);
66 String n1 = ‘name+"_start";
67 %tracelink(t_start:Transition, ‘Transition(n1, pn,ArcEList(), ArcEList(), 1, 1));
68 n1 = ‘name+"_finish";
69 %tracelink(t_finish:Transition, ‘Transition(n1, pn,ArcEList(), ArcEList(), 1, 1));
70
71 ‘Arc(t_start, p_ready, pn,ArcKindnormal(), 1);
72 ‘Arc(p_running, t_start, pn,ArcKindnormal(), 1);
73 ‘Arc(t_finish, p_running, pn,ArcKindnormal(), 1);
74 ‘Arc(p_finished, t_finish, pn,ArcKindnormal(), 1);
75
76 WorkDefinition from = ‘p.getFrom();
77 if (from!=null) {
78 Transition source = %resolve(from:WorkDefinition,t_start:Transition);
79 source.setNet(pn);
80 Arc tmpZoomIn = ‘Arc(p_ready,source,pn,ArcKindnormal(), 1);
81
82 Transition target = %resolve(from:WorkDefinition,t_finish:Transition);
83 target.setNet(pn);
84 Arc tmpZoomOut = ‘Arc(target,p_finished,pn,ArcKindread_arc(), 1);
85 }
86 }
87 }
88
89 definition WD2PN traversal ‘TopDown(WD2PN(tom__linkClass,pn)) {
90 wd@WorkDefinition[name=name] -> {
91 //System.out.println("Je suis un A");
92 Place p_ready = ‘Place(name + "_ready", pn,ArcEList(), ArcEList(), 1);
93 String n1 = ‘name+"_started";
94 %tracelink(p_started:Place, ‘Place(n1, pn,ArcEList(), ArcEList(), 0));
95 Place p_running = ‘Place(name+"_running", pn,ArcEList(), ArcEList(), 0);
96 n1 = ‘name+"_finished";
97 %tracelink(p_finished:Place, ‘Place(n1, pn,ArcEList(), ArcEList(), 0));
98 n1 = ‘name+"_start";
99 %tracelink(t_start:Transition, ‘Transition(n1, pn,ArcEList(), ArcEList(), 1, 1));
100 n1 = ‘name+"_finish";
101 %tracelink(t_finish:Transition, ‘Transition(n1, pn,ArcEList(), ArcEList(), 1, 1));
102
103 ‘Arc(t_start, p_ready, pn,ArcKindnormal(), 1);
104 ‘Arc(p_started, t_start, pn,ArcKindnormal(), 1);
105 ‘Arc(p_running, t_start, pn,ArcKindnormal(), 1);
106 ‘Arc(t_finish, p_running, pn,ArcKindnormal(), 1);
107 ‘Arc(p_finished, t_finish, pn,ArcKindnormal(), 1);
108
109 SimplePDLSemantics.DDMMSimplePDL.Process parent = ‘wd.getParent();
110 Transition source = %resolve(parent:Process,t_start:Transition);
111 source.setNet(pn);
112 Arc tmpDistribute = ‘Arc(p_ready,source,pn,ArcKindnormal(), 1);
113
114 Transition target = %resolve(parent:Process,t_finish:Transition);
115 target.setNet(pn);
116 Arc tmpRejoin = ‘Arc(target,p_finished,pn,ArcKindread_arc(), 1);
117 }
118 }
119
120 definition WS2PN traversal ‘TopDown(WS2PN(tom__linkClass,pn)) {
121 ws@WorkSequence[predecessor=p,successor=s,linkType=linkType] -> {
122 Place source= null;
123 Transition target= null;
A.1. Code de la transformationSimplePDLToPetriNet 117
125 WorkDefinition suc = ‘s; 126 %match(linkType) { 127 (WorkSequenceTypefinishToFinish|WorkSequenceTypefinishToStart)[] -> { 128 source = %resolve(pre:WorkDefinition,p_finished:Place); 129 } 130 (WorkSequenceTypestartToStart|WorkSequenceTypestartToFinish)[] -> { 131 source = %resolve(pre:WorkDefinition,p_started:Place); 132 } 133 134 (WorkSequenceTypefinishToStart|WorkSequenceTypestartToStart)[] -> { 135 target = %resolve(suc:WorkDefinition,t_start:Transition); 136 } 137 (WorkSequenceTypestartToFinish|WorkSequenceTypefinishToFinish)[] -> { 138 target = %resolve(suc:WorkDefinition,t_finish:Transition); 139 } 140 } 141 source.setNet(pn); 142 target.setNet(pn); 143144 Arc wsImage = ‘Arc(target,source, pn,ArcKindread_arc(), 1);
145 }
146 }
147 }
148
149 public static void main(String[] args) {
150 System.out.println("\nStarting...\n");
151
152 XMIResourceImpl resource = new XMIResourceImpl();
153 SimplePDLSemantics.DDMMSimplePDL.Process p_root;
154 Map opts = new HashMap();
155 opts.put(XMIResource.OPTION_SCHEMA_LOCATION, java.lang.Boolean.TRUE);
156
157 if (args.length>0) {
158 DDMMSimplePDLPackage packageInstance = DDMMSimplePDLPackage.eINSTANCE;
159 File input = new File(args[0]);
160 try {
161 resource.load(new FileInputStream(input),opts);
162 } catch (Exception e) {
163 e.printStackTrace();
164 }
165 p_root = (SimplePDLSemantics.DDMMSimplePDL.Process) resource.getContents().get(0);
166 } else {
167 System.out.println("No model instance given in argument. Using default hardcoded model.");
168 WorkDefinition wd1 = ‘WorkDefinition(null,WorkSequenceEList(),WorkSequenceEList(),"A",null); 169 WorkDefinition wd2 = ‘WorkDefinition(null,WorkSequenceEList(),WorkSequenceEList(),"B",null); 170 WorkDefinition wd3 = ‘WorkDefinition(null,WorkSequenceEList(),WorkSequenceEList(),"C",null); 171 WorkDefinition wd4 = ‘WorkDefinition(null,WorkSequenceEList(),WorkSequenceEList(),"D",null); 172 WorkSequence ws1 = ‘WorkSequence(null,WorkSequenceTypestartToStart(),wd1,wd2); 173 WorkSequence ws2 = ‘WorkSequence(null,WorkSequenceTypestartToFinish(),wd3,wd4); 174 175 p_root = ‘Process("root",ProcessElementEList(wd1,wd2,ws1),null);
176 SimplePDLSemantics.DDMMSimplePDL.Process p_child = ‘Process("child",ProcessElementEList(wd3,wd4,ws2), wd2);
177 178 wd1.setParent(p_root); 179 wd2.setParent(p_root); 180 wd2.setProcess(p_child); 181 182 wd3.setParent(p_child); 183 wd4.setParent(p_child); 184 185 ws1.setParent(p_root); 186 ws2.setParent(p_child); 187 }
188 SimplePDLToPetriNet translator = new SimplePDLToPetriNet();
189
190 try {
191 translator.pn = ‘PetriNet(NodeEList(),ArcEList(),"main");
192
193 //System.out.println("Initial Petri net");
194 //‘Sequence(TopDown(PrintTransition()),TopDown(PrintPlace())).visit(translator.pn, new EcoreContainmentIntrospector());
195
196 /*//transformer is equivalent to:
197 Strategy transformer = ‘Sequence(
198 TopDown(Process2PetriNet(translator)), 199 TopDown(WorkDefinition2PetriNet(translator)), 200 TopDown(WorkSequence2PetriNet(translator)) 201 ); 202 */ 203
205 //model as second one
206 Strategy transformer = ‘SimplePDLToPetriNet(translator.tom__linkClass,translator.pn);
207 transformer.visit(p_root, new EcoreContainmentIntrospector());
208 ‘TopDown(tom__StratResolve_SimplePDLToPetriNet(translator.tom__linkClass,translator.pn)).visit(translator.pn, new EcoreContainmentIntrospector());
209 210
211 //for generation of textual Petri nets usable as input for TINA
212 String outputName = "resultingPetri.net";
213 writer = new BufferedWriter(new OutputStreamWriter(new
214 FileOutputStream(new File(outputName)))); 215 216 System.out.println("\nResult"); 217 ‘Sequence(TopDown(PrintTransition()),TopDown(PrintPlace())).visit(translator.pn, 218 new EcoreContainmentIntrospector()); 219
220 System.out.println("\nFinish to generate "+outputName+" file, usable as input for TINA");
221 writer.flush(); 222 writer.close(); 223 System.out.println("done."); 224 225 } catch(VisitFailure e) { 226 System.out.println("strategy fail!"); 227 } catch(java.io.FileNotFoundException e) {
228 System.out.println("Cannot create Petri net output file.");
229 } catch (java.io.IOException e) {
230 System.out.println("Petri net save failed!");
231 }
232 }
233
234 %strategy PrintArc() extends Identity() {
235 visit Arc { 236 Arc[source=node1, target=node2] -> { 237 System.out.println(‘node1.getName() + " -> " + ‘node2.getName()); 238 } 239 } 240 } 241
242 %strategy PrintTransition() extends Identity() {
243 visit Transition {
244 tr@ResolveWorkDefinitionTransition[tom_resolve_element_attribute_name=name] -> {
245 System.out.println("tr resolve " + ‘name);
246 return ‘tr;
247 }
248
249 ptr@ResolveProcessTransition[tom_resolve_element_attribute_name=name] -> {
250 System.out.println("tr process resolve " + ‘name);
251 return ‘ptr; 252 } 253 254 Transition[name=name,incomings=sources,outgoings=targets] -> { 255 String s = " "; 256 String t = " "; 257 %match {
258 ArcEList(_*,Arc[kind=k,weight=w,source=node],_*) << sources && Place[name=placename]<< node -> {
259 s += ‘placename + ((‘k==‘ArcKindread_arc())?"?":"*") + ‘w + " ";
260 }
261 ArcEList(_*,Arc[kind=k,weight=w,target=node],_*) << targets && Place[name=placename]<< node -> {
262 t += ‘placename + ((‘k==‘ArcKindread_arc())?"?":"*") + ‘w + " "; 263 } 264 } 265 multiPrint("tr " + ‘name + s + "->" + t); 266 } 267 268 269 } 270 } 271
272 %strategy PrintPlace() extends Identity() {
273 visit Place {
274 pl@ResolveWorkDefinitionPlace[tom_resolve_element_attribute_name=name] -> {
275 System.out.println("pl resolve " + ‘name);
276 return ‘pl; 277 } 278 279 Place[name=name,initialMarking=w] && w!=0 -> { 280 multiPrint("pl " + ‘name + " " + "(" + ‘w + ")"); 281 } 282 283 } 284 }
A.2. Mod`ele source 119
285
286 public static void multiPrint(String s) {
287 System.out.println(s);
288 try {
289 writer.write(s+"\n");
290 } catch (java.io.IOException e) {
291 System.out.println("Petri net save failed!");
292 }
293 }
294 295 }
A.2 Mod`ele source
Cette transformation a ´et´e test´ee avec de nombreux mod`eles. Le mod`ele donn´e par le
listing 1 est le mod`ele donn´e en exemple dans la section 7.1 du chapitre 7. Il s’agit aussi du
mod`ele par d´efaut de la transformation dans le cas o`u aucun mod`ele n’est pass´e en param`etre
(c’est en fait le mod`ele ´equivalent directement construit enTomsans chargement de fichier).
<?xml version="1.0" encoding="ASCII"?>
<simplepdl.ddmm:Process xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:simplepdl.ddmm="simplepdl.ddmm" xsi:schemaLocation="simplepdl.ddmm SimplePDLSemantics.ecore#//DDMMSimplePDL" name="root">
<processElements xsi:type="simplepdl.ddmm:WorkDefinition" linksToSuccessors="//@processElements.2" name="A"/> <processElements xsi:type="simplepdl.ddmm:WorkDefinition" linksToPredecessors="//@processElements.2" name="B">
<process name="child">
<processElements xsi:type="simplepdl.ddmm:WorkDefinition"
linksToSuccessors="//@processElements.1/@process/@processElements.2" name="C"/> <processElements xsi:type="simplepdl.ddmm:WorkDefinition"
linksToPredecessors="//@processElements.1/@process/@processElements.2" name="D"/> <processElements xsi:type="simplepdl.ddmm:WorkSequence" linkType="startToFinish"
predecessor="//@processElements.1/@process/@processElements.0" successor="//@processElements.1/@process/@processElements.1"/> </process> </processElements> <processElements xsi:type="simplepdl.ddmm:WorkSequence" predecessor="//@processElements.0" successor="//@processElements.1"/> </simplepdl.ddmm:Process>
Listing 1 – Mod`ele source de l’exemple pour la transformation SimplePDLToPetriNet (format.xmi)
A.3 Mod`ele r´esultant
Le mod`ele source donn´e pr´ec´edemment produit le mod`ele cible suivant 2, qui est en fait le
r´eseau de Petri r´esultant de la transformation, s´erialis´e sous la forme d’un fichier au format
compatible avec l’entr´ee dumodel-checker TINA[BRV04] (il est aussi affich´e directement sur
la sortie standard) :
tr root_start root_ready*1 -> root_running*1 A_ready*1 B_ready*1
tr root_finish root_running*1 A_finished?1 B_finished?1 -> root_finished*1 tr child_start child_ready*1 -> child_running*1 C_ready*1 D_ready*1
tr child_finish child_running*1 C_finished?1 D_finished?1 -> child_finished*1 tr B_start B_ready*1 A_started?1 -> B_started*1 B_running*1 child_ready*1 tr B_finish B_running*1 child_finished?1 -> B_finished*1
tr A_start A_ready*1 -> A_started*1 A_running*1 tr A_finish A_running*1 -> A_finished*1 tr C_start C_ready*1 -> C_started*1 C_running*1 tr C_finish C_running*1 -> C_finished*1 tr D_start D_ready*1 -> D_started*1 D_running*1 tr D_finish D_running*1 C_started?1 -> D_finished*1 pl root_ready (1) pl child_ready (1) pl A_ready (1) pl B_ready (1) pl C_ready (1) pl D_ready (1)