Transitions¶
Transitions fire work over the thread pool; arcs connect them to places.
cpnx.Transition
dataclass
¶
A CPN transition that fires when all its input places are enabled.
In CPN formalism a transition has:
- Input arcs with arc expressions determining which tokens are consumed
- Output arcs with arc expressions determining which tokens are produced
- A guard — a boolean predicate over the binding that must hold for the transition to be enabled (evaluated before the action runs)
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Unique identifier within a |
inputs |
list[InputArc]
|
Input arcs (place to transition). |
outputs |
list[OutputArc]
|
Output arcs (transition to place). |
action |
Callable[[list[Token]], list[Token]]
|
Callable consuming input tokens and returning output tokens. Runs on the thread pool outside the engine lock. |
guard |
Callable[[list[Token]], bool] | str | None
|
CPN transition guard — |
priority |
int
|
Lower value fires first when multiple transitions are enabled. Defaults to 10. |
action_timeout_secs |
float | None
|
Maximum wall-clock seconds the action may run. When This does not kill the underlying OS thread. The timed-out action
continues running in the background until it completes or the process exits;
its return value is silently discarded. Callers must apply native I/O
timeouts inside their actions (e.g. |
max_retries |
int | None
|
Maximum number of times to retry the transition action on failure
before dead-lettering the data tokens.
|
binding_policy |
BindingPolicy | None
|
How the engine resolves which input tokens bind this transition
when checking enablement — see |
binding_priority_key |
Callable[[list[Token]], object] | None
|
Sort key used only under Performance / lock discipline: unlike a callable |
Source code in src/cpnx/transitions.py
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 | |
cpnx.SubstitutionTransition
dataclass
¶
Bases: Transition
A Transition that encapsulates an entire sub-PetriNet (Hierarchical CPN).
Unlike a plain Transition, whose action is an arbitrary callable, a
SubstitutionTransition delegates firing to a nested PetriNet (the
subnet): named port places inside the subnet are bound to named socket places in the
parent net via port_socket_map, and subnet_deadline_secs bounds how long the subnet
is given to reach quiescence. The child subnet is fully insulated from the parent net —
it carries no reference to its parent. Communication occurs strictly through the
port_socket_map.
A subnet instance may only be wrapped by one SubstitutionTransition at a
time; this is tracked process-wide via a weak set. Attempting to wrap the same subnet
twice raises ValueError. Constructing with a non-dict port_socket_map, or with
non-string port/socket names, raises TypeError. Referencing a port place that does not
exist in the subnet raises ValueError.
Attributes:
| Name | Type | Description |
|---|---|---|
subnet |
PetriNet
|
The nested |
port_socket_map |
dict[str, str]
|
Mapping of port place names (in |
subnet_deadline_secs |
float
|
Maximum wall-clock seconds allowed for the subnet to reach
quiescence when this transition fires. Defaults to |
Source code in src/cpnx/transitions.py
cpnx.InputArc
dataclass
¶
Describe how a transition consumes tokens from one input place.
In CPN formalism an input arc carries an arc expression — a function
that, given the current tokens in the place, determines which tokens are
consumed and in what order. expression is that function.
Attributes:
| Name | Type | Description |
|---|---|---|
place |
str
|
Name of the source place. |
count |
int
|
Number of tokens to consume. Ignored when |
consume_all |
bool
|
Drain the entire place atomically. Defaults to |
settle_secs |
float
|
Wait for no new arrivals for this many seconds before
consuming. Defaults to |
expression |
Callable[[list[Token]], list[Token]] | str | None
|
CPN input arc expression. Receives all tokens currently
in the place; returns them in desired consumption order.
Can be a pure Callable or a sandboxed expression string.
The engine consumes the first |
Source code in src/cpnx/transitions.py
cpnx.OutputArc
dataclass
¶
Describe how a transition deposits tokens into one output place.
In CPN formalism an output arc carries an arc expression — a function
evaluated against the transition's output tokens that determines whether
tokens flow along this arc. expression is that predicate.
Attributes:
| Name | Type | Description |
|---|---|---|
place |
str
|
Name of the target place. |
count |
int
|
Number of tokens to deposit. Defaults to 1. |
expression |
Callable[[list[Token]], bool] | str | None
|
CPN output arc expression. Receives the list of non-resource
output tokens returned by the action; the arc is skipped
(no tokens deposited) when it returns |
Source code in src/cpnx/transitions.py
on_color
classmethod
¶
Build an OutputArc that only fires for a matching first token color.
The returned arc's expression is a sandboxed expression string that checks whether
the action's output tokens are non-empty and the first token's color equals color.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
color
|
str
|
The |
required |
place
|
str
|
Name of the target place. |
required |
count
|
int
|
Number of tokens to deposit when the arc fires. Defaults to 1. |
1
|
Returns:
| Type | Description |
|---|---|
OutputArc
|
A new |
OutputArc
|
when the first token in the action's output has color |
Source code in src/cpnx/transitions.py
BindingPolicy selects how a transition resolves which input tokens bind it — the legacy leading-token check, or a deterministic-complete binding search.
cpnx.BindingPolicy
¶
Bases: Enum
Strategy for choosing which input tokens bind a transition when it is enabled.
In CPN theory a transition is enabled if any assignment of place tokens (a
binding) satisfies its guard. cpnx historically tested only the head of each
input place (FIFO, or reordered by InputArc.expression), which
causes head-of-line blocking: a place holding [A, B] whose guard wants B
reports the transition disabled, because only A is ever tested. BindingPolicy
selects how the engine resolves that binding. See the design record in
docs/adr/0001-combinatorial-binding-search.md.
Attributes:
| Name | Type | Description |
|---|---|---|
LEGACY |
Test only the first |
|
FIRST |
Search input-token combinations in a stable insertion order and select
the first combination whose guard is satisfied. Complete (finds a valid
binding if one exists anywhere in the place, fixing head-of-line blocking)
and deterministic (the same marking always yields the same binding). When
the transition has no guard, this is identical to |
|
RANDOM |
Enumerate the satisfying combinations and select one uniformly at
random. Reproducible when the owning |
|
PRIORITY |
Enumerate the satisfying combinations and select the one minimizing
|
Note
The search enumerates the Cartesian product of each input arc's count-sized token
combinations, varying the last arc in Transition.inputs fastest. Consequences
for tuning:
- Resource arcs inflate the space. A
ResourcePlace/PacedResourcePlacepermit arc contributesC(capacity, count)interchangeable options that usually give the guard the same answer, so they can consumebinding_search_limiton redundant permutations. List resource arcs before data arcs inTransition.inputsso the data dimension (the one that actually changes the guard result) varies first, and/or raisebinding_search_limit. - For
FIRSTthe first binding yielded is exactlyLEGACY's head selection, soFIRSTis a strict superset ofLEGACY. RANDOM/PRIORITYmust scan the whole (bounded) candidate set, so they do not short-circuit and are typically costlier thanFIRST. If the candidate space exceedsbinding_search_limit, they select over the firstlimitcandidates only (a truncated prefix), firingon_binding_search_exhausted. If that prefix contains no satisfying binding, the transition is treated as disabled for that check — it can stall exactly likeFIRST, not just fire over a smaller set.