petri_net_nn.subnets¶
subnets ¶
Five elemental Petri net subnets from §5 of the architecture spec.
Continuous relaxation of the token firing rule (spec §4.2):
activation(t) = sigmoid( sum_p w(p,t) * a(p) - theta(t) )
a(p) = sum_{t: (t,p) in F} activation(t) * w(t,p)
Each place's activation a(p) is a scalar in [0,1] (spec §4.1) carried as a tensor of shape (batch,) so that a forward pass can score many process instances at once.
Forward passes return a dict keyed by Petri-net element name (the same names that appear in the diagrams in §5), so a caller can inspect any transition activation or place activation without having to remember a positional convention.
SequentialSubnet ¶
Bases: Module
Subnet 1 — sequential execution.
[P_before] --T_step--> [P_after]
Source code in petri_net_nn/subnets.py
XORSubnet ¶
Bases: Module
Subnet 2 — exclusive choice.
--T_route_A--> [P_path_A]
[P_decision] <
--T_route_B--> [P_path_B]
Both transitions share P_decision as their input place. Soft routing is what the continuous relaxation produces; the structural constraint (only these two declared paths exist) is enforced by construction.
Source code in petri_net_nn/subnets.py
AndSplitSubnet ¶
Bases: Module
Subnet 3 — parallel split (AND-gateway).
--> [P_branch_A]
[P_ready] -- T_spawn
--> [P_branch_B]
A single transition with two output arcs; both branches activate simultaneously when T_spawn fires.
Source code in petri_net_nn/subnets.py
AndJoinSubnet ¶
Bases: Module
Subnet 4 — synchronisation (AND-join).
[P_branch_A] --\
T_merge --> [P_unified]
[P_branch_B] --/
Spec §5 calls this the hardest subnet to relax: a partial firing (one branch complete, the other not) must not propagate. We bias initialisation toward a high threshold and use a sharpness parameter on the sigmoid so the activation function approaches a step.
Source code in petri_net_nn/subnets.py
SagaSubnet ¶
Bases: Module
Subnet 5 — saga compensation.
[P_active] --T_succeed--> [P_complete]
[P_active] --T_fail-----> [P_compensating]
[P_compensating] --T_compensate--> [P_initial]
Two competing transitions out of P_active (success / failure), and a compensation transition closing the loop back to P_initial. The whole subnet is a feed-forward DAG when unrolled for one execution step.