The incumbent's key: the ghost code list with the sentinel stamped, and the stored best leaf's rows.
Equations
- Hex.GraphIso.Nauty.incKey ctx bs canonlab = { codes := bs ++ [Hex.GraphIso.Nauty.codeSentinel], rows := Hex.GraphIso.Nauty.leafRows ctx canonlab }
Instances For
A leaf key of the current path.
Equations
- Hex.GraphIso.Nauty.pathLeafKey ctx cs lab = { codes := cs ++ [Hex.GraphIso.Nauty.codeSentinel], rows := Hex.GraphIso.Nauty.leafRows ctx lab }
Instances For
A code-tied leaf strictly above the incumbent's depth compares above it: the leaf's sentinel meets a real incumbent code.
A code-tied leaf at the incumbent's depth hands the comparison to the rows.
The downward-frozen verdict at a leaf, in incumbent-key form.
The upward-frozen verdict at a leaf, in incumbent-key form.
The unwind level of the shared prune tail.
Equations
- One or more equations did not get rendered due to their size.
Instances For
A faithful comparison machine records its agreement or divergence at a genuine path level.
The shared prune tail either returns no lower than the frozen code divergence or jumps to the level immediately above the saved cheap-cell boundary. These are the two logically different early-return modes.
The shared prune tail always returns below its positive saved cheap-cell boundary.
A nonnegative comparison depth and positive saved boundary make the shared prune return a genuine natural-number level.
The frozen-downward fast arm: the comparison state is untouched and the shared prune tail decides the unwind level.
The frozen-downward arm raises a short-prune request exactly when it admits an implicit pair and does not return to the first-path guide.
A fresh short-prune request in the frozen-downward arm proves that the implicit pair was actually admitted below the saved boundary.
The short-leaf install: a code-tied leaf strictly above the incumbent's depth installs itself with no row comparison.
The upward-frozen install: a leaf reached with compCanon = 1
installs itself directly.
The row-decided install: a code-tied leaf at the incumbent's depth whose rows compare above installs itself.
The row-decided rejection: a code-tied leaf at the incumbent's depth whose rows compare below is discarded, freezing the downward comparison.
The fields processnode never writes: the labelling pair, the
first-path data, and the level bookkeeping consumed by the child
loops.
The row-tied arm: a code-tied leaf at the incumbent's depth whose
rows equal the incumbent's is an automorphism candidate (nauty's code
2); the incumbent survives unchanged and the unwind returns to one
of the guiding ancestors.
The full leaf event off the first path: at a discrete node,
processnode leaves the incumbent at the key maximum of the entry
incumbent and the current leaf, re-establishes the store invariant,
and hands back a comparison machine for the unwind. That machine is
intact when the comparison stayed frozen or was re-seeded by an
install, and in the reset form when a row rejection repurposed
compCanon (recover_codeInv_reset consumes it). The return level is
one of the four unwind forms.
One recover step after a node event: the comparison machine
survives the unwind in whichever mode the event left it (live with
compCanon ≤ 0, or the reset mode a row rejection leaves behind), and
the first-path machine is clamped. The induction applies this at every
return to a child loop.
nauty's workperm at a first-path-agreeing leaf: the scatter of
the current leaf's labelling over the first leaf's.
Equations
- Hex.GraphIso.Nauty.firstScatter n firstlab lab = List.foldl (fun (w : Array Nat) (i : Nat) => w.set! firstlab[i]! lab[i]!) (Array.replicate n 0) (List.range n)
Instances For
A first-to-current scatter preserves its fixed n-slot workspace
size.
A full scatter from a permutation labelling overwrites every slot, so its result is independent of the initial workspace contents.
The code-1 arm: a first-path-agreeing leaf passing the
admission test records a generator and unwinds to gcaFirst with
the whole comparison state untouched.
A successful code-one admission does not change the canonical GCA control.
A code-one admission does not create a short-prune request.
The code-one arm stores the same first-to-current scatter that it appends to the generator trace.
The bounded-ledger effect of the shared code-three/code-four tail.
Equations
- Hex.GraphIso.Nauty.pruneAutos level st = if level = st.noncheaplevel then st.autos else (Hex.GraphIso.Nauty.pushAuto st (Hex.GraphIso.Nauty.fmptn st.lab st.ptn st.noncheaplevel n)).autos
Instances For
Whenever the shared tail admits its implicit pair, bounded workspace
capacity makes that pair the exact newest entry read by shortprune.
The frozen-downward fast arm has exactly the shared prune-tail ledger effect.
The short-leaf install has exactly the shared prune-tail ledger effect.
A row-decided install has exactly the shared prune-tail ledger effect.
A row-decided rejection has exactly the shared prune-tail ledger effect.
A row-tied code-two return either uses the canonical ancestor, or its special first-ancestor return is backed by a strictly smaller orbit pointer in the output state.
A fresh short-prune request from the code-two arm accompanies the canonical-guide return; the special first-guide orbit return never raises the flag.
The code-two arm leaves the canonical guide untouched.
The code-two arm stores the same incumbent-to-current scatter that it appends to the generator trace.
A first-path-agreeing leaf failing the admission test behaves, in the return level and the whole comparison state, exactly as the same state entered off the first path. The only effect of the test is the skipped generator.
Failing the first-path admission test has the same autos-ledger effect as entering the ordinary off-path comparison arm.
The leaf event at a first-path-agreeing leaf that fails the
admission test: identical to processnode_leaf, by the reduction
processnode_gateFail_eq.
The code-1 skip is sound at key level: with the codes agreeing
with the first path outright and the rows transported by the
admitted automorphism, the leaf's key is the first leaf's key, and
an incumbent dominating the first leaf absorbs it.
The fields otherNodePrep never writes: everything the store
invariant, the first-path data, and the unwind bookkeeping read.
The fields recover never writes: the store invariant's data,
the first-path arrays, and the unwind targets.
CanongInv passes through otherNodePrep untouched.
The store fields no internal step writes: the generator trace and
the bounded autos workspace pass through otherNodePrep and
recover untouched, so both ledger clauses ride the unwind and the
comparison step by frame.
firstterminal seeds the first-path machine: the just-installed
first leaf agrees with itself at full depth.
firstterminal seeds the store invariant: the installed
canonlab with samerows = 0 is vacuously consistent.
firstterminal installs the first leaf without touching either
store, so both ledger clauses are carried across the seed.
The discrete arm of specNode, isolated: at a node whose
refinement is discrete, the subtree key is the leaf key.
One child key of a spec node: the subtree below individualizing
the o-th target-cell vertex of the refined state.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The internal arm of specNode, isolated: at a non-discrete node
the subtree key under the path prefix is the maximum of the
children's keys under the path extended by the node's own code.
The entry invariant of the maximality induction at a node about
to refine at level = cs.length + 1: the search skeleton, both
comparison machines, the store invariant, cell stabilization of every
recorded generator at this node, and the two ledgers the pruning arms
consume.
genTraceOk is store validity: every recorded generator is a checked
automorphism, which is what childKey_of_carried needs of the
carriers the gca returns hand up. autosOk is the (fix, mcr)
ledger of Invariant/Autos, anchored at the root partition rptn/rlab
where it is unconditional; the shortprune/longprune arms move a
single pair down the path with pairOk_descend at the point of
use.
- codeInv : CodeCmpInv n cs bs st.canoncode st.canonlevel st.eqlevCanon st.compCanon
- firstInv : FirstCodeInv n cs fs st.firstcode st.eqlevFirst
- genTraceOk : GenTraceOk ctx st (ColorMap G)
Instances For
Store validity crosses a frame-preserving step.
A testcanlab tie against the updated store says the leaf's rows
are the incumbent's: this is the harm3 hypothesis of
genTraceOk_processnode, supplied from DomOk.canongInv.
A reached labelling lands in the vertex range.
The frozen divergence survives truncation: with the divergence
recorded at level eqlevCanon + 1, the path prefix down to any level
at or beyond it still compares below the incumbent, whatever comes
after.
The key-level truncated verdict: every subtree hanging below the truncated path is dominated once the machine froze downward at or above the truncation level.
frozen_take_keyCmp_lt in the keyLe form the absorption
consumes.
The whole-path instance: with the machine frozen downward, every subtree below the current path is dominated.
A checked automorphism stabilizing the refined node's cells and carrying one target-cell vertex onto another identifies the two children's subtree keys.