Model summary
OrderFlowRestockFlowProcess flow
Source file
03-process-flow.prl
This example models an order-fulfillment flow with two canvas
diagrams on the same model: a main order flow and a recurring restock
flow. It introduces branching (exclusive_gateway), timed waits
(timer_event), and the multi-page canvas pattern that real-world
models rely on.
Primitives introduced
| Primitive | Purpose |
|---|---|
Multiple start_events |
One entry point per canvas diagram. |
Multiple end_events |
Different terminal states (e.g. shipped vs cancelled). |
timer_event (WAIT) |
Wait for a fixed period (e.g. “72 hours after order placed”). |
timer_event (REPEAT) |
Fire on a recurring schedule (e.g. “first of every month”). |
exclusive_gateway |
Branch the flow based on a condition. |
"default" edge |
The fallback edge when no other gateway condition matches. |
| Multi-page canvas | One model, multiple canvas diagrams, each with its own start. |
Multiple starts and ends
start_event OrderStart { }
start_event RestockStart { }
end_event OrderShipped { }
end_event OrderCancelled { }
A model with N canvas diagrams typically has N start_events.
Each diagram has exactly one entry point. There can be more
end_events than start_events — a single flow can terminate in
multiple outcomes (here: shipped vs cancelled).
Timer events
timer_event PaymentWindow {
type WAIT
para "72 hours after order placed"
}
timer_event RestockTimer {
type REPEAT
para "First of every month"
}
type |
Meaning |
|---|---|
WAIT |
Pause the flow until the specified time elapses. |
REPEAT |
Fire on a recurring schedule, regardless of flow position. |
A REPEAT timer is the engine of recurring processes — see
the timer loop pattern below.
Exclusive gateways
exclusive_gateway StockCheck {
label "Is the item in stock?"
}
exclusive_gateway PaymentConfirmed {
label "Was payment received within the window?"
}
An exclusive_gateway is a decision point. Its outgoing edges are
label-led with mutually exclusive descriptions; exactly one is taken.
Processes with canvas references
process FulfillOrder {
name "Fulfill a customer order"
actor Warehouse
canvas OrderFlow
}
process ScheduleRestock {
name "Schedule restock for next cycle"
actor CustomerService
canvas RestockFlow
}
The canvas OrderFlow clause binds the process to a named diagram.
This is how a model declares which canvas a process “lives on” when
there are multiple diagrams.
The two canvas diagrams
OrderFlow: branching with default fallback
canvas OrderFlow {
elements {
OrderStart { x 0 y 0 }
StockCheck { x 0 y 100 }
PaymentWindow { x -150 y 220 }
PaymentConfirmed { x -150 y 330 }
PickAndPack { x -150 y 440 }
OrderShipped { x -150 y 550 }
CancelOrder { x 150 y 220 }
RefundCustomer { x 150 y 330 }
OrderCancelled { x 150 y 440 }
}
process_flow {
Edge1 { from OrderStart to StockCheck }
Edge2 { from StockCheck to PaymentWindow description "Item is in stock" }
Edge3 { from StockCheck to CancelOrder description "default" }
Edge4 { from PaymentWindow to PaymentConfirmed }
Edge5 { from PaymentConfirmed to PickAndPack description "Payment received" }
Edge6 { from PaymentConfirmed to RefundCustomer description "default" }
Edge7 { from PickAndPack to OrderShipped }
Edge8 { from CancelOrder to OrderCancelled }
Edge9 { from RefundCustomer to OrderCancelled }
}
data { }
}
Two gateways, each with a labelled branch and a "default" branch:
StockCheck— in stock goes left to payment; out of stock goes right to cancellation.PaymentConfirmed— paid goes left to fulfilment; unpaid goes right to refund.
The "default" description marks the edge taken when no other condition
matches. (This model uses human-readable descriptions only; the
compliance example shows
gateway edges with machine-readable condition expressions.)
RestockFlow: the timer loop
canvas RestockFlow {
elements {
RestockStart { x 0 y 0 }
OrderNewInventory { x 0 y 100 }
RestockTimer { x 0 y 200 }
}
process_flow {
Edge1 { from RestockStart to OrderNewInventory }
Edge2 { from OrderNewInventory to RestockTimer }
Edge3 { from RestockTimer to OrderNewInventory }
}
data { }
}
This is the timer loop pattern:
RestockStart → OrderNewInventory → RestockTimer ─┐
↑ │
└────────────────────────────┘
The flow enters, places a restock order, waits for the timer to fire on its recurring schedule, then loops back to place another order. This models “place an order every month, forever.”
Pattern: timer loops
The recurring-process pattern is so common it has its own shape:
Edge1 { from Start to SomeProcess }
Edge2 { from SomeProcess to Timer }
Edge3 { from Timer to SomeProcess } // ← the loop
The same shape appears in the implementation package
for ReviewSuppliers → SupplierReviewTimer → ReviewSuppliers.
Pattern: default edges
A gateway lists its outgoing edges in priority order. The edge with
description "default" is taken only when no other edge’s condition
(or description, in human-readable models) matches. Every
exclusive_gateway should have exactly one "default" edge as a
fallback.
What this example leaves out
- Compliance — no
provisionormodality. Added in compliance and measurement. - Data — the
data { }blocks are empty. Data appears in data and registries. - Machine-readable conditions — edges use only
description. Conditions are added in compliance and measurement.
Model elements
▾Roles3
WarehouseFinanceCustomerServiceCustomer service
▾Processes6
FulfillOrderFulfill a customer orderactor: WarehousePickAndPackPick and pack the orderactor: WarehouseCancelOrderCancel the orderactor: WarehouseRefundCustomerRefund the customeractor: FinanceScheduleRestockSchedule restock for next cycleactor: CustomerServiceOrderNewInventoryPlace a purchase order with the supplieractor: CustomerService
▾Events6
OrderStartstartRestockStartstartOrderShippedendOrderCancelledendPaymentWindowtimerRestockTimertimer
▾Gateways2
StockCheckIs the item in stock?PaymentConfirmedWas payment received within the window?