Skip to content

petri_net_nn.bpmn

bpmn

BPMN 2.0 -> Petri net extractor.

Implements the structural translation in ยง3 of the architecture spec (Aalst-style workflow-net mapping):

BPMN sequenceFlow      -> place
BPMN task              -> single transition
BPMN startEvent        -> initial token on the outgoing flow's place
BPMN endEvent          -> sink place (incoming flow's place)
parallelGateway        -> single transition (AND-split / AND-join)
exclusiveGateway       -> one transition per branch sharing a place
                          (XOR-split: shared input;
                           XOR-join : shared output)
compensation boundary  -> see compensation translation below.
compensate end event   -> see compensation translation below.
error / timer /        -> alternative transition out of the
signal / escalation /     attached task's input place, into the
message boundary          boundary's outgoing sequenceFlow's place.
intermediateThrowEvent -> pass-through transition (one input,
/ intermediateCatchEvent  one output, no event semantics).
laneSet / lane         -> silently ignored (informational only).
messageFlow            -> shared message place between the source
(collaboration only)      task transition in one pool and the target
                          task transition in another, threading
                          token flow across pool boundaries.

Compensation has two interpretations depending on whether the process contains a compensate end event: * without one โ€” the boundary becomes an alternative T_fail transition out of the attached task's input place; * with one โ€” the boundary is a passive marker, the task transition is extended with an output to a completion-marker place, and the throw event becomes a transition AND-joining its own input flow with that completion marker.

Cross-pool composition: a <collaboration> root with <participant processRef="..."> children is supported. Each pool's process is parsed independently into the same Petri net with the participant's ID as a prefix on every place / transition ID, so the pools' internal nodes don't collide. <messageFlow> elements then introduce shared message places that connect the sending pool's task transition to the receiving pool's task transition.

Out of scope for this scaffold: subprocesses (raise with a roadmap pointer), non-interrupting boundary events, intermediate events with event definitions, message flows to/from non-task nodes (events, gateways).

The parser accepts a BPMN XML string, a path to a .bpmn or .xml file, or any file-like object yielding XML text.

parse_bpmn

parse_bpmn(source)

Parse a BPMN 2.0 XML source into a Petri net.

Dispatches on the root structure: a <collaboration> produces a composed multi-pool net (one per participant), while a plain <process> document produces a single-pool net (current behaviour). A ValueError is raised for unsupported BPMN constructs.

Source code in petri_net_nn/bpmn.py
def parse_bpmn(source: str | Path | IO[str] | IO[bytes]) -> PetriNet:
    """Parse a BPMN 2.0 XML source into a Petri net.

    Dispatches on the root structure: a ``<collaboration>`` produces a
    composed multi-pool net (one per participant), while a plain
    ``<process>`` document produces a single-pool net (current
    behaviour). A ``ValueError`` is raised for unsupported BPMN
    constructs.
    """
    root = _load_xml(source)

    collab = root.find(f"{NS}collaboration")
    if collab is not None:
        return _parse_collaboration(root, collab)

    process = root.find(f"{NS}process")
    if process is None:
        raise ValueError("no <process> element found in BPMN document")

    net = PetriNet()
    _parse_process(process, prefix="", net=net)
    return net