locus · logic lane · 2026-10-09

The same fork, later

A logic of place and link that follows individual nodes through the reactions of a bigraphical reactive system, with every verdict checked by Lean's kernel.

In brief

  1. Question. Bigraphs model place (what is inside what) and link (which ports are connected), and rules change both. A logic of reaction steps alone ignores both. We want to state properties such as "any fork philosopher 0 holds can later be on the table again, the same fork".
  2. Built. Rules that say which redex items survive; reactions that carry a tracking map; a logic with place and link atoms whose variables are carried along each step; and a certified checker.
  3. Proved. Tracking is well defined and one-to-one; the logic is invariant under renumbering; the checker is sound for every formula, and false verdicts are certified by duality. Six properties of the dining philosophers about individual forks, and twelve of the alternating bit protocol about individual messages, are theorems.
  4. Borrowed, not claimed. The logic is a port of a published, mechanised design for graph transformation. No claim is made about which equivalence of bigraphs it characterises.

PROVED here means checked by Lean's kernel using only the axioms propext and Quot.sound: no classical choice, no native_decide, no sorry.

1. Bigraphs in one paragraph

A bigraph has nodes, each with a control (its kind: phil₀, fork, table) and a number of ports. The place graph is a forest: every node lies inside another node or directly in a region. The link graph puts each port on a link: a private edge or an outer name. A reaction rule R → R′ replaces an occurrence of the pattern R (the redex) by R′ (the reactum); holes in R (sites) match arbitrary content, the parameter, which the rule moves. In locus every rule is linear: each piece of parameter is used at most once. Nodes and edges are numbered, and agents that differ only by renumbering are support equivalent, a ≏ b.

2. What the literature offers

Condensed from a survey of about ninety verified references (docs/research/spatial-behavioural-logics.md).

Spatial logics describe shape at one moment

BiLog for bigraphs, the ambient logic and the spatial logic of the π-calculus can say "this agent is two parallel parts, one satisfying A, the other B". They describe the shape of a state precisely. Their dynamics is at most a next-step modality, and none follows an individual node through time.

They are also, provably, not logics of behaviour. A logic that can say "exactly two parallel parts" can count and inspect components, so two agents that behave alike but are built differently satisfy different formulas: the logic's notion of "the same" is same structure (Sangiorgi 2001; Hirschkoff, Lozes and Sangiorgi 2008). For bigraphs that is ≏, not bisimilarity. This is why we do not ask the new logic to characterise an equivalence.

Located modal logic observes where actions happen

For CCS with localities (Boudol, Castellani, Hennessy and Kiehn 1993), modalities record the location of an action, and logical equivalence is location equivalence. Locations there are labels on actions, not a space that evolves.

Graph-transformation logics follow entities

Temporal logics for graph rewriting with variables for nodes and edges, carried along each step by a counterpart map (Gadducci, Laretto and Trotta 2023/2026, mechanised in Agda; earlier Distefano, Rensink and Katoen 2002). When the counterpart maps are partial functions, the usual laws of fixpoint logic hold. This is the template we port.

For bigraphs: nothing that tracks

No published bigraph logic quantifies over the same node or link across reactions. Tracking maps exist only inside tools.

3. The model: tracked rules and tracked reactions

A tracked rule is a rule with a tracking list τ of pairs (u, w): redex item u becomes reactum item w. It must be well formed: no item twice on either side, nodes to nodes, edges to edges.

The rule pickLeft for philosopher 0, with the philosopher and the fork tracked from redex to reactum redex phil₀ thinking fork l reactum phil₀ hungry fork l τ: the same philosopher, the same fork
The rule pickLeft₀. Green outlines are tracked: philosopher and fork survive the reaction as themselves (dashed green). The state node thinking (dashed red) is deleted and hungry is created. Violet is the link l that the fork shares with the philosopher's port.

For a reaction a → a′ through a decomposition a = D ∘ (R with parameter d), the tracking map f sends each node or edge of a to its counterpart in a′, or nowhere:

an item of a in …goes to …
the context Ditself (renumbered as a′ is)
the redex Rits τ-partner in R′, if τ names one; otherwise it is deleted
the parameter dits copy in the reactum's site; deleted if that piece is discarded

We write a →tf a′ for a reaction with tag t and tracking map f. Outer names are fixed by the interface and are not tracked.

structure TrRule (α Ctrl : Type) where
  rule : RuleD Ctrl          -- the simulator's rule, unchanged
  tag  : Option α            -- action tag (none = internal)
  τ    : List (Nat × Nat)    -- redex item u becomes reactum item w

Proved (trackDefined). Every library reaction has a tracking map, and with well-formed τ every tracking map is one-to-one and sends nodes to nodes and edges to edges. Linearity is what makes this true: a copied parameter would have two counterparts.

4. The logic

Variables x, y range over nodes, ℓ over links, X over sets of states.

atoms p ::= ctrl(x) = K | prnt(x, y) | root(x) = r | anc(x, y) | port(x, i) = ℓ | ℓ = name y | x = y formulas φ ::= p | ¬p | φ ∧ φ | φ ∨ φ | ∃x. φ | ∀x. φ | ∃ℓ. φ | ∀ℓ. φ | ⟨t⟩φ | [t]φ | ⟨→⟩φ | [→]φ | X | μX. φ | νX. φ
atomreadsgraph
ctrl(x) = Knode x has control K—
prnt(x, y)x lies directly inside yplace
root(x) = rx lies directly in region rplace
anc(x, y)x lies somewhere inside yplace
port(x, i) = ℓport i of x is on link ℓlink
ℓ = name ylink ℓ is the outer name ylink
x = ythe same node or link—

Meaning. A formula holds at a state with a valuation of its variables.

| ρ, a, σ, .dia t φ => ∃ a' f, TrReact S trs t a a' f ∧ PSat trs ρ a' (σ.tr f) φ
| ρ, a, σ, .box t φ => ∀ a' f, TrReact S trs t a a' f → PSat trs ρ a' (σ.tr f) φ
-- σ.tr f : move every variable along the tracking map f

Proved (psatInv). Renumbering a state, with its variables, changes no truth value. The logic is about bigraphs up to ≏.

5. Checking, and why the verdicts are theorems

Asking the kernel to search a state space does not finish, so locus checks models by certificate:

  1. An untrusted, compiled program explores the reachable states and writes a certificate as literal data: the states, and for each matcher step its target, a renumbering witness, and its tracking list.
  2. A Boolean checker, run by the kernel, confirms each step with one run of the matcher and recomputes each tracking list from the matcher's output. Nothing is searched.
  3. An evaluator computes the formula's truth value on the certificate's finite graph.

Proved (trackSoundAll). If the checker accepts and the evaluator says φ is true at a listed state, φ is true there in the library's semantics, for every formula. The rules must satisfy three conditions, each checked by decide:

The core is tracked matcher completeness (trCOcc): every tracked library reaction is found by the matcher, with the same tracking map, up to renumbering. Without it a certificate could leave out a step and make a "for every step" formula look true.

False verdicts, by duality (psat_dual, trackFalse). Swapping ∧/∨, ∃/∀, ⟨⟩/[], μ/ν and p/¬p gives the dual of a formula; we prove, constructively, that a true dual makes the formula false. "φ is false" is certified by checking its dual true.

The simulator's matcher and the existing proofs about it are unchanged. The tracked proof reuses them by import and does not replace them: it has extra side conditions, so it does not subsume cocc_G1.

6. The dining philosophers, fork by fork

Three philosophers, three forks, the fair protocol: pick up the left fork, then the right, eat, put both down; a hungry philosopher whose right fork is taken puts its left fork back. Philosophers and forks are tracked; their states are not. Writing onTable(x) := ∃y. ctrl(y)=table ∧ prnt(x,y) and heldByj(x) := ∃q. ctrl(q)=philj ∧ prnt(x,q):

propertyformulaverdict
returns: always, any fork phil₀ holds can later be on the table again, the same forkAG ∀p∀x. (phil₀(p) ∧ fork(x) ∧ prnt(x,p)) → μX. onTable(x) ∨ ⟨→⟩XTRUE
returnsSome: some fork phil₀ holds can later be on the table againEF ∃x. heldBy₀(x) ∧ μX. onTable(x) ∨ ⟨→⟩XTRUE
handOver: some fork phil₀ holds is later held by phil₂EF ∃x. heldBy₀(x) ∧ μX. heldBy₂(x) ∨ ⟨→⟩XTRUE
bypass: … and gets there without passing the tableEF ∃x. heldBy₀(x) ∧ μX. heldBy₂(x) ∨ (¬onTable(x) ∧ ⟨→⟩X)FALSE
pickSame: the fork phil₁ picks up from the table is that same fork∀x. (fork(x) ∧ onTable(x)) → [pickLeft₁](onTable(x) ∨ heldBy₁(x))TRUE
forksPersist: no step deletes a forkAG ∀x. fork(x) → [→] x = xTRUE

All six are theorems about the library meaning at the initial state, proved from one 14-state certificate in about 64 seconds of kernel time. With the same rules but no tracking, "returns", "pickSame" and "forksPersist" come out false: after one step the variable has no counterpart, so "the same fork later" cannot be said at all. The gate has been watched failing: corrupting one entry of one tracking list makes the certificate check fail.

7. The alternating bit protocol, message by message

The ABP sends messages over two lossy one-place channels and retransmits until acknowledged. Retransmission shapes the model: a copy of a message is a new node, since linear rules cannot duplicate one. So a message's identity is a link.

held(ℓ): the sender holds a message on link ℓ; out(ℓ): the user holds one. The model has 224 states and 39 linear rules.

Certified without the kernel exploring anything

Compiled code explores the states and computes every verdict; the kernel only checks certificates, with four checkers each proved sound:

certificateproves
the closed set of reachable states, property checked state by stateAG ψ
a path to a counterexample state¬ AG ψ
witness paths: a run per obligation, carrying ℓ through the tracking to a goalμX. φ ∨ ⟨t⟩X
an invariant table of (state, value of ℓ) pairs, closed under tracked stepsνY. φ ∧ [t]Y
propertyformulaverdict
sameMessage: the delivered message is the one the sender held when it was deliveredAG ∀ℓ. [deliver](out(ℓ) → held(ℓ))TRUE
heldNow (control): … the one the sender holds nowAG ∀ℓ. out(ℓ) → held(ℓ)FALSE
canDeliver: every accepted message can still be deliveredAG [accept] ∀ℓ. held(ℓ) → μX. ⟨deliver⟩out(ℓ) ∨ ⟨τ⟩XTRUE
noDuplicate: no message is delivered twiceAG ∀ℓ. [deliver](out(ℓ) → νY. [deliver]¬out(ℓ) ∧ [→]Y)TRUE
noStray: every copy in the channel is of the current message or staleinvariantTRUE
copyGone (control): no copy remains after deliveryinvariantFALSE

Twelve verdicts in all, eight TRUE and four FALSE (the others: heldStable, dupEntry, dupStep and canDeliverC TRUE; noStrayStrict and canDeliverHeldC FALSE), checked in about six minutes over separately built modules of under 4 GB each, every checker watched rejecting a corrupted certificate. With tracking ignored the model is weakly bisimilar over rule tags to the one-place buffer (accept and deliver visible; messages carry no data): proved, abpTrack_wbisim_buff, built on demand.

A finding: with nothing of any redex tracked, only heldStable changes verdict. Message links mostly survive a step in the context, which is tracked automatically; only the rules that delete a copy need their own tracking.

8. Exactly what is proved

statementLean
tracking is defined for every reaction; one-to-one, sort-preservingtrackDefined
invariance under renumberingpsatInv
a matcher step is a tracked library reaction with the computed maptrReact_occ
soundness for existential formulas, no side conditionstrackSound
tracked matcher completeness (G1, no idle redex edge, well-formed τ)trCOcc
soundness for every formula (same conditions)trackSoundAll
duality; certified false verdictspsat_dual, trackFalse
the six dining verdictsreturns_holds … bypass_false
four certificate checkers (closed set, path, witness paths, invariant table)agCheck_sound, agFalse, muWalk_sound, nuCheck_sound
twelve ABP verdictssameMessage_holds … copyGone_false

About 4,200 lines of Lean in Logic/Track*.lean; the dining certificate is Logic/Examples/M1Prime/DiningTrackCert.lean. Open: completeness of the checker itself (not needed, since false verdicts go through duality).

9. What is known and what is not

piecestatus
counterpart maps; variables carried along steps; laws for partial mapsKNOWN: Gadducci–Laretto–Trotta (Agda)
dead-variable readingKNOWN: Distefano–Rensink–Katoen 2002
tracked rulesKNOWN: Milner's tracking map is on supports, that is nodes and edges; ours runs forwards and must be injective
linear rules give one-to-one trackingFOLKLORE
a place-and-link logic over tracked bigraph reactionsAPPARENTLY NEW
its certified checking against a mechanised bigraph semanticsAPPARENTLY NEW
spatial logics characterise structure, not behaviourKNOWN: Sangiorgi; Hirschkoff–Lozes–Sangiorgi

APPARENTLY NEW means searched for and not found. It is not a claim of originality; that decision is Matthew's.

10. Limits

Source of record: docs/logic-tracked.md in the locus repository, with statuses in docs/logic-statements.md. Reproduce with lake build Logic and lake env lean Logic/Examples/M1Prime/DiningTrackCert.lean.