Status: implemented · Audience: maintainers and verifier authors · Primary source: Gotoh 1982
Affine gaps need history: the next gap symbol costs $g_e$ when the same gap
is open and $g_o+g_e$ otherwise. A scalar (index, cost) position cannot
distinguish those cases. The design must preserve byte/character/token
genericity, exact comparison, pooled traversal, and the 24-byte position seam.
The selected design maps Gotoh's three matrices to PositionKind and supplies
typed parameters through AutomatonVariant::Params. It does not add an
Algorithm variant because Algorithm is a parameter-free unit-cost selector.
| Component | Responsibility |
|---|---|
AffineGapParams | exact decimal scaling, getters, budget conversion |
AffineV | fused successors, epsilon closure, B-4/B-5 subsumption, finish, window |
QueryVariant::Affine | carry typed parameters through the existing iterator |
AffineQueryIterator | convert scaled candidate costs for presentation |
affine_gap_distance_units | independent quadratic oracle |
| formal tree | prove arithmetic and bounded-transition invariants |
The ordinary and affine iterators share traversal, path reconstruction, dictionary units, substitution policies, and state pooling. Only the five variant operations differ.
_f64 engineRejected because exact decimal input is already representable through
CostScale. Floating comparison would reintroduce epsilon policy, NaN branches,
and platform-sensitive ordering while duplicating 3,637 lines of weighted
state machinery.
AlgorithmRejected because an enum value cannot carry the parameter set without changing
every serialized, FFI, and product surface. VariantSpec::AffineGap is a seam
marker; typed entry points dispatch directly to AffineV.
Rejected because it abandons canonical position frontiers and state pooling.
The PositionKind byte is sufficient history.
Rejected by a generated counterexample. Cross-index pruning changes which epsilon representatives survive closure. The shipped kernel satisfies the missing precondition by fusing the priced query skip with consumption of the current dictionary edge; B-5 was enabled only after the fused transition, arbitrary-suffix reduction to B-4, and executable differential properties were added together.
ScaleError.checked_add; every run uses checked
multiplication where multiplication occurs.$g_e=0$ is exact but uses the full remaining-query window.The proof stack is intentionally redundant:
The formal manifest is the single registration point. Trusted proof files contain no admitted theorem, axiom, external body, or assumed function.
Any change to gap convention, gap_step, layer order, finish cost, or window
must update all of the following in one change: reference DP, automaton kernel,
Rocq, Dafny, Verus, SMT, TLA+, direct properties, literate chapter, and diagram.
This duplication is deliberate cross-validation, not production-code drift.
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |