diff --git a/livrables/PDL.xtext b/livrables/PDL.xtext new file mode 100644 index 0000000..192c6a3 --- /dev/null +++ b/livrables/PDL.xtext @@ -0,0 +1,51 @@ +// automatically generated by Xtext +grammar fr.n7.simplepdl.txt.PDL with org.eclipse.xtext.common.Terminals + +import "http://simplepdl" +import "http://www.eclipse.org/emf/2002/Ecore" as ecore + +Process returns Process : + {Process} + 'process' name=ID '{' + processElements+=ProcessElement* + '}' ; + +ProcessElement returns ProcessElement: + WorkDefinition | WorkSequence | Guidance | Resource +; + +WorkDefinition returns WorkDefinition : + {WorkDefinition} + 'wd' name=ID + requests+=Request* +; + +WorkSequence returns WorkSequence : + {WorkSequence} + 'ws' linkType=WorkSequenceType + 'from' predecessor=[WorkDefinition] + 'to' successor=[WorkDefinition] +; + +Guidance returns Guidance : + {Guidance} + 'note' text=STRING +; + +Resource returns Resource : + {Resource} + 'res' name=ID quantity=INT +; + +Request returns Request : + {Request} + 'req' target=[Resource] quantity=INT +; + + +enum WorkSequenceType returns WorkSequenceType : + startToStart = 's2s' + | finishToStart = 'f2s' + | startToFinish = 's2f' + | finishToFinish = 'f2f' +; diff --git a/livrables/PetriNet2Tina.mtl b/livrables/PetriNet2Tina.mtl deleted file mode 120000 index 68c5bd1..0000000 --- a/livrables/PetriNet2Tina.mtl +++ /dev/null @@ -1 +0,0 @@ -../eclipse-workspace/fr.n7.petrinet.toTINA/src/fr/n7/petrinet/toTINA/main/toTINA.mtl \ No newline at end of file diff --git a/livrables/SimplePDL-finish.mtl b/livrables/SimplePDL-finish.mtl new file mode 100644 index 0000000..49d4cfd --- /dev/null +++ b/livrables/SimplePDL-finish.mtl @@ -0,0 +1,19 @@ +[comment encoding = UTF-8 /] +[module toLTL('http://simplepdl')] + + +[template public processToLTL(aProcess : Process)] +[comment @main/] +[file (aProcess.name + '.ltl', false, 'UTF-8')] +[let wds : OrderedSet(WorkDefinition) = aProcess.getWDs() ] +[for (wds) before ('[] <> (') separator (' /\\ ') after (');')][self.name + '_finished'/][/for] +[/let] +[/file] +[/template] + + +[query public getWDs(p: Process) : OrderedSet(WorkDefinition) = + p.processElements->select( e | e.oclIsTypeOf(WorkDefinition) ) + ->collect( e | e.oclAsType(WorkDefinition) ) + ->asOrderedSet() +/] \ No newline at end of file diff --git a/livrables/SimplePDL-invariants.mtl b/livrables/SimplePDL-invariants.mtl new file mode 100644 index 0000000..96c5c18 --- /dev/null +++ b/livrables/SimplePDL-invariants.mtl @@ -0,0 +1,20 @@ +[comment encoding = UTF-8 /] +[module toLTL('http://simplepdl')] + + +[template public processToLTL(aProcess : Process)] +[comment @main/] +[file (aProcess.name + '.ltl', false, 'UTF-8')] +[let wds : OrderedSet(WorkDefinition) = aProcess.getWDs() ] +[for (wds) before ('[] <> ((') separator (') /\\ (') after ('));')]['(' + self.name + '_idle /\\ -' + self.name + '_running /\\ -' + self.name + '_finished) \\/ (-' + self.name + '_idle /\\ ' + self.name + '_running /\\ -' + self.name + '_finished) \\/ (-' + self.name + '_idle /\\ -' + self.name + '_running /\\ ' + self.name + '_finished)'/][/for] +[for (wds) before ('[] <> ((') separator (') /\\ (') after ('));')][self.name + '_finished => [](-' + self.name + '_running' + ' /\\ -' + self.name + '_idle /\\ ' + self.name + '_started)'/][/for] +[/let] +[/file] +[/template] + + +[query public getWDs(p: Process) : OrderedSet(WorkDefinition) = + p.processElements->select( e | e.oclIsTypeOf(WorkDefinition) ) + ->collect( e | e.oclAsType(WorkDefinition) ) + ->asOrderedSet() +/] \ No newline at end of file diff --git a/livrables/SimplePDL2PetriNet.atl b/livrables/SimplePDL2PetriNet.atl new file mode 100644 index 0000000..bb6097f --- /dev/null +++ b/livrables/SimplePDL2PetriNet.atl @@ -0,0 +1,158 @@ +module SimplePDL2PetriNet; +create OUT: petrinet from IN: simplepdl; + + +-- Obtenir la place correspondant au predecesseur d'une WorkSequence +helper context simplepdl!WorkSequence +def: getPlaceOfPredecessor(): petrinet!Place = + if self.linkType = #startToStart or self.linkType = #startToFinish then + petrinet!Place.allInstances() + ->select(p | p.name = self.predecessor.name + '_started') + ->asSequence()->first() + else + petrinet!Place.allInstances() + ->select(p | p.name = self.predecessor.name + '_finished') + ->asSequence()->first() + endif; + +-- Obtenir la transition correspondant au successeur d'une WorkSequence +helper context simplepdl!WorkSequence +def: getTransitionOfSuccessor(): petrinet!Transition = + if self.linkType = #startToStart or self.linkType = #finishToStart then + petrinet!Transition.allInstances() + ->select(t | t.name = self.successor.name + '_start') + ->asSequence()->first() + else + petrinet!Transition.allInstances() + ->select(t | t.name = self.successor.name + '_finish') + ->asSequence()->first() + endif; + +-- Obtenir la place correspondant a la Resource d'une Request +helper context simplepdl!Request +def: getPlaceOfTarget(): petrinet!Place = + petrinet!Place.allInstances() + ->select(p | p.name = self.target.name + '_resource') + ->asSequence()->first(); + +-- Obtenir la transition start correspondant au Requester d'une Request +helper context simplepdl!Request +def: getStartTransitionOfRequester(): petrinet!Transition = + petrinet!Transition.allInstances() + ->select(t | t.name = self.requester.name + '_start') + ->asSequence()->first(); + +-- Obtenir la transition finish correspondant au Requester d'une Request +helper context simplepdl!Request +def: getFinishTransitionOfRequester(): petrinet!Transition = + petrinet!Transition.allInstances() + ->select(t | t.name = self.requester.name + '_finish') + ->asSequence()->first(); + + +-- Traduire un Process en un PetriNet de même nom +rule Process2PetriNet { + from p: simplepdl!Process + to pn: petrinet!Network (name <- p.name) +} + +-- Traduire une WorkDefinition en un motif sur le réseau de Petri +rule WorkDefinition2PetriNet { + from wd: simplepdl!WorkDefinition + to + -- PLACES d'une WorkDefinition + p_idle: petrinet!Place( + name <- wd.name + '_idle', + tokens <- 1, + network <- wd.process), + p_running: petrinet!Place( + name <- wd.name + '_running', + tokens <- 0, + network <- wd.process), + p_started: petrinet!Place( + name <- wd.name + '_started', + tokens <- 0, + network <- wd.process), + p_finished: petrinet!Place( + name <- wd.name + '_finished', + tokens <- 0, + network <- wd.process), + -- TRANSITIONS d'une WorkDefinition + t_start: petrinet!Transition( + name <- wd.name + '_start', + network <- wd.process), + t_finish: petrinet!Transition( + name <- wd.name + '_finish', + network <- wd.process), + -- ARCS d'un WorkDefinition + a_idle2start: petrinet!Arc( + place <- p_idle, + transition <- t_start, + outgoing <- false, + weight <- 1), + a_start2running: petrinet!Arc( + place <- p_running, + transition <- t_start, + outgoing <- true, + weight <- 1), + a_start2started: petrinet!Arc( + place <- p_started, + transition <- t_start, + outgoing <- true, + weight <- 1), + a_running2finish: petrinet!Arc( + place <- p_running, + transition <- t_finish, + outgoing <- false, + weight <- 1), + a_finish2finished: petrinet!Arc( + place <- p_finished, + transition <- t_finish, + outgoing <- true, + weight <- 1) +} + +-- Traduire une WorkDefinition en un motif sur le réseau de Petri +rule WorkSequence2PetriNet { + from ws: simplepdl!WorkSequence + to + -- ARCS d'une WorkSequence + arc1: petrinet!Arc( + place <- ws.getPlaceOfPredecessor(), + transition <- ws.getTransitionOfSuccessor(), + outgoing <- false, + weight <- 1), + arc2: petrinet!Arc( + place <- ws.getPlaceOfPredecessor(), + transition <- ws.getTransitionOfSuccessor(), + outgoing <- true, + weight <- 1) +} + +-- Traduire une Resource en un motif sur le réseau de Petri +rule Resource2PetriNet { + from res: simplepdl!Resource + to + -- PLACE d'une Resource + place: petrinet!Place( + name <- res.name + '_resource', + tokens <- res.quantity, + network <- res.process) +} + +-- Traduire une Request en un motif sur le réseau de Petri +rule Request2PetriNet { + from req: simplepdl!Request + to + -- ARCS d'une Request + arcs1: petrinet!Arc( + place <- req.getPlaceOfTarget(), + transition <- req.getStartTransitionOfRequester(), + outgoing <- false, + weight <- req.quantity), + arcs2: petrinet!Arc( + place <- req.getPlaceOfTarget(), + transition <- req.getFinishTransitionOfRequester(), + outgoing <- true, + weight <- req.quantity) +} \ No newline at end of file diff --git a/livrables/SimplePDL2PetriNet.java b/livrables/SimplePDL2PetriNet.java deleted file mode 120000 index a12e0fd..0000000 --- a/livrables/SimplePDL2PetriNet.java +++ /dev/null @@ -1 +0,0 @@ -../eclipse-workspace/fr.n7.simplepdl/src/simplepdl/manip/simplepdl2petrinet.java \ No newline at end of file diff --git a/livrables/ko-net.xmi b/livrables/ko-net.xmi deleted file mode 120000 index 8dc14b5..0000000 --- a/livrables/ko-net.xmi +++ /dev/null @@ -1 +0,0 @@ -../eclipse-workspace/fr.n7.petrinet/ko-net.xmi \ No newline at end of file diff --git a/livrables/ko-net.xmi b/livrables/ko-net.xmi new file mode 100644 index 0000000..ada751d --- /dev/null +++ b/livrables/ko-net.xmi @@ -0,0 +1,26 @@ + + + + + + + + + + diff --git a/livrables/ko-pdl1.xmi b/livrables/ko-pdl1.xmi deleted file mode 120000 index c304f71..0000000 --- a/livrables/ko-pdl1.xmi +++ /dev/null @@ -1 +0,0 @@ -../eclipse-workspace/fr.n7.simplepdl/ko-pdl1.xmi \ No newline at end of file diff --git a/livrables/ko-pdl1.xmi b/livrables/ko-pdl1.xmi new file mode 100644 index 0000000..bf30c46 --- /dev/null +++ b/livrables/ko-pdl1.xmi @@ -0,0 +1,37 @@ + + + + + + + + + + + + diff --git a/livrables/ko-pdl2.xmi b/livrables/ko-pdl2.xmi deleted file mode 120000 index 05f793a..0000000 --- a/livrables/ko-pdl2.xmi +++ /dev/null @@ -1 +0,0 @@ -../eclipse-workspace/fr.n7.simplepdl/ko-pdl2.xmi \ No newline at end of file diff --git a/livrables/ko-pdl2.xmi b/livrables/ko-pdl2.xmi new file mode 100644 index 0000000..1ae0113 --- /dev/null +++ b/livrables/ko-pdl2.xmi @@ -0,0 +1,32 @@ + + + + + + + + + diff --git a/livrables/net.xmi b/livrables/net.xmi deleted file mode 120000 index 493b2f7..0000000 --- a/livrables/net.xmi +++ /dev/null @@ -1 +0,0 @@ -../eclipse-workspace/fr.n7.petrinet/net.xmi \ No newline at end of file diff --git a/livrables/net.xmi b/livrables/net.xmi new file mode 100644 index 0000000..d223b9d --- /dev/null +++ b/livrables/net.xmi @@ -0,0 +1,24 @@ + + + + + + + + + diff --git a/livrables/pdl-sujet.net b/livrables/pdl-sujet.net deleted file mode 120000 index 90e0749..0000000 --- a/livrables/pdl-sujet.net +++ /dev/null @@ -1 +0,0 @@ -../eclipse-workspace/fr.n7.petrinet.exemples/gen/Developpement.net \ No newline at end of file diff --git a/livrables/pdl-sujet.net b/livrables/pdl-sujet.net new file mode 100644 index 0000000..a6d66ac --- /dev/null +++ b/livrables/pdl-sujet.net @@ -0,0 +1,25 @@ +net Developpement +pl Conception_idle (1) +pl Conception_running (0) +pl Conception_started (0) +pl Conception_finished (0) +pl RedactionTest_idle (1) +pl RedactionTest_running (0) +pl RedactionTest_started (0) +pl RedactionTest_finished (0) +pl RedactionDoc_idle (1) +pl RedactionDoc_running (0) +pl RedactionDoc_started (0) +pl RedactionDoc_finished (0) +pl Programmation_idle (1) +pl Programmation_running (0) +pl Programmation_started (0) +pl Programmation_finished (0) +tr Conception_start Conception_idle*1 -> Conception_running*1 Conception_started*1 +tr Conception_finish Conception_running*1 -> Conception_finished*1 +tr RedactionTest_start RedactionTest_idle*1 Conception_started*1 -> RedactionTest_running*1 RedactionTest_started*1 Conception_started*1 +tr RedactionTest_finish RedactionTest_running*1 Programmation_finished*1 -> RedactionTest_finished*1 Programmation_finished*1 +tr RedactionDoc_start RedactionDoc_idle*1 Conception_started*1 -> RedactionDoc_running*1 RedactionDoc_started*1 Conception_started*1 +tr RedactionDoc_finish RedactionDoc_running*1 Conception_finished*1 -> RedactionDoc_finished*1 Conception_finished*1 +tr Programmation_start Programmation_idle*1 Conception_finished*1 -> Programmation_running*1 Programmation_started*1 Conception_finished*1 +tr Programmation_finish Programmation_running*1 -> Programmation_finished*1 diff --git a/livrables/pdl-sujet.xmi b/livrables/pdl-sujet.xmi deleted file mode 120000 index 6f874ae..0000000 --- a/livrables/pdl-sujet.xmi +++ /dev/null @@ -1 +0,0 @@ -../eclipse-workspace/fr.n7.simplepdl/pdl-sujet.xmi \ No newline at end of file diff --git a/livrables/pdl-sujet.xmi b/livrables/pdl-sujet.xmi new file mode 100644 index 0000000..d312792 --- /dev/null +++ b/livrables/pdl-sujet.xmi @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/livrables/petriNet.aird b/livrables/petriNet.aird deleted file mode 120000 index 720deba..0000000 --- a/livrables/petriNet.aird +++ /dev/null @@ -1 +0,0 @@ -../eclipse-workspace/fr.n7.petrinet/petrinet.aird \ No newline at end of file diff --git a/livrables/petriNet.aird b/livrables/petriNet.aird new file mode 100644 index 0000000..8d6e5bf --- /dev/null +++ b/livrables/petriNet.aird @@ -0,0 +1,367 @@ + + + + petriNet.ecore + petriNet.genmodel + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bold + + + + + + + + + + + + + + + + bold + + + + bold + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + bold + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + italic + + + + + + + + bold + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + bold + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + bold + + + + + + + + bold + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + + + + + + + + + + + bold + + + bold + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/livrables/petriNet.ecore b/livrables/petriNet.ecore deleted file mode 120000 index 84c351d..0000000 --- a/livrables/petriNet.ecore +++ /dev/null @@ -1 +0,0 @@ -../eclipse-workspace/fr.n7.petrinet/petrinet.ecore \ No newline at end of file diff --git a/livrables/petriNet.ecore b/livrables/petriNet.ecore new file mode 100644 index 0000000..18832c8 --- /dev/null +++ b/livrables/petriNet.ecore @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/livrables/petriNet.ocl b/livrables/petriNet.ocl deleted file mode 120000 index 831998f..0000000 --- a/livrables/petriNet.ocl +++ /dev/null @@ -1 +0,0 @@ -../eclipse-workspace/fr.n7.petrinet/petrinet.ocl \ No newline at end of file diff --git a/livrables/petriNet.ocl b/livrables/petriNet.ocl new file mode 100644 index 0000000..f44a2e3 --- /dev/null +++ b/livrables/petriNet.ocl @@ -0,0 +1,21 @@ +import 'petriNet.ecore' + +package petrinet + +context Network +inv validName('Invalid name: ' + self.name): + self.name.matches('[A-Za-z_][A-Za-z0-9_]*') +inv uniqNamesNode: self.nodes + ->forAll(n1, n2 | n1 = n2 or n1.name <> n2.name) + +context Node +inv nameMin2Char: self.name.matches('..+') +inv weirdName: not self.name.matches('([0-9]*|_*)') + +context Place +inv negativeQuantity: self.tokens >= 0 + +context Arc +inv negativeQuantity: self.weight >= 0 + +endpackage \ No newline at end of file diff --git a/livrables/petriNet.png b/livrables/petriNet.png deleted file mode 120000 index 10d97b1..0000000 --- a/livrables/petriNet.png +++ /dev/null @@ -1 +0,0 @@ -../eclipse-workspace/fr.n7.petrinet/petrinet.png \ No newline at end of file diff --git a/livrables/petriNet.png b/livrables/petriNet.png new file mode 100644 index 0000000..ec8af88 Binary files /dev/null and b/livrables/petriNet.png differ diff --git a/livrables/simplePDL.aird b/livrables/simplePDL.aird deleted file mode 120000 index 2b20f3a..0000000 --- a/livrables/simplePDL.aird +++ /dev/null @@ -1 +0,0 @@ -../eclipse-workspace/fr.n7.simplepdl/simplepdl.aird \ No newline at end of file diff --git a/livrables/simplePDL.aird b/livrables/simplePDL.aird new file mode 100644 index 0000000..f896f3a --- /dev/null +++ b/livrables/simplePDL.aird @@ -0,0 +1,635 @@ + + + + simplePDL.ecore + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bold + + + + + + + bold + + + + bold + + + + + + + + + + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + italic + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + bold + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + bold + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + bold + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + bold + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + bold + + + + + + + + bold + + + + + + + + KEEP_LOCATION + KEEP_SIZE + KEEP_RATIO + + + + + + + + + bold + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + italic + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bold + + + bold + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/livrables/simplePDL.ecore b/livrables/simplePDL.ecore deleted file mode 120000 index 47a4397..0000000 --- a/livrables/simplePDL.ecore +++ /dev/null @@ -1 +0,0 @@ -../eclipse-workspace/fr.n7.simplepdl/simplepdl.ecore \ No newline at end of file diff --git a/livrables/simplePDL.ecore b/livrables/simplePDL.ecore new file mode 100644 index 0000000..43c3f3b --- /dev/null +++ b/livrables/simplePDL.ecore @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/livrables/simplePDL.ocl b/livrables/simplePDL.ocl deleted file mode 120000 index 7b90572..0000000 --- a/livrables/simplePDL.ocl +++ /dev/null @@ -1 +0,0 @@ -../eclipse-workspace/fr.n7.simplepdl/simplepdl.ocl \ No newline at end of file diff --git a/livrables/simplePDL.ocl b/livrables/simplePDL.ocl new file mode 100644 index 0000000..4e7a91f --- /dev/null +++ b/livrables/simplePDL.ocl @@ -0,0 +1,44 @@ +import 'simplePDL.ecore' + +package simplepdl + +context Process +inv validName('Invalid name: ' + self.name): + self.name.matches('[A-Za-z_][A-Za-z0-9_]*') +inv uniqNamesWD: self.processElements + ->select(pe | pe.oclIsKindOf(WorkDefinition)) + ->collect(pe | pe.oclAsType(WorkDefinition)) + ->forAll(w1, w2 | w1 = w2 or w1.name <> w2.name) +inv uniqNamesRes: self.processElements + ->select(pe | pe.oclIsKindOf(Resource)) + ->collect(pe | pe.oclAsType(Resource)) + ->forAll(r1, r2 | r1 = r2 or r1.name <> r2.name) + +context ProcessElement +def: process(): Process = + Process.allInstances() + ->select(p | p.processElements->includes(self)) + ->asSequence()->first() + +context WorkSequence +inv successorAndPredecessorInSameProcess('Activities not in the same process : ' + + self.predecessor.name + ' in ' + self.predecessor.process().name+ ' and ' + + self.successor.name + ' in ' + self.successor.process().name): + self.process() = self.successor.process() + and self.process() = self.predecessor.process() +inv notReflexive: self.predecessor <> self.successor + +context WorkDefinition +inv nameMin2Char: self.name.matches('..+') +inv weirdName: not self.name.matches('([0-9]*|[a-zA-Z]*|_*)') + +context Resource +inv negativeQuantity: self.quantity > 0 +inv nameMin2Char: self.name.matches('..+') +inv weirdName: not self.name.matches('([0-9]*|_*)') + +context Request +inv negativeQuantity: self.quantity > 0 +inv greedy: self.quantity <= self.target.quantity + +endpackage \ No newline at end of file diff --git a/livrables/simplePDL.odesign b/livrables/simplePDL.odesign deleted file mode 120000 index 867c975..0000000 --- a/livrables/simplePDL.odesign +++ /dev/null @@ -1 +0,0 @@ -../eclipse-workspace/fr.n7.simplepdl.design/description/simplepdl.odesign \ No newline at end of file diff --git a/livrables/simplePDL.odesign b/livrables/simplePDL.odesign new file mode 100644 index 0000000..66c2da7 --- /dev/null +++ b/livrables/simplePDL.odesign @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/livrables/simplePDL.png b/livrables/simplePDL.png deleted file mode 120000 index 48537fd..0000000 --- a/livrables/simplePDL.png +++ /dev/null @@ -1 +0,0 @@ -../eclipse-workspace/fr.n7.simplepdl/simplepdl.png \ No newline at end of file diff --git a/livrables/simplePDL.png b/livrables/simplePDL.png new file mode 100644 index 0000000..bb66955 Binary files /dev/null and b/livrables/simplePDL.png differ diff --git a/livrables/simplepdl2petrinet.java b/livrables/simplepdl2petrinet.java new file mode 100644 index 0000000..a18c63e --- /dev/null +++ b/livrables/simplepdl2petrinet.java @@ -0,0 +1,236 @@ +package simplepdl.manip; + +import java.io.IOException; +import java.util.Collections; +import java.util.Map; + +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; +import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl; + +import petrinet.Arc; +import petrinet.Network; +import petrinet.Node; +import petrinet.PetrinetFactory; +import petrinet.PetrinetPackage; +import petrinet.Place; +import petrinet.Transition; +import simplepdl.Process; +import simplepdl.SimplepdlPackage; +import simplepdl.WorkDefinition; +import simplepdl.WorkSequence; +import simplepdl.WorkSequenceType; +import simplepdl.Request; + +public class simplepdl2petrinet { + + public static void main(String[] args) { + + // Charger les package SimplePDL et Petrinet afin de les enregistrer dans le registre d'Eclipse. + SimplepdlPackage packageInstance = SimplepdlPackage.eINSTANCE; + PetrinetPackage packageInstance2 = PetrinetPackage.eINSTANCE; + + // Enregistrer l'extension ".xmi" comme devant être ouverte à + // l'aide d'un objet "XMIResourceFactoryImpl" + Resource.Factory.Registry reg = Resource.Factory.Registry.INSTANCE; + Map m = reg.getExtensionToFactoryMap(); + m.put("xmi", new XMIResourceFactoryImpl()); + + // Créer un objet resourceSetImpl qui contiendra une ressource EMF (le modèle) + ResourceSet resSet = new ResourceSetImpl(); + + // Charger la ressource (notre modèle) + URI modelURI = URI.createURI("models/developpement.xmi"); + Resource resource = resSet.getResource(modelURI, true); + + // Récupérer le premier élément du modèle (élément racine) + Process process = (Process) resource.getContents().get(0); + + // La fabrique pour fabriquer les éléments de PetriNET + PetrinetFactory myFactory = PetrinetFactory.eINSTANCE; + + // Créer un élément Network + Network network = myFactory.createNetwork(); + network.setName(process.getName()); + + // Conversion des Resource en Places + for (Object o : process.getProcessElements()) { + if (o instanceof simplepdl.Resource) { + + simplepdl.Resource r = (simplepdl.Resource) o; + String name = r.getName(); + int qty = r.getQuantity(); + + Place res = myFactory.createPlace(); + res.setName(name + "_resource"); + res.setTokens(qty); + + network.getNodes().add(res); + } + } + + // Conversion des WorkDefinition en Node et Transition + for (Object o : process.getProcessElements()) { + if (o instanceof WorkDefinition) { + WorkDefinition wd = (WorkDefinition) o; + String name = wd.getName(); + + Place idle = myFactory.createPlace(); + idle.setName(name + "_idle"); + idle.setTokens(1); + Place started = myFactory.createPlace(); + started.setName(name + "_started"); + started.setTokens(0); + Place running = myFactory.createPlace(); + running.setName(name + "_running"); + running.setTokens(0); + Place finished = myFactory.createPlace(); + finished.setName(name + "_finished"); + finished.setTokens(0); + + Arc pause2start = myFactory.createArc(); + pause2start.setPlace(idle); + pause2start.setOutgoing(false); + pause2start.setWeight(1); + Arc start2running = myFactory.createArc(); + start2running.setPlace(running); + start2running.setOutgoing(true); + start2running.setWeight(1); + Arc start2started = myFactory.createArc(); + start2started.setPlace(started); + start2started.setOutgoing(true); + start2started.setWeight(1); + Transition start = myFactory.createTransition(); + start.setName(name + "_start"); + start.getArcs().add(pause2start); + start.getArcs().add(start2running); + start.getArcs().add(start2started); + + Arc running2finish = myFactory.createArc(); + running2finish.setPlace(running); + running2finish.setOutgoing(false); + running2finish.setWeight(1); + Arc finish2finished = myFactory.createArc(); + finish2finished.setPlace(finished); + finish2finished.setOutgoing(true); + finish2finished.setWeight(1); + Transition finish = myFactory.createTransition(); + finish.setName(name + "_finish"); + finish.getArcs().add(running2finish); + finish.getArcs().add(finish2finished); + + network.getNodes().add(idle); + network.getNodes().add(start); + network.getNodes().add(started); + network.getNodes().add(running); + network.getNodes().add(finish); + network.getNodes().add(finished); + + // Conversion des Requests s'il y en a + for (Request req : wd.getRequests()) { + + int qty = req.getQuantity(); + Place target = null; + + for (Node node : network.getNodes()) { + if (node instanceof Place) { + Place place = (Place) node; + if (place.getName().equals(req.getTarget().getName() + "_resource")) { + target = place; + } + } + } + + Arc res2start = myFactory.createArc(); + res2start.setPlace(target); + res2start.setOutgoing(false); + res2start.setWeight(qty); + Arc finish2res = myFactory.createArc(); + finish2res.setPlace(target); + finish2res.setOutgoing(true); + finish2res.setWeight(qty); + + start.getArcs().add(res2start); + finish.getArcs().add(finish2res); + } + } + } + + // Conversion des WorkSequence en Node et Transition + for (Object o : process.getProcessElements()) { + if (o instanceof WorkSequence) { + WorkSequence ws = (WorkSequence) o; + WorkSequenceType type = ws.getLinkType(); + WorkDefinition predecessor = ws.getPredecessor(); + WorkDefinition successor = ws.getSuccessor(); + + // creation des suffixs permettant la recherche des noeuds + String predecessor_suffix = new String(); + String successor_suffix = new String(); + switch (type) { + case START_TO_START: + predecessor_suffix = "_started"; + successor_suffix = "_start"; + break; + case START_TO_FINISH: + predecessor_suffix = "_started"; + successor_suffix = "_finished"; + break; + case FINISH_TO_START: + predecessor_suffix = "_finished"; + successor_suffix = "_start"; + break; + case FINISH_TO_FINISH: + predecessor_suffix = "_finished"; + successor_suffix = "_finish"; + break; + default: + System.out.print("the fuck ?"); + break; + } + + // creation du read-arc + Arc arc1 = myFactory.createArc(); + arc1.setOutgoing(false); + arc1.setWeight(1); + Arc arc2 = myFactory.createArc(); + arc2.setOutgoing(true); + arc2.setWeight(1); + + for (Node node : network.getNodes()) { + if (node instanceof Place) { + Place place = (Place) node; + if (place.getName().equals(predecessor.getName() + predecessor_suffix)) { + arc1.setPlace(place); + arc2.setPlace(place); + } + } + if (node instanceof Transition) { + Transition transition = (Transition) node; + if (transition.getName().equals(successor.getName() + successor_suffix)) { + transition.getArcs().add(arc1); + transition.getArcs().add(arc2); + } + } + } + } + } + + + // Créer le nouveau xmi (modèle convertit) + URI convURI = URI.createURI("../fr.n7.petrinet/models/gen/developpement_java.xmi"); + Resource conv = resSet.createResource(convURI); + + // Ajouter le Network dans le nouveau modèle + conv.getContents().add(network); + + // Sauver la ressource + try { + conv.save(Collections.EMPTY_MAP); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/livrables/toTINA.mtl b/livrables/toTINA.mtl new file mode 100644 index 0000000..601544f --- /dev/null +++ b/livrables/toTINA.mtl @@ -0,0 +1,44 @@ +[comment encoding = UTF-8 /] +[module toTINA('http://petrinet')] + +[template public networkToTINA(aNetwork : Network)] +[comment @main/] +[file (aNetwork.name + '.net', false, 'UTF-8')] +net [aNetwork.name/] +[let places : OrderedSet(Place) = aNetwork.getPlaces() ] + [if (places->size() > 0)] + [for (place : Place | places)] +pl [place.name/] ([place.tokens/]) + [/for] + [else] + [/if] +[/let] +[let transitions : OrderedSet(Transition) = aNetwork.getTransitions() ] + [if (transitions->size() > 0)] + [for (transition : Transition | transitions)] +[transition.afficher()/] + [/for] + [else] + [/if] +[/let] +[/file] +[/template] + +[query public getPlaces(n: Network) : OrderedSet(Place) = + n.nodes + ->select( e | e.oclIsTypeOf(Place) ) + ->collect( e | e.oclAsType(Place) ) + ->asOrderedSet() +/] + +[query public getTransitions(n: Network) : OrderedSet(Transition) = + n.nodes + ->select( e | e.oclIsTypeOf(Transition) ) + ->collect( e | e.oclAsType(Transition) ) + ->asOrderedSet() +/] + +[template public afficher(t : Transition) post (trim()) ] +[comment][let outgoing = t.getArcs()->select( e | e.isOutgoing() ) /][/comment] +tr [t.name/] [for (a : Arc | t.arcs)][if (not a.outgoing)][a.place.name/]*[a.weight/] [/if][/for]-> [for (a : Arc | t.arcs)][if (a.outgoing)][a.place.name/]*[a.weight/] [/if][/for] +[/template] \ No newline at end of file diff --git a/rapport/rapport.tex b/rapport/rapport.tex deleted file mode 100644 index bab4d6f..0000000 --- a/rapport/rapport.tex +++ /dev/null @@ -1,399 +0,0 @@ -\documentclass[a4paper, 12pt]{article} -\usepackage[T1]{fontenc} -\usepackage[french]{babel} -\usepackage[utf8]{inputenc} -\usepackage{graphicx} -\usepackage{amsmath} -\usepackage{amsfonts} -\usepackage{amssymb} -\usepackage{color} -\usepackage{xcolor} -\usepackage{natbib} -\usepackage[hidelinks]{hyperref} -\usepackage[nottoc, numbib]{tocbibind} -\usepackage[justification=centering]{caption} -\usepackage{mathtools} -\usepackage{lipsum} -\usepackage{lscape} -\usepackage{caption} -\usepackage{subcaption} -\usepackage{minted} -\usepackage{multicol} -\usepackage{svg} - -\newminted{text}{linenos, numbersep=6pt, frame=leftline} -\newminted{html}{linenos, numbersep=6pt, frame=leftline} - -\usepackage{contour} -\usepackage{ulem} -\renewcommand{\ULdepth}{1.8pt} -\contourlength{0.8pt} -\newcommand{\myuline}[1]{% - \uline{\phantom{#1}}% - \llap{\contour{white}{#1}}% -} - -\newcommand{\dst}{\displaystyle} - -\usepackage[margin=2cm]{geometry} - -\graphicspath{ - {./assets/} -} - -\begin{document} - -\begin{figure}[t] - \centering - $\includesvg[height=1cm]{inp-enseeiht.svg}$ -\end{figure} - -\title{ - \vspace{4cm} - \textbf{Rapport de Mini-Projet} \\ - Génie du Logiciel et des Systèmes \\ - Chaîne de vérification de modèles de processus -} -\author{ - \myuline{Groupe M-02} \\ - Fainsin Laurent \\ - Guillotin Damien \\ -} -\date{ - \vspace{10cm} - Département Sciences du Numérique \\ - Deuxième année \\ - 2021 — 2022 -} - -\maketitle - -\newpage - -\tableofcontents - -\newpage - -\section{Métamodèles (avec Ecore)} - -\subsection{simplePDL.ecore} - -Ce projet se base sur un langage simplifié de modélisation de processus de développement, appelé SimplePDL. -Nous sommes donc parti du modèle Ecore de base du modèle SimplePDL auquel nous avons ajouté progressivement des nouveaux éléments. -Dans un premier temps, il a fallu ajouter la modélisation des guidances comme indiqué dans le sujet. - -\begin{figure}[H] - \centering - \includegraphics[width=15cm]{simplePDL_guidance.png} - \caption{Métamodèle simplePDL avec guidance} - \label{simplePDL_guidance} -\end{figure} - -Nous avons ensuite dû choisir une manière de modéliser les ressources nécessaires au processus de développement. -Notre choix de modélisation s’est porté sur : une Ressource (qui implémente ProcessElement) est demandée par le biai d’une Request elle-même générée par une WorkDefinition. -On se retrouve donc avec un nouveau modèle Ecore de la forme : - -\begin{figure}[H] - \centering - \includegraphics[width=15cm]{simplePDL_guidance_ressource.png} - \caption{Métamodèle simplePDL avec guidance et ressource} - \label{simplePDL_guidance_ressource} -\end{figure} - -\newpage - -Les relations Ressource-Request et Request-WorkDefinition sont déclarées en EOpposite pour pouvoir facilement passer d’un fils à un parent et vice versa. -Le modèle SimplePDL est maintenant complet pour représenter des processus de développement. -Un exemple complet d’utilisation de ce modèle serait : - -\begin{figure}[H] - \centering - \includegraphics[width=15cm]{simplePDL_complet.png} - \caption{Métamodèle simplePDL complet} - \label{simplePDL_complet} -\end{figure} - -\subsection{petriNet.ecore} - -En se basant sur ce que l’on a vu pour le modèle SimplePDL, nous avons créé un modèle Ecore permettant de modéliser les réseaux de pétri. -Nous avons modélisé un réseau comme étant composé de nœuds. -Ces nœuds peuvent être les places ou des transitions. -Ils sont donc nommés et reliés entre eux par des arcs. -Ses arcs ont un attribut entier nommé weight pour indiquer le poids de l’arc ainsi qu’un boolean outgoing pour indiquer si ce dernier est dirigé d’une Place vers une Transition ou d’une Transition vers une Place. -(Si outgoing est vrai, alors l’arc va de la transition vers la place.) - -\begin{figure}[H] - \centering - \includegraphics[width=15cm]{petriNet_complet.png} - \caption{Métamodèle petriNet complet} - \label{petriNet_complet} -\end{figure} - -\newpage - -\section{Sémantique statique (avec OCL)} - -Les contraintes OCL sont là pour vérifier des informations du modèle vis-à-vis du métamodèle. -Elles assurent certains points de cohérence et permettent d'éviter les ambiguïtés. - -\subsection{simplePDL.ocl} - -Pour les modèles SimplePDL, nous contraignons les noms des Process au format camelCase. De même les noms des WorkDefinitions et des Resources doivent posséder au minimum 2 caractères et ne pas être exclusivement constitués de chiffres ou d'underscores. -\begin{textcode} -context Process -inv validName('Invalid name: ' + self.name): - self.name.matches('[A-Za-z_][A-Za-z0-9_]*') - -context WorkDefinition, Resource -inv nameMin2Char: self.name.matches('..+') -inv weirdName: not self.name.matches('([0-9]*|_*)') -\end{textcode} - -Pour ne pas avoir d'ambiguité dans le modèle, les noms des WorkDefinitions et des Ressources doivent être uniques. -\begin{textcode} -context Process -inv uniqNamesWD: self.processElements - ->select(pe | pe.oclIsKindOf(WorkDefinition)) - ->collect(pe | pe.oclAsType(WorkDefinition)) - ->forAll(w1, w2 | w1 = w2 or w1.name <> w2.name) -inv uniqNamesRes: self.processElements - ->select(pe | pe.oclIsKindOf(Resource)) - ->collect(pe | pe.oclAsType(Resource)) - ->forAll(r1, r2 | r1 = r2 or r1.name <> r2.name) -\end{textcode} - -Nous avons aussi contraint l’utilisateur à utiliser les WorkSequence sur des WorkDefinition appartenant au même Process. Pour éviter des non-sens, les WorkSequence ne peuvent pas non plus avoir le même successeur et prédécesseur. -\begin{textcode} -context WorkSequence -inv successorAndPredecessorInSameProcess('Activities not in the same process : ' - + self.predecessor.name + ' in ' + self.predecessor.process().name+ ' and ' - + self.successor.name + ' in ' + self.successor.process().name): - self.process() = self.successor.process() - and self.process() = self.predecessor.process() -inv notReflexive: self.predecessor <> self.successor -\end{textcode} - -Nous avons aussi ajouté des contraintes sur les quantités des Resource et Request. -En effet, cela n’a pas de sens d’avoir des Resources ou des Requests avec des quantités négatives. De plus, une Request ne peut pas être plus grande que le nombre initial de ressources. (Le nombre initial de ressources est le maximum puisqu’il n’y a pas de création.) -\begin{textcode} -context Resource, Request -inv negativeQuantity: self.quantity > 0 - -context Request -inv greedy: self.quantity <= self.target.quantity -\end{textcode} - -\newpage - -\subsection{petriNet.ocl} - -Les modèles PetriNet étant relativement similaires aux modèles SimplePDL, nous avons établi des contraintes OCL similaires. -Nous obligeons le Network et les Node à avoir des noms uniques mais également sensés. -\begin{textcode} -context Network -inv validName('Invalid name: ' + self.name): - self.name.matches('[A-Za-z_][A-Za-z0-9_]*') -inv uniqNamesNode: self.nodes - ->forAll(n1, n2 | n1 = n2 or n1.name <> n2.name) - -context Node -inv nameMin2Char: self.name.matches('..+') -inv weirdName: not self.name.matches('([0-9]*|_*)') -\end{textcode} - -Le nombre de jetons des Place et le poids des Arc doivent évidemment être positifs. -\begin{textcode} -context Place -inv negativeQuantity: self.tokens >= 0 -context Arc -inv negativeQuantity: self.weight >= 0 -\end{textcode} - -\newpage - -\section{Eclipse Modeling Framework (EMF)} - -Pour permettre une meilleur intégration de nos métamodèles dans notre environnement de developpement (sous Eclipse), nous pouvons créer des greffons nous permetttant de les intégrer dans d'autres projets, ainsi que des éditeurs arborescents nous permettant de mieux visualiser/éditer des modèles conformes à nos métamodèles Ecore. -Le code java de ces éditeurs arborescent est engendré par nos métamodèles Ecore, mais nous pouvons le modifier manuellement pour que ceux-ci conviennent parfaitement à nos critères. -Ces plugins seront déployés dans une Eclipse Application séparée de notre environnement de developpement principale pour ne pas mélanger métamodèles et modèles. - -\subsection{plugin simplePDL} - -\begin{figure}[H] - \centering - \includegraphics[width=15cm]{simplePDL_emf.png} - \caption{Éditeur arborecent d'un modèle simplePDL} - \label{simplePDL_EMF} -\end{figure} - -\subsection{plugin petriNet} - -\begin{figure}[H] - \centering - \includegraphics[width=15cm]{petriNet_emf.png} - \caption{Éditeur arborecent d'un modèle petriNet} - \label{petriNet_EMF} -\end{figure} - -\newpage - -\subsection{simplePDL $\rightarrow$ petriNet (avec Java)} - -Maintenant que nous pouvons charger plus facilement nos métamodèles dans notre environnement de travail, il nous est aussi possible d'importer nos modèles dans un programme Java (grâce aux modules générés automatiquements par EMF). Ainsi en 200 lignes de code, nous pouvons convertir directement un modèles simplePDL en un modèle petriNet. - -\section{Transformation de modèle à texte (avec Acceleo)} - -Il nous est possible de transcrire nos modèles vers d'autres formats de fichiers pour nous permettre de les utiliser dans logiciels tierces, et ainsi de les modifier/visualiser plus aisaiment. - -\subsection{simplePDL $\rightarrow$ html (toHTML.mtl)} - -Nous pouvons dans un premier temps de transformer nos modèles simplePDL selon le langage de balisage HTML. - -\begin{htmlcode} -developpement - -

Process "developpement"

-

Work definitions

- - -\end{htmlcode} - -\subsection{simplePDL $\rightarrow$ dot (toDOT.mtl)} - -Nous pouvons de même transformer nos modèles simplePDL selon le langage de description de graphe DOT. - -\begin{textcode} -digraph "developpement" { - "Conception" -> "RedactionDoc" [arrowhead=vee label=finishToFinish] - "Conception" -> "RedactionDoc" [arrowhead=vee label=startToStart] - "Conception" -> "Programmation" [arrowhead=vee label=finishToStart] - "Conception" -> "RedactionTests" [arrowhead=vee label=startToStart] - "Programmation" -> "RedactionTests" [arrowhead=vee label=finishToFinish] -} -\end{textcode} - -\newpage - -\subsection{petriNet $\rightarrow$ tina (toTINA.mtl)} - -Enfin, il nous est possible de transformer nos modèles petriNet selon le language de description de réseau de Petri TINA (format .net). - -\begin{textcode} -net coolNetwork -pl debut (1) -pl fin (0) -tr debut2fin debut*1 -> fin*1 -\end{textcode} - -\section{Définition de syntaxes concrètes graphiques (avec Sirius)} - -Tout comme lors de la création d'éditeurs arborescent spécifiques à nos métamodèles (cf EMF), il nous est possible de créer des éditeurs graphiques pour nos métamodèles. Cela nous donne accès à des outils graphiques permettant ainsi à un utilisateur non accoutumé à des outils complexes de créer et modifier des modèles (de processus ou de réseau de petri). - -\subsection{simplePDL.odesign} - -\begin{figure}[H] - \centering - \includegraphics[width=14cm]{simplePDL_sirius.png} - \caption{Éditeur graphique d'un modèle simplePDL} - \label{simplePDL_sirius} -\end{figure} - -\subsection{petriNet.odesign} - -\begin{figure}[H] - \centering - \includegraphics[width=14cm]{petriNet_sirius.png} - \caption{Éditeur graphique d'un modèle petriNet} - \label{petriNet_sirius} -\end{figure} - -\newpage - -\section{Définition de syntaxes concrètes textuelles (avec Xtext)} - -Dans la continuité de la création d'outils pour manipuler et visualiser nos modèles, il nous est possible de définir une styntaxe textuelle associée à nos métamodèles. - -\subsection{simplePDL.xtext} - -Ainsi pour simplePDL, la syntaxe textuelle suivante permet de manipuler nos modèles facilement, sans passer par des outils graphiques parfois complexes. -\begin{textcode} -process Developpement { - res Crayon 10 - res Papier 20 - wd Conception - req Crayon 10 - req Papier 5 - wd RedactionTest - wd RedactionDoc - wd Programmation - ws f2s from Conception to Programmation - ws s2s from Conception to RedactionTest - ws s2s from Conception to RedactionDoc - ws f2f from Conception to RedactionDoc - ws f2f from Programmation to RedactionTest -} -\end{textcode} - -\newpage - -\section{Transformation de modèle à modèle (avec ATL)} - -Finalement il nous est possible, tout comme lors de la transformation modèle à modèle via l'écriture d'un programme Java, de transformer un modèle selon un autre métamodèles via l'outil ATL. - -\subsection{simplePDL $\rightarrow$ petriNet} - -\begin{figure}[H] - \centering - \includegraphics[width=15cm]{transfo.png} - \caption{Modèle pour la transformation de modèle à modèle} - \label{transfo} -\end{figure} - -Pour transformer une WorkDefinition dasn un réseau de Petri, nous créons 4 places (\_idle, \_running, \_started, \_finished) ainsi que 2 transitions (\_start, \_finish). -Pour transformer une WorkSequence, nous relions la place du predecesseur à la transition du successeur, par exemple dans le cas d'un linkType start2start nous relions un \_started à un \_start. -Pour transformer une Resource, nous créons simplement une place avec le bon nombre de tokens. Pour ce qui est des Requests d'une WorkDefinition nous relions le \_start et le \_finish de la WorkDefinition à la ressource avec les poids correspondants. - -\newpage - -\section{Logique Temporelle Linéaire (LTL)} - -Dans l'optique d'une vérification de la terminaison et de la transformation correcte de notre modèle simplePDL en modèle petriNET, nous pouvons à partir du modèle simplePDL générer des propositions que nous demanderons par la suite à selte/tina de vérifier. \\ - -Pour vérifier la terminaison du processus, nous pouvons écrire: -\begin{textcode} -[] <> (WD1_finished /\ WD2_finished /\ WD3_finished); -\end{textcode} - -Pour vérifier qu'une WorkDefinition ne soit que dans un seul état à la fois, nous pouvons écrire (via l'intermédiaire d'un xor): -\begin{textcode} -[] (((WD1_idle /\ -WD1_running /\ -WD1_finished) - \/ (-WD1_idle /\ WD1_running /\ -WD1_finished) - \/ (-WD1_idle /\ -WD1_running /\ WD1_finished)) - /\ ((WD2_idle /\ -WD2_running /\ -WD2_finished) - \/ (-WD2_idle /\ WD2_running /\ -WD2_finished) - \/ (-WD2_idle /\ -WD2_running /\ WD2_finished)) - /\ ((WD3_idle /\ -WD3_running /\ -WD3_finished) - \/ (-WD3_idle /\ WD3_running /\ -WD3_finished) - \/ (-WD3_idle /\ -WD3_running /\ WD3_finished))); -\end{textcode} - -Pour vérifier qu'une WorkDefinition ne progresse que dans un seul sens, nous pouvons -\begin{textcode} -[] ((WD1_finished => - [](-WD1_running /\ -WD1_idle /\ WD1_started)) - /\ (WD2_finished => [](-WD2_running /\ -WD2_idle /\ WD2_started)) - /\ (WD3_finished => [](-WD3_running /\ -WD3_idle /\ WD3_started))); -\end{textcode} - -\end{document}