Flow diagrams to Petri nets

This document describes how the FD2PN component has been reused for several workflow languages. This component features a reusable transformation from a Workflow concept to a Petri net, which is able to deal with several of the patterns defined in the Workflow patterns catalog.

The menu provides links to the different artefacts of the case study.

Code for Bentō:
Template:
Concepts:
Meta-models:

Apromore

Apromore is an open repository to store process models in a variety of languages.

Meta-model

The following diagram contains the Apromore meta-model, also available in SVG and PNG formats. In Apromore, there are two kinds of Nodes: Work nodes and Routing nodes. The latter correspond to YAWL split/join types, the former are either Tasks or Events.

Binding

The binding naturally maps FlowEdge in the concept to Edge in Apromore, and the collections to bind Node.ins/outs are calculated based on the source/target references of Edges. Task in the concept are mapped to Appromore Tasks. However, we distinguish wether they are initial/final based on its input/output edges. The Routing nodes are mapped similarly to YAWL, and again, OR-join is not supported.

--
-- Binding between apromore (http://apromore.org) and workflow
-- 
binding bpmn2fd {  
	concept   FD   : "platform:/resource/bento.examples.flow_diagrams.petrinets/metamodels/flow_concept.ecore"
	metamodel APRO : "platform:/resource/bento.examples.flow_diagrams.petrinets/bindings/apromore2pn/apromore.ecore"

	class FlowDiagram to Net	
	class Node        to Node
	class FlowEdge    to Edge	
	class Task        to Task when self.outEdges->notEmpty()
	     						           
	feature FlowDiagram.nodes is nodes
	feature FlowDiagram.edges is edges

	feature FlowEdge."in" is source
	feature FlowEdge.out is target

	feature Node.ins = APRO!Edge.allInstances()->select( e | e.target = self )
	feature Node.outs = APRO!Edge.allInstances()->select( e | e.source = self )
	
	feature Task.name is name
	feature Task.isInitial = self.inEdges->isEmpty()
	    
	class FinalTask to Task when self.outEdges->isEmpty()
	
	class ParallelSplit   to ANDSplit
	class MultiChoice     to ORSplit
	class ExclusiveChoice to XORSplit
	
	-- ORJoin not supported...	
	class SimpleMerge     to XORJoin
	class Synchronization to ANDJoin  
	
	feature FinalTask.isTerminating = false

	
	helper Task.inEdges  : OclAny = APRO!Edge.allInstances()->select( e | e.target = self )
	helper Task.outEdges : OclAny = APRO!Edge.allInstances()->select( e | e.source = self )
}