Imports
/- Copyright (c) 2026 Terence Rokop. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Terence Rokop -/ module public import Geb.Mathlib.Computability.Cobham.Cases public import Geb.Mathlib.Computability.Cobham.Tree public import Geb.Mathlib.Data.Tree.Ranked.Binary

The generic ranked recognizer

The validity scan of Geb/Mathlib/Data/Tree/Ranked/Preorder.lean, at an arbitrary ranked alphabet, composed with a verdict test into a recognizer, as an expression of Cobham's class.

Main definitions

    Cobham.bufBits — the incomplete block in a slot of the alphabet's width.

    Cobham.stateWord — the scan state as a bitstring.

    Cobham.dispatchWidth — the number of state bits a step dispatches on.

    Cobham.decodeState — the inverse of the state layout.

    Cobham.dropCount, Cobham.nextPrefix — the bits a step drops and prepends.

    Cobham.rankedStep, Cobham.rankedSem — the recognizer's step and the meaning of its scan.

    Cobham.ranked, Cobham.rankedOf — the scan as an expression of C, and at its declared arity.

    Cobham.acceptWord, Cobham.acceptTest — the accepting state's word and the test deciding it.

    Cobham.isRankedRaw, Cobham.isRanked, Cobham.isRankedOf, Cobham.isRankedSem — the recognizer's raw tree, the expression of C over it, that expression at its declared arity, and its meaning.

Main statements

    Cobham.length_bufBits_of_lt, Cobham.length_stateWord_of_lt — the slot's and the state word's lengths.

    Cobham.dropWhile_bufBits — the slot past its padding.

    Cobham.ofFn_bits_stateWord — the state word truncated to a window and zero-padded.

    Cobham.decodeState_stateWord_of_lt — the decoder inverts the layout up to capping the pending count at the depth window.

    Cobham.dropCount_min_depth, Cobham.nextPrefix_min_depth — capping the pending count at the depth window changes neither.

    Cobham.stateWord_scanStep_of_lt — a step rewrites a bounded prefix and drops a bounded number of bits.

    Cobham.stepWord_rankedStep_of_lt, Cobham.rankedSem_eq — the expression computes the scan, one step and then on every input.

    Cobham.length_rankedSem_le — the recursion bound the scanner asks for.

    Cobham.rankedSem_eq_eval — the meaning read at the raw tree is the meaning the expression carries.

    Cobham.ofFn_bits_stateWord_eq_iff — the verdict window separates the accepting state from every other reachable one.

    Cobham.stepWord_acceptTest — the test's value at the state it reads.

    Cobham.wValid_isRankedRaw — the raw tree's admissibility, from its two components'.

    Cobham.isRankedSem_apply, Cobham.isRankedSem_eq_ite — the composition's value, and the value on both branches.

    Cobham.isRankedSem_eq_singleton_iff_valid — the recognizer accepts exactly the words spelling a term.

    Cobham.isRankedSem_eq_eval — the meaning read at the raw tree is the meaning the expression carries.

    Cobham.isRankedSem_binRanked_eq_singleton_iff_isTreeSem — at the two-symbol alphabet it accepts the language Cobham.isTree accepts.

Implementation notes

RankedAlphabet.Scan carries an incomplete block, a count of pending subterms, and a liveness flag. The count is unbounded and the other two are not, and an expression of the class reaches only a bounded prefix of a word, so the count is the tail and the layout admits no alternative.

The block cannot be delimited by its own length, since the fields after it would then stand at a position not statically known. It occupies a slot of exactly R.width bits, delimited by a true sentinel preceded by false padding: reading from offset one, past the flag, the first true is the sentinel and the block is what follows it, the padding being all false. The slot's length is invariant under accumulation — the padding shrinks as the block grows — which is why the fields after it never move. This costs R.width bits rather than the 2 * R.width a separate fill counter would.

length_bufBits_of_lt's hypothesis is consumed rather than decorative. Nat subtraction being truncated, a block of length R.width or more yields a slot of length one past the block, and stateWord is then not injective: at R.width = 2 the states ⟨[false, true], 0, true⟩ and ⟨[false], 1, true⟩ share the word [true, true, false, true]. The invariant excluding this is RankedAlphabet.length_buf_scanFinal_lt.

The pending count is unary. Binary would need a truncated subtraction definable in the class, and Cobham/Tree.lean's recognizer represents its own depth in unary already.

ofFn_bits_stateWord is stated at an arbitrary window, the dispatch and the verdict reading different ones.

The branch family's domain is Fin (dispatchWidth R) → Bool at a symbolic width, so recovering the fields index by index would carry a bound proof at every step. decodeState avoids that by passing through List.ofFn and reading the fields with the List API. This also keeps the module clear of DecidableEq (Fin n → Bool), which resolves through Fintype.decidablePiFintype, measured as depending on Classical.choice, while DecidableEq (List Bool) measures clean.

The run of false past the slot is cleared by a two-case reduction rather than by List.takeWhile_replicate, which was measured to depend on Classical.choice through List.filter_replicate. A proof shortened back onto that lemma fails lake lint.

The dispatch reads the flag and the slot together with the low R.maxArity + 1 bits of the pending count, which give min depth (R.maxArity + 1). Those bits decide r ≤ depth for every symbol: if the count is at least R.maxArity + 1 then every arity is below it, and otherwise those bits are the count itself. RankedAlphabet.le_maxArity_of_arOf_eq_some is what makes the window sufficient, and it is what dropCount_min_depth and nextPrefix_min_depth consume.

Neither SmashFree (ranked R) nor SmashFree (isRanked R) is stated here. smashFreeBool is a WType.elim over the whole tree, so at a symbolic alphabet it is not decide-dischargeable and needs a recursion mirroring wValid_casesRaw, and at a concrete alphabet it forces every node. Nothing in this module uses smash, so the statement is expected to hold and is left to the branch that needs it. Cobham/Tree.lean keeps comb and isTree, so isTree_smashFree and the [Strahm2003] Theorem 1(2) reasoning keep their subject.

No equivalence here is discharged by omega, which pulls Classical.choice on an Iff goal; each is built from its two implications or from Iff.trans.

isRankedSem_eq_ite pins the value on the rejecting branch as well as the accepting one. isRankedSem_eq_singleton_iff_valid alone would admit a recognizer returning [false] on a rejected word, so correctness as a function is not implied by correctness of the accepted set.

The containment this module realizes is an instance of Cobham's characterisation of the polynomial-time functions; what it delivers is an explicit expression computing the decision, not a new theorem.

References

    [Cobham1965]

    [Strahm2003]

Tags

Cobham, bounded recursion on notation, ranked alphabet, preorder, scan, recognizer

namespace Cobhamopen RankedAlphabetpublic section

The incomplete block in a slot of the alphabet's width: false padding, a true sentinel, then the block.

@[`@[expose]` has no effect outside a `module` fileexpose] def bufBits (R : RankedAlphabet) (buf : List Bool) : List Bool := List.replicate (R.width - 1 - buf.length) false ++ true :: buf

The scan state as a bitstring: the liveness flag, the block slot, then the pending count in unary.

@[`@[expose]` has no effect outside a `module` fileexpose] def stateWord (R : RankedAlphabet) (s : Scan) : List Bool := s.live :: bufBits R s.buf ++ List.replicate s.depth true

The number of state bits a step dispatches on: the flag, the slot, and enough of the pending count to decide r ≤ depth for every arity r.

@[`@[expose]` has no effect outside a `module` fileexpose] def dispatchWidth (R : RankedAlphabet) : := R.width + R.maxArity + 2

The slot holds the alphabet's width, the padding shrinking as the block grows. Nat subtraction being truncated, the hypothesis is consumed.

theorem length_bufBits_of_lt (R : RankedAlphabet) (buf : List Bool) (h : buf.length < R.width) : (bufBits R buf).length = R.width := R:RankedAlphabetbuf:List Boolh:buf.length < R.width(bufBits R buf).length = R.width R:RankedAlphabetbuf:List Boolh:buf.length < R.widthR.width - 1 - buf.length + (buf.length + 1) = R.width All goals completed! 🐙

The state word's length: the flag, the slot, and the pending count.

theorem length_stateWord_of_lt (R : RankedAlphabet) (s : Scan) (h : s.buf.length < R.width) : (stateWord R s).length = 1 + R.width + s.depth := R:RankedAlphabets:Scanh:s.buf.length < R.width(stateWord R s).length = 1 + R.width + s.depth R:RankedAlphabets:Scanh:s.buf.length < R.widthR.width + s.depth + 1 = 1 + R.width + s.depth All goals completed! 🐙

The slot past its padding is the sentinel followed by the block.

theorem dropWhile_bufBits (R : RankedAlphabet) (buf : List Bool) : (bufBits R buf).dropWhile (fun b !b) = true :: buf := R:RankedAlphabetbuf:List BoolList.dropWhile (fun b !b) (bufBits R buf) = true :: buf R:RankedAlphabetbuf:List BoolList.dropWhile (fun b !b) (true :: buf) = true :: buf All goals completed! 🐙

The state word truncated to a window past the slot and zero-padded: the flag, the slot, and the pending count capped at the window. Stated at an arbitrary window, the dispatch and the verdict reading different ones.

theorem ofFn_bits_stateWord (R : RankedAlphabet) (s : Scan) (p m : ) (hp : p = 1 + R.width + m) (h : s.buf.length < R.width) : List.ofFn (bits p (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min m s.depth) true ++ List.replicate (m - s.depth) false)) := R:RankedAlphabets:Scanp:m:hp:p = 1 + R.width + mh:s.buf.length < R.widthList.ofFn (bits p (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min m s.depth) true ++ List.replicate (m - s.depth) false)) R:RankedAlphabets:Scanm:h:s.buf.length < R.widthList.ofFn (bits (1 + R.width + m) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min m s.depth) true ++ List.replicate (m - s.depth) false)) R:RankedAlphabets:Scanm:h:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthList.ofFn (bits (1 + R.width + m) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min m s.depth) true ++ List.replicate (m - s.depth) false)) R:RankedAlphabets:Scanm:h:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhdw:1 + R.width + m = (bufBits R s.buf).length + m + 1List.ofFn (bits (1 + R.width + m) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min m s.depth) true ++ List.replicate (m - s.depth) false)) R:RankedAlphabets:Scanm:h:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhdw:1 + R.width + m = (bufBits R s.buf).length + m + 1hpad:1 + R.width + m - (stateWord R s).length = m - s.depthList.ofFn (bits (1 + R.width + m) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min m s.depth) true ++ List.replicate (m - s.depth) false)) All goals completed! 🐙

The inverse of the state layout, read off List.ofFn of the bit family: the flag is the head, the block is the slot past its padding and sentinel, and the pending count is the run of true that follows the slot. Every operation is structural, so no Fin arithmetic and no Fintype-derived decidability arises.

@[`@[expose]` has no effect outside a `module` fileexpose] def decodeState (R : RankedAlphabet) (v : Fin (dispatchWidth R) Bool) : Scan := (((List.ofFn v).tail.take R.width).dropWhile (fun b !b)).tail, (((List.ofFn v).tail.drop R.width).takeWhile id).length, (List.ofFn v).headD false

The decoder inverts the layout, up to capping the pending count at the depth window R.maxArity + 1.

theorem decodeState_stateWord_of_lt (R : RankedAlphabet) (s : Scan) (h : s.buf.length < R.width) : decodeState R (bits (dispatchWidth R) (stateWord R s)) = { s with depth := min s.depth (R.maxArity + 1) } := R:RankedAlphabets:Scanh:s.buf.length < R.widthdecodeState R (bits (dispatchWidth R) (stateWord R s)) = { buf := s.buf, depth := min s.depth (R.maxArity + 1), live := s.live } R:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthdecodeState R (bits (dispatchWidth R) (stateWord R s)) = { buf := s.buf, depth := min s.depth (R.maxArity + 1), live := s.live } R:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhword:List.ofFn (bits (dispatchWidth R) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min (R.maxArity + 1) s.depth) true ++ List.replicate (R.maxArity + 1 - s.depth) false))decodeState R (bits (dispatchWidth R) (stateWord R s)) = { buf := s.buf, depth := min s.depth (R.maxArity + 1), live := s.live } R:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhword:List.ofFn (bits (dispatchWidth R) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min (R.maxArity + 1) s.depth) true ++ List.replicate (R.maxArity + 1 - s.depth) false))hslot:List.take R.width (List.ofFn (bits (dispatchWidth R) (stateWord R s))).tail = bufBits R s.bufdecodeState R (bits (dispatchWidth R) (stateWord R s)) = { buf := s.buf, depth := min s.depth (R.maxArity + 1), live := s.live } R:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhword:List.ofFn (bits (dispatchWidth R) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min (R.maxArity + 1) s.depth) true ++ List.replicate (R.maxArity + 1 - s.depth) false))hslot:List.take R.width (List.ofFn (bits (dispatchWidth R) (stateWord R s))).tail = bufBits R s.bufhtail:List.drop R.width (List.ofFn (bits (dispatchWidth R) (stateWord R s))).tail = List.replicate (min (R.maxArity + 1) s.depth) true ++ List.replicate (R.maxArity + 1 - s.depth) falsedecodeState R (bits (dispatchWidth R) (stateWord R s)) = { buf := s.buf, depth := min s.depth (R.maxArity + 1), live := s.live } R:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhword:List.ofFn (bits (dispatchWidth R) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min (R.maxArity + 1) s.depth) true ++ List.replicate (R.maxArity + 1 - s.depth) false))hslot:List.take R.width (List.ofFn (bits (dispatchWidth R) (stateWord R s))).tail = bufBits R s.bufhtail:List.drop R.width (List.ofFn (bits (dispatchWidth R) (stateWord R s))).tail = List.replicate (min (R.maxArity + 1) s.depth) true ++ List.replicate (R.maxArity + 1 - s.depth) false(decodeState R (bits (dispatchWidth R) (stateWord R s))).buf = { buf := s.buf, depth := min s.depth (R.maxArity + 1), live := s.live }.bufR:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhword:List.ofFn (bits (dispatchWidth R) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min (R.maxArity + 1) s.depth) true ++ List.replicate (R.maxArity + 1 - s.depth) false))hslot:List.take R.width (List.ofFn (bits (dispatchWidth R) (stateWord R s))).tail = bufBits R s.bufhtail:List.drop R.width (List.ofFn (bits (dispatchWidth R) (stateWord R s))).tail = List.replicate (min (R.maxArity + 1) s.depth) true ++ List.replicate (R.maxArity + 1 - s.depth) false(decodeState R (bits (dispatchWidth R) (stateWord R s))).depth = { buf := s.buf, depth := min s.depth (R.maxArity + 1), live := s.live }.depthR:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhword:List.ofFn (bits (dispatchWidth R) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min (R.maxArity + 1) s.depth) true ++ List.replicate (R.maxArity + 1 - s.depth) false))hslot:List.take R.width (List.ofFn (bits (dispatchWidth R) (stateWord R s))).tail = bufBits R s.bufhtail:List.drop R.width (List.ofFn (bits (dispatchWidth R) (stateWord R s))).tail = List.replicate (min (R.maxArity + 1) s.depth) true ++ List.replicate (R.maxArity + 1 - s.depth) false(decodeState R (bits (dispatchWidth R) (stateWord R s))).live = { buf := s.buf, depth := min s.depth (R.maxArity + 1), live := s.live }.live R:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhword:List.ofFn (bits (dispatchWidth R) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min (R.maxArity + 1) s.depth) true ++ List.replicate (R.maxArity + 1 - s.depth) false))hslot:List.take R.width (List.ofFn (bits (dispatchWidth R) (stateWord R s))).tail = bufBits R s.bufhtail:List.drop R.width (List.ofFn (bits (dispatchWidth R) (stateWord R s))).tail = List.replicate (min (R.maxArity + 1) s.depth) true ++ List.replicate (R.maxArity + 1 - s.depth) false(decodeState R (bits (dispatchWidth R) (stateWord R s))).buf = { buf := s.buf, depth := min s.depth (R.maxArity + 1), live := s.live }.buf R:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhword:List.ofFn (bits (dispatchWidth R) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min (R.maxArity + 1) s.depth) true ++ List.replicate (R.maxArity + 1 - s.depth) false))hslot:List.take R.width (List.ofFn (bits (dispatchWidth R) (stateWord R s))).tail = bufBits R s.bufhtail:List.drop R.width (List.ofFn (bits (dispatchWidth R) (stateWord R s))).tail = List.replicate (min (R.maxArity + 1) s.depth) true ++ List.replicate (R.maxArity + 1 - s.depth) false{ buf := (true :: s.buf).tail, depth := (List.takeWhile id (List.drop R.width (List.ofFn (bits (dispatchWidth R) (stateWord R s))).tail)).length, live := (List.ofFn (bits (dispatchWidth R) (stateWord R s))).headD false }.buf = { buf := s.buf, depth := min s.depth (R.maxArity + 1), live := s.live }.buf All goals completed! 🐙 R:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhword:List.ofFn (bits (dispatchWidth R) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min (R.maxArity + 1) s.depth) true ++ List.replicate (R.maxArity + 1 - s.depth) false))hslot:List.take R.width (List.ofFn (bits (dispatchWidth R) (stateWord R s))).tail = bufBits R s.bufhtail:List.drop R.width (List.ofFn (bits (dispatchWidth R) (stateWord R s))).tail = List.replicate (min (R.maxArity + 1) s.depth) true ++ List.replicate (R.maxArity + 1 - s.depth) false(decodeState R (bits (dispatchWidth R) (stateWord R s))).depth = { buf := s.buf, depth := min s.depth (R.maxArity + 1), live := s.live }.depth R:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhword:List.ofFn (bits (dispatchWidth R) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min (R.maxArity + 1) s.depth) true ++ List.replicate (R.maxArity + 1 - s.depth) false))hslot:List.take R.width (List.ofFn (bits (dispatchWidth R) (stateWord R s))).tail = bufBits R s.bufhtail:List.drop R.width (List.ofFn (bits (dispatchWidth R) (stateWord R s))).tail = List.replicate (min (R.maxArity + 1) s.depth) true ++ List.replicate (R.maxArity + 1 - s.depth) falsehfalse: (j : ), List.takeWhile id (List.replicate j false) = [](decodeState R (bits (dispatchWidth R) (stateWord R s))).depth = { buf := s.buf, depth := min s.depth (R.maxArity + 1), live := s.live }.depth R:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhword:List.ofFn (bits (dispatchWidth R) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min (R.maxArity + 1) s.depth) true ++ List.replicate (R.maxArity + 1 - s.depth) false))hslot:List.take R.width (List.ofFn (bits (dispatchWidth R) (stateWord R s))).tail = bufBits R s.bufhtail:List.drop R.width (List.ofFn (bits (dispatchWidth R) (stateWord R s))).tail = List.replicate (min (R.maxArity + 1) s.depth) true ++ List.replicate (R.maxArity + 1 - s.depth) falsehfalse: (j : ), List.takeWhile id (List.replicate j false) = []{ buf := (List.dropWhile (fun b !b) (List.take R.width (List.ofFn (bits (dispatchWidth R) (stateWord R s))).tail)).tail, depth := min (R.maxArity + 1) s.depth, live := (List.ofFn (bits (dispatchWidth R) (stateWord R s))).headD false }.depth = { buf := s.buf, depth := min s.depth (R.maxArity + 1), live := s.live }.depth All goals completed! 🐙 R:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhword:List.ofFn (bits (dispatchWidth R) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min (R.maxArity + 1) s.depth) true ++ List.replicate (R.maxArity + 1 - s.depth) false))hslot:List.take R.width (List.ofFn (bits (dispatchWidth R) (stateWord R s))).tail = bufBits R s.bufhtail:List.drop R.width (List.ofFn (bits (dispatchWidth R) (stateWord R s))).tail = List.replicate (min (R.maxArity + 1) s.depth) true ++ List.replicate (R.maxArity + 1 - s.depth) false(decodeState R (bits (dispatchWidth R) (stateWord R s))).live = { buf := s.buf, depth := min s.depth (R.maxArity + 1), live := s.live }.live All goals completed! 🐙

The bits a step drops from the state word: the flag and the slot, together with the popped subterms where a completed block's symbol pops.

@[`@[expose]` has no effect outside a `module` fileexpose] def dropCount (R : RankedAlphabet) (b : Bool) (s : Scan) : := match s.live with | false => 1 + R.width | true => match decide ((b :: s.buf).length = R.width) with | false => 1 + R.width | true => match R.arOf (decodeBits (b :: s.buf)) with | none => 1 + R.width | some r => match decide (r s.depth) with | false => 1 + R.width | true => 1 + R.width + r

The bits a step prepends to the state word: the rebuilt flag and slot, together with the pushed subterm where a completed block's symbol pops.

@[`@[expose]` has no effect outside a `module` fileexpose] def nextPrefix (R : RankedAlphabet) (b : Bool) (s : Scan) : List Bool := match s.live with | false => false :: bufBits R s.buf | true => match decide ((b :: s.buf).length = R.width) with | false => true :: bufBits R (b :: s.buf) | true => match R.arOf (decodeBits (b :: s.buf)) with | none => false :: bufBits R [] | some r => match decide (r s.depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]

Capping the pending count at the depth window R.maxArity + 1 leaves the bits dropped unchanged: the only test reading the count compares it with an arity, which is at most the largest.

theorem dropCount_min_depth (R : RankedAlphabet) (b : Bool) (s : Scan) : dropCount R b { s with depth := min s.depth (R.maxArity + 1) } = dropCount R b s := R:RankedAlphabetb:Bools:ScandropCount R b { buf := s.buf, depth := min s.depth (R.maxArity + 1), live := s.live } = dropCount R b s R:RankedAlphabetb:Boolbuf:List Booldepth:live:BooldropCount R b { buf := { buf := buf, depth := depth, live := live }.buf, depth := min { buf := buf, depth := depth, live := live }.depth (R.maxArity + 1), live := { buf := buf, depth := depth, live := live }.live } = dropCount R b { buf := buf, depth := depth, live := live } R:RankedAlphabetb:Boolbuf:List Booldepth:live:Bool(match { buf := { buf := buf, depth := depth, live := live }.buf, depth := min { buf := buf, depth := depth, live := live }.depth (R.maxArity + 1), live := { buf := buf, depth := depth, live := live }.live }.live with | false => 1 + R.width | true => match decide ((b :: { buf := { buf := buf, depth := depth, live := live }.buf, depth := min { buf := buf, depth := depth, live := live }.depth (R.maxArity + 1), live := { buf := buf, depth := depth, live := live }.live }.buf).length = R.width) with | false => 1 + R.width | true => match R.arOf (decodeBits (b :: { buf := { buf := buf, depth := depth, live := live }.buf, depth := min { buf := buf, depth := depth, live := live }.depth (R.maxArity + 1), live := { buf := buf, depth := depth, live := live }.live }.buf)) with | none => 1 + R.width | some r => match decide (r { buf := { buf := buf, depth := depth, live := live }.buf, depth := min { buf := buf, depth := depth, live := live }.depth (R.maxArity + 1), live := { buf := buf, depth := depth, live := live }.live }.depth) with | false => 1 + R.width | true => 1 + R.width + r) = match { buf := buf, depth := depth, live := live }.live with | false => 1 + R.width | true => match decide ((b :: { buf := buf, depth := depth, live := live }.buf).length = R.width) with | false => 1 + R.width | true => match R.arOf (decodeBits (b :: { buf := buf, depth := depth, live := live }.buf)) with | none => 1 + R.width | some r => match decide (r { buf := buf, depth := depth, live := live }.depth) with | false => 1 + R.width | true => 1 + R.width + r R:RankedAlphabetb:Boolbuf:List Booldepth:live:Bool(match live with | false => 1 + R.width | true => match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match R.arOf (decodeBits (b :: buf)) with | none => 1 + R.width | some r => match decide (r min depth (R.maxArity + 1)) with | false => 1 + R.width | true => 1 + R.width + r) = match live with | false => 1 + R.width | true => match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match R.arOf (decodeBits (b :: buf)) with | none => 1 + R.width | some r => match decide (r depth) with | false => 1 + R.width | true => 1 + R.width + r R:RankedAlphabetb:Boolbuf:List Booldepth:(match false with | false => 1 + R.width | true => match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match R.arOf (decodeBits (b :: buf)) with | none => 1 + R.width | some r => match decide (r min depth (R.maxArity + 1)) with | false => 1 + R.width | true => 1 + R.width + r) = match false with | false => 1 + R.width | true => match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match R.arOf (decodeBits (b :: buf)) with | none => 1 + R.width | some r => match decide (r depth) with | false => 1 + R.width | true => 1 + R.width + rR:RankedAlphabetb:Boolbuf:List Booldepth:(match true with | false => 1 + R.width | true => match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match R.arOf (decodeBits (b :: buf)) with | none => 1 + R.width | some r => match decide (r min depth (R.maxArity + 1)) with | false => 1 + R.width | true => 1 + R.width + r) = match true with | false => 1 + R.width | true => match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match R.arOf (decodeBits (b :: buf)) with | none => 1 + R.width | some r => match decide (r depth) with | false => 1 + R.width | true => 1 + R.width + r R:RankedAlphabetb:Boolbuf:List Booldepth:(match false with | false => 1 + R.width | true => match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match R.arOf (decodeBits (b :: buf)) with | none => 1 + R.width | some r => match decide (r min depth (R.maxArity + 1)) with | false => 1 + R.width | true => 1 + R.width + r) = match false with | false => 1 + R.width | true => match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match R.arOf (decodeBits (b :: buf)) with | none => 1 + R.width | some r => match decide (r depth) with | false => 1 + R.width | true => 1 + R.width + r All goals completed! 🐙 R:RankedAlphabetb:Boolbuf:List Booldepth:(match true with | false => 1 + R.width | true => match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match R.arOf (decodeBits (b :: buf)) with | none => 1 + R.width | some r => match decide (r min depth (R.maxArity + 1)) with | false => 1 + R.width | true => 1 + R.width + r) = match true with | false => 1 + R.width | true => match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match R.arOf (decodeBits (b :: buf)) with | none => 1 + R.width | some r => match decide (r depth) with | false => 1 + R.width | true => 1 + R.width + r R:RankedAlphabetb:Boolbuf:List Booldepth:har:R.arOf (decodeBits (b :: buf)) = none(match true with | false => 1 + R.width | true => match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match none with | none => 1 + R.width | some r => match decide (r min depth (R.maxArity + 1)) with | false => 1 + R.width | true => 1 + R.width + r) = match true with | false => 1 + R.width | true => match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match none with | none => 1 + R.width | some r => match decide (r depth) with | false => 1 + R.width | true => 1 + R.width + rR:RankedAlphabetb:Boolbuf:List Booldepth:val✝:har:R.arOf (decodeBits (b :: buf)) = some val✝(match true with | false => 1 + R.width | true => match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match some val✝ with | none => 1 + R.width | some r => match decide (r min depth (R.maxArity + 1)) with | false => 1 + R.width | true => 1 + R.width + r) = match true with | false => 1 + R.width | true => match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match some val✝ with | none => 1 + R.width | some r => match decide (r depth) with | false => 1 + R.width | true => 1 + R.width + r R:RankedAlphabetb:Boolbuf:List Booldepth:har:R.arOf (decodeBits (b :: buf)) = none(match true with | false => 1 + R.width | true => match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match none with | none => 1 + R.width | some r => match decide (r min depth (R.maxArity + 1)) with | false => 1 + R.width | true => 1 + R.width + r) = match true with | false => 1 + R.width | true => match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match none with | none => 1 + R.width | some r => match decide (r depth) with | false => 1 + R.width | true => 1 + R.width + r All goals completed! 🐙 R:RankedAlphabetb:Boolbuf:List Booldepth:val✝:har:R.arOf (decodeBits (b :: buf)) = some val✝(match true with | false => 1 + R.width | true => match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match some val✝ with | none => 1 + R.width | some r => match decide (r min depth (R.maxArity + 1)) with | false => 1 + R.width | true => 1 + R.width + r) = match true with | false => 1 + R.width | true => match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match some val✝ with | none => 1 + R.width | some r => match decide (r depth) with | false => 1 + R.width | true => 1 + R.width + r R:RankedAlphabetb:Boolbuf:List Booldepth:r:har:R.arOf (decodeBits (b :: buf)) = some val✝(match true with | false => 1 + R.width | true => match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match some val✝ with | none => 1 + R.width | some r => match decide (r min depth (R.maxArity + 1)) with | false => 1 + R.width | true => 1 + R.width + r) = match true with | false => 1 + R.width | true => match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match some val✝ with | none => 1 + R.width | some r => match decide (r depth) with | false => 1 + R.width | true => 1 + R.width + r R:RankedAlphabetb:Boolbuf:List Booldepth:r:har:R.arOf (decodeBits (b :: buf)) = some val✝hr:r R.maxArity(match true with | false => 1 + R.width | true => match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match some r with | none => 1 + R.width | some r => match decide (r min depth (R.maxArity + 1)) with | false => 1 + R.width | true => 1 + R.width + r) = match true with | false => 1 + R.width | true => match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match some r with | none => 1 + R.width | some r => match decide (r depth) with | false => 1 + R.width | true => 1 + R.width + r R:RankedAlphabetb:Boolbuf:List Booldepth:r:har:R.arOf (decodeBits (b :: buf)) = some val✝hr:r R.maxArity(match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match decide (r min depth (R.maxArity + 1)) with | false => 1 + R.width | true => 1 + R.width + r) = match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match decide (r depth) with | false => 1 + R.width | true => 1 + R.width + r R:RankedAlphabetb:Boolbuf:List Booldepth:r:har:R.arOf (decodeBits (b :: buf)) = some val✝hr:r R.maxArityhle:depth R.maxArity + 1(match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match decide (r min depth (R.maxArity + 1)) with | false => 1 + R.width | true => 1 + R.width + r) = match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match decide (r depth) with | false => 1 + R.width | true => 1 + R.width + rR:RankedAlphabetb:Boolbuf:List Booldepth:r:har:R.arOf (decodeBits (b :: buf)) = some val✝hr:r R.maxArityhle:R.maxArity + 1 depth(match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match decide (r min depth (R.maxArity + 1)) with | false => 1 + R.width | true => 1 + R.width + r) = match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match decide (r depth) with | false => 1 + R.width | true => 1 + R.width + r R:RankedAlphabetb:Boolbuf:List Booldepth:r:har:R.arOf (decodeBits (b :: buf)) = some val✝hr:r R.maxArityhle:depth R.maxArity + 1(match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match decide (r min depth (R.maxArity + 1)) with | false => 1 + R.width | true => 1 + R.width + r) = match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match decide (r depth) with | false => 1 + R.width | true => 1 + R.width + r All goals completed! 🐙 R:RankedAlphabetb:Boolbuf:List Booldepth:r:har:R.arOf (decodeBits (b :: buf)) = some val✝hr:r R.maxArityhle:R.maxArity + 1 depth(match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match decide (r min depth (R.maxArity + 1)) with | false => 1 + R.width | true => 1 + R.width + r) = match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match decide (r depth) with | false => 1 + R.width | true => 1 + R.width + r All goals completed! 🐙

Capping the pending count leaves the bits prepended unchanged, as dropCount_min_depth.

theorem nextPrefix_min_depth (R : RankedAlphabet) (b : Bool) (s : Scan) : nextPrefix R b { s with depth := min s.depth (R.maxArity + 1) } = nextPrefix R b s := R:RankedAlphabetb:Bools:ScannextPrefix R b { buf := s.buf, depth := min s.depth (R.maxArity + 1), live := s.live } = nextPrefix R b s R:RankedAlphabetb:Boolbuf:List Booldepth:live:BoolnextPrefix R b { buf := { buf := buf, depth := depth, live := live }.buf, depth := min { buf := buf, depth := depth, live := live }.depth (R.maxArity + 1), live := { buf := buf, depth := depth, live := live }.live } = nextPrefix R b { buf := buf, depth := depth, live := live } R:RankedAlphabetb:Boolbuf:List Booldepth:live:Bool(match { buf := { buf := buf, depth := depth, live := live }.buf, depth := min { buf := buf, depth := depth, live := live }.depth (R.maxArity + 1), live := { buf := buf, depth := depth, live := live }.live }.live with | false => false :: bufBits R { buf := { buf := buf, depth := depth, live := live }.buf, depth := min { buf := buf, depth := depth, live := live }.depth (R.maxArity + 1), live := { buf := buf, depth := depth, live := live }.live }.buf | true => match decide ((b :: { buf := { buf := buf, depth := depth, live := live }.buf, depth := min { buf := buf, depth := depth, live := live }.depth (R.maxArity + 1), live := { buf := buf, depth := depth, live := live }.live }.buf).length = R.width) with | false => true :: bufBits R (b :: { buf := { buf := buf, depth := depth, live := live }.buf, depth := min { buf := buf, depth := depth, live := live }.depth (R.maxArity + 1), live := { buf := buf, depth := depth, live := live }.live }.buf) | true => match R.arOf (decodeBits (b :: { buf := { buf := buf, depth := depth, live := live }.buf, depth := min { buf := buf, depth := depth, live := live }.depth (R.maxArity + 1), live := { buf := buf, depth := depth, live := live }.live }.buf)) with | none => false :: bufBits R [] | some r => match decide (r { buf := { buf := buf, depth := depth, live := live }.buf, depth := min { buf := buf, depth := depth, live := live }.depth (R.maxArity + 1), live := { buf := buf, depth := depth, live := live }.live }.depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) = match { buf := buf, depth := depth, live := live }.live with | false => false :: bufBits R { buf := buf, depth := depth, live := live }.buf | true => match decide ((b :: { buf := buf, depth := depth, live := live }.buf).length = R.width) with | false => true :: bufBits R (b :: { buf := buf, depth := depth, live := live }.buf) | true => match R.arOf (decodeBits (b :: { buf := buf, depth := depth, live := live }.buf)) with | none => false :: bufBits R [] | some r => match decide (r { buf := buf, depth := depth, live := live }.depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true] R:RankedAlphabetb:Boolbuf:List Booldepth:live:Bool(match live with | false => false :: bufBits R buf | true => match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match R.arOf (decodeBits (b :: buf)) with | none => false :: bufBits R [] | some r => match decide (r min depth (R.maxArity + 1)) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) = match live with | false => false :: bufBits R buf | true => match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match R.arOf (decodeBits (b :: buf)) with | none => false :: bufBits R [] | some r => match decide (r depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true] R:RankedAlphabetb:Boolbuf:List Booldepth:(match false with | false => false :: bufBits R buf | true => match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match R.arOf (decodeBits (b :: buf)) with | none => false :: bufBits R [] | some r => match decide (r min depth (R.maxArity + 1)) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) = match false with | false => false :: bufBits R buf | true => match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match R.arOf (decodeBits (b :: buf)) with | none => false :: bufBits R [] | some r => match decide (r depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]R:RankedAlphabetb:Boolbuf:List Booldepth:(match true with | false => false :: bufBits R buf | true => match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match R.arOf (decodeBits (b :: buf)) with | none => false :: bufBits R [] | some r => match decide (r min depth (R.maxArity + 1)) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) = match true with | false => false :: bufBits R buf | true => match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match R.arOf (decodeBits (b :: buf)) with | none => false :: bufBits R [] | some r => match decide (r depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true] R:RankedAlphabetb:Boolbuf:List Booldepth:(match false with | false => false :: bufBits R buf | true => match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match R.arOf (decodeBits (b :: buf)) with | none => false :: bufBits R [] | some r => match decide (r min depth (R.maxArity + 1)) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) = match false with | false => false :: bufBits R buf | true => match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match R.arOf (decodeBits (b :: buf)) with | none => false :: bufBits R [] | some r => match decide (r depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true] All goals completed! 🐙 R:RankedAlphabetb:Boolbuf:List Booldepth:(match true with | false => false :: bufBits R buf | true => match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match R.arOf (decodeBits (b :: buf)) with | none => false :: bufBits R [] | some r => match decide (r min depth (R.maxArity + 1)) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) = match true with | false => false :: bufBits R buf | true => match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match R.arOf (decodeBits (b :: buf)) with | none => false :: bufBits R [] | some r => match decide (r depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true] R:RankedAlphabetb:Boolbuf:List Booldepth:har:R.arOf (decodeBits (b :: buf)) = none(match true with | false => false :: bufBits R buf | true => match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match none with | none => false :: bufBits R [] | some r => match decide (r min depth (R.maxArity + 1)) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) = match true with | false => false :: bufBits R buf | true => match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match none with | none => false :: bufBits R [] | some r => match decide (r depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]R:RankedAlphabetb:Boolbuf:List Booldepth:val✝:har:R.arOf (decodeBits (b :: buf)) = some val✝(match true with | false => false :: bufBits R buf | true => match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match some val✝ with | none => false :: bufBits R [] | some r => match decide (r min depth (R.maxArity + 1)) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) = match true with | false => false :: bufBits R buf | true => match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match some val✝ with | none => false :: bufBits R [] | some r => match decide (r depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true] R:RankedAlphabetb:Boolbuf:List Booldepth:har:R.arOf (decodeBits (b :: buf)) = none(match true with | false => false :: bufBits R buf | true => match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match none with | none => false :: bufBits R [] | some r => match decide (r min depth (R.maxArity + 1)) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) = match true with | false => false :: bufBits R buf | true => match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match none with | none => false :: bufBits R [] | some r => match decide (r depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true] All goals completed! 🐙 R:RankedAlphabetb:Boolbuf:List Booldepth:val✝:har:R.arOf (decodeBits (b :: buf)) = some val✝(match true with | false => false :: bufBits R buf | true => match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match some val✝ with | none => false :: bufBits R [] | some r => match decide (r min depth (R.maxArity + 1)) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) = match true with | false => false :: bufBits R buf | true => match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match some val✝ with | none => false :: bufBits R [] | some r => match decide (r depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true] R:RankedAlphabetb:Boolbuf:List Booldepth:r:har:R.arOf (decodeBits (b :: buf)) = some val✝(match true with | false => false :: bufBits R buf | true => match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match some val✝ with | none => false :: bufBits R [] | some r => match decide (r min depth (R.maxArity + 1)) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) = match true with | false => false :: bufBits R buf | true => match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match some val✝ with | none => false :: bufBits R [] | some r => match decide (r depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true] R:RankedAlphabetb:Boolbuf:List Booldepth:r:har:R.arOf (decodeBits (b :: buf)) = some val✝hr:r R.maxArity(match true with | false => false :: bufBits R buf | true => match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match some r with | none => false :: bufBits R [] | some r => match decide (r min depth (R.maxArity + 1)) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) = match true with | false => false :: bufBits R buf | true => match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match some r with | none => false :: bufBits R [] | some r => match decide (r depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true] R:RankedAlphabetb:Boolbuf:List Booldepth:r:har:R.arOf (decodeBits (b :: buf)) = some val✝hr:r R.maxArity(match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match decide (r min depth (R.maxArity + 1)) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) = match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match decide (r depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true] R:RankedAlphabetb:Boolbuf:List Booldepth:r:har:R.arOf (decodeBits (b :: buf)) = some val✝hr:r R.maxArityhle:depth R.maxArity + 1(match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match decide (r min depth (R.maxArity + 1)) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) = match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match decide (r depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]R:RankedAlphabetb:Boolbuf:List Booldepth:r:har:R.arOf (decodeBits (b :: buf)) = some val✝hr:r R.maxArityhle:R.maxArity + 1 depth(match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match decide (r min depth (R.maxArity + 1)) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) = match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match decide (r depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true] R:RankedAlphabetb:Boolbuf:List Booldepth:r:har:R.arOf (decodeBits (b :: buf)) = some val✝hr:r R.maxArityhle:depth R.maxArity + 1(match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match decide (r min depth (R.maxArity + 1)) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) = match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match decide (r depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true] All goals completed! 🐙 R:RankedAlphabetb:Boolbuf:List Booldepth:r:har:R.arOf (decodeBits (b :: buf)) = some val✝hr:r R.maxArityhle:R.maxArity + 1 depth(match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match decide (r min depth (R.maxArity + 1)) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) = match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match decide (r depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true] All goals completed! 🐙

A step of the scan rewrites a bounded prefix of the state word and drops a bounded number of its bits: the flag and the slot are rebuilt, and the pending count in the tail is popped by the arity of a completed block's symbol.

theorem stateWord_scanStep_of_lt (R : RankedAlphabet) (b : Bool) (s : Scan) (h : s.buf.length < R.width) : stateWord R (R.scanStep b s) = nextPrefix R b s ++ (stateWord R s).drop (dropCount R b s) := R:RankedAlphabetb:Bools:Scanh:s.buf.length < R.widthstateWord R (R.scanStep b s) = nextPrefix R b s ++ List.drop (dropCount R b s) (stateWord R s) R:RankedAlphabetb:Bools:Scanh:s.buf.length < R.widthhpre:(s.live :: bufBits R s.buf).length = 1 + R.widthstateWord R (R.scanStep b s) = nextPrefix R b s ++ List.drop (dropCount R b s) (stateWord R s) R:RankedAlphabetb:Bools:Scanh:s.buf.length < R.widthhpre:(s.live :: bufBits R s.buf).length = 1 + R.widthhdrop:List.drop (1 + R.width) (stateWord R s) = List.replicate s.depth truestateWord R (R.scanStep b s) = nextPrefix R b s ++ List.drop (dropCount R b s) (stateWord R s) R:RankedAlphabetb:Bools:Scanh:s.buf.length < R.widthhpre:(s.live :: bufBits R s.buf).length = 1 + R.widthhdrop:List.drop (1 + R.width) (stateWord R s) = List.replicate s.depth truehdropr: (r : ), List.drop (1 + R.width + r) (stateWord R s) = List.replicate (s.depth - r) truestateWord R (R.scanStep b s) = nextPrefix R b s ++ List.drop (dropCount R b s) (stateWord R s) R:RankedAlphabetb:Boolbuf:List Booldepth:live:Boolh:{ buf := buf, depth := depth, live := live }.buf.length < R.widthhpre:({ buf := buf, depth := depth, live := live }.live :: bufBits R { buf := buf, depth := depth, live := live }.buf).length = 1 + R.widthhdrop:List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := live }) = List.replicate { buf := buf, depth := depth, live := live }.depth truehdropr: (r : ), List.drop (1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := live }) = List.replicate ({ buf := buf, depth := depth, live := live }.depth - r) truestateWord R (R.scanStep b { buf := buf, depth := depth, live := live }) = nextPrefix R b { buf := buf, depth := depth, live := live } ++ List.drop (dropCount R b { buf := buf, depth := depth, live := live }) (stateWord R { buf := buf, depth := depth, live := live }) R:RankedAlphabetb:Boolbuf:List Booldepth:live:Boolh:{ buf := buf, depth := depth, live := live }.buf.length < R.widthhpre:({ buf := buf, depth := depth, live := live }.live :: bufBits R { buf := buf, depth := depth, live := live }.buf).length = 1 + R.widthhdrop:List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := live }) = List.replicate { buf := buf, depth := depth, live := live }.depth truehdropr: (r : ), List.drop (1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := live }) = List.replicate ({ buf := buf, depth := depth, live := live }.depth - r) truestateWord R (match { buf := buf, depth := depth, live := live }.live with | false => { buf := buf, depth := depth, live := live } | true => match decide ((b :: { buf := buf, depth := depth, live := live }.buf).length = R.width) with | false => { buf := b :: { buf := buf, depth := depth, live := live }.buf, depth := { buf := buf, depth := depth, live := live }.depth, live := true } | true => match R.arOf (decodeBits (b :: { buf := buf, depth := depth, live := live }.buf)) with | none => { buf := [], depth := { buf := buf, depth := depth, live := live }.depth, live := false } | some r => match decide (r { buf := buf, depth := depth, live := live }.depth) with | false => { buf := [], depth := { buf := buf, depth := depth, live := live }.depth, live := false } | true => { buf := [], depth := { buf := buf, depth := depth, live := live }.depth - r + 1, live := true }) = (match { buf := buf, depth := depth, live := live }.live with | false => false :: bufBits R { buf := buf, depth := depth, live := live }.buf | true => match decide ((b :: { buf := buf, depth := depth, live := live }.buf).length = R.width) with | false => true :: bufBits R (b :: { buf := buf, depth := depth, live := live }.buf) | true => match R.arOf (decodeBits (b :: { buf := buf, depth := depth, live := live }.buf)) with | none => false :: bufBits R [] | some r => match decide (r { buf := buf, depth := depth, live := live }.depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) ++ List.drop (match { buf := buf, depth := depth, live := live }.live with | false => 1 + R.width | true => match decide ((b :: { buf := buf, depth := depth, live := live }.buf).length = R.width) with | false => 1 + R.width | true => match R.arOf (decodeBits (b :: { buf := buf, depth := depth, live := live }.buf)) with | none => 1 + R.width | some r => match decide (r { buf := buf, depth := depth, live := live }.depth) with | false => 1 + R.width | true => 1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := live }) R:RankedAlphabetb:Boolbuf:List Booldepth:live:Boolh:{ buf := buf, depth := depth, live := live }.buf.length < R.widthhpre:({ buf := buf, depth := depth, live := live }.live :: bufBits R { buf := buf, depth := depth, live := live }.buf).length = 1 + R.widthhdrop:List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := live }) = List.replicate { buf := buf, depth := depth, live := live }.depth truehdropr: (r : ), List.drop (1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := live }) = List.replicate ({ buf := buf, depth := depth, live := live }.depth - r) truestateWord R (match live with | false => { buf := buf, depth := depth, live := live } | true => match decide ((b :: buf).length = R.width) with | false => { buf := b :: buf, depth := depth, live := true } | true => match R.arOf (decodeBits (b :: buf)) with | none => { buf := [], depth := depth, live := false } | some r => match decide (r depth) with | false => { buf := [], depth := depth, live := false } | true => { buf := [], depth := depth - r + 1, live := true }) = (match live with | false => false :: bufBits R buf | true => match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match R.arOf (decodeBits (b :: buf)) with | none => false :: bufBits R [] | some r => match decide (r depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) ++ List.drop (match live with | false => 1 + R.width | true => match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match R.arOf (decodeBits (b :: buf)) with | none => 1 + R.width | some r => match decide (r depth) with | false => 1 + R.width | true => 1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := live }) R:RankedAlphabetb:Boolbuf:List Booldepth:h:{ buf := buf, depth := depth, live := false }.buf.length < R.widthhpre:({ buf := buf, depth := depth, live := false }.live :: bufBits R { buf := buf, depth := depth, live := false }.buf).length = 1 + R.widthhdrop:List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := false }) = List.replicate { buf := buf, depth := depth, live := false }.depth truehdropr: (r : ), List.drop (1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := false }) = List.replicate ({ buf := buf, depth := depth, live := false }.depth - r) truestateWord R (match false with | false => { buf := buf, depth := depth, live := false } | true => match decide ((b :: buf).length = R.width) with | false => { buf := b :: buf, depth := depth, live := true } | true => match R.arOf (decodeBits (b :: buf)) with | none => { buf := [], depth := depth, live := false } | some r => match decide (r depth) with | false => { buf := [], depth := depth, live := false } | true => { buf := [], depth := depth - r + 1, live := true }) = (match false with | false => false :: bufBits R buf | true => match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match R.arOf (decodeBits (b :: buf)) with | none => false :: bufBits R [] | some r => match decide (r depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) ++ List.drop (match false with | false => 1 + R.width | true => match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match R.arOf (decodeBits (b :: buf)) with | none => 1 + R.width | some r => match decide (r depth) with | false => 1 + R.width | true => 1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := false })R:RankedAlphabetb:Boolbuf:List Booldepth:h:{ buf := buf, depth := depth, live := true }.buf.length < R.widthhpre:({ buf := buf, depth := depth, live := true }.live :: bufBits R { buf := buf, depth := depth, live := true }.buf).length = 1 + R.widthhdrop:List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate { buf := buf, depth := depth, live := true }.depth truehdropr: (r : ), List.drop (1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate ({ buf := buf, depth := depth, live := true }.depth - r) truestateWord R (match true with | false => { buf := buf, depth := depth, live := true } | true => match decide ((b :: buf).length = R.width) with | false => { buf := b :: buf, depth := depth, live := true } | true => match R.arOf (decodeBits (b :: buf)) with | none => { buf := [], depth := depth, live := false } | some r => match decide (r depth) with | false => { buf := [], depth := depth, live := false } | true => { buf := [], depth := depth - r + 1, live := true }) = (match true with | false => false :: bufBits R buf | true => match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match R.arOf (decodeBits (b :: buf)) with | none => false :: bufBits R [] | some r => match decide (r depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) ++ List.drop (match true with | false => 1 + R.width | true => match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match R.arOf (decodeBits (b :: buf)) with | none => 1 + R.width | some r => match decide (r depth) with | false => 1 + R.width | true => 1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) R:RankedAlphabetb:Boolbuf:List Booldepth:h:{ buf := buf, depth := depth, live := false }.buf.length < R.widthhpre:({ buf := buf, depth := depth, live := false }.live :: bufBits R { buf := buf, depth := depth, live := false }.buf).length = 1 + R.widthhdrop:List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := false }) = List.replicate { buf := buf, depth := depth, live := false }.depth truehdropr: (r : ), List.drop (1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := false }) = List.replicate ({ buf := buf, depth := depth, live := false }.depth - r) truestateWord R (match false with | false => { buf := buf, depth := depth, live := false } | true => match decide ((b :: buf).length = R.width) with | false => { buf := b :: buf, depth := depth, live := true } | true => match R.arOf (decodeBits (b :: buf)) with | none => { buf := [], depth := depth, live := false } | some r => match decide (r depth) with | false => { buf := [], depth := depth, live := false } | true => { buf := [], depth := depth - r + 1, live := true }) = (match false with | false => false :: bufBits R buf | true => match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match R.arOf (decodeBits (b :: buf)) with | none => false :: bufBits R [] | some r => match decide (r depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) ++ List.drop (match false with | false => 1 + R.width | true => match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match R.arOf (decodeBits (b :: buf)) with | none => 1 + R.width | some r => match decide (r depth) with | false => 1 + R.width | true => 1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := false }) R:RankedAlphabetb:Boolbuf:List Booldepth:h:{ buf := buf, depth := depth, live := false }.buf.length < R.widthhpre:({ buf := buf, depth := depth, live := false }.live :: bufBits R { buf := buf, depth := depth, live := false }.buf).length = 1 + R.widthhdrop:List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := false }) = List.replicate { buf := buf, depth := depth, live := false }.depth truehdropr: (r : ), List.drop (1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := false }) = List.replicate ({ buf := buf, depth := depth, live := false }.depth - r) truestateWord R { buf := buf, depth := depth, live := false } = false :: bufBits R buf ++ List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := false }) R:RankedAlphabetb:Boolbuf:List Booldepth:h:{ buf := buf, depth := depth, live := false }.buf.length < R.widthhpre:({ buf := buf, depth := depth, live := false }.live :: bufBits R { buf := buf, depth := depth, live := false }.buf).length = 1 + R.widthhdrop:List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := false }) = List.replicate { buf := buf, depth := depth, live := false }.depth truehdropr: (r : ), List.drop (1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := false }) = List.replicate ({ buf := buf, depth := depth, live := false }.depth - r) truestateWord R { buf := buf, depth := depth, live := false } = false :: bufBits R buf ++ List.replicate { buf := buf, depth := depth, live := false }.depth true All goals completed! 🐙 R:RankedAlphabetb:Boolbuf:List Booldepth:h:{ buf := buf, depth := depth, live := true }.buf.length < R.widthhpre:({ buf := buf, depth := depth, live := true }.live :: bufBits R { buf := buf, depth := depth, live := true }.buf).length = 1 + R.widthhdrop:List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate { buf := buf, depth := depth, live := true }.depth truehdropr: (r : ), List.drop (1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate ({ buf := buf, depth := depth, live := true }.depth - r) truestateWord R (match true with | false => { buf := buf, depth := depth, live := true } | true => match decide ((b :: buf).length = R.width) with | false => { buf := b :: buf, depth := depth, live := true } | true => match R.arOf (decodeBits (b :: buf)) with | none => { buf := [], depth := depth, live := false } | some r => match decide (r depth) with | false => { buf := [], depth := depth, live := false } | true => { buf := [], depth := depth - r + 1, live := true }) = (match true with | false => false :: bufBits R buf | true => match decide ((b :: buf).length = R.width) with | false => true :: bufBits R (b :: buf) | true => match R.arOf (decodeBits (b :: buf)) with | none => false :: bufBits R [] | some r => match decide (r depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) ++ List.drop (match true with | false => 1 + R.width | true => match decide ((b :: buf).length = R.width) with | false => 1 + R.width | true => match R.arOf (decodeBits (b :: buf)) with | none => 1 + R.width | some r => match decide (r depth) with | false => 1 + R.width | true => 1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) R:RankedAlphabetb:Boolbuf:List Booldepth:h:{ buf := buf, depth := depth, live := true }.buf.length < R.widthhpre:({ buf := buf, depth := depth, live := true }.live :: bufBits R { buf := buf, depth := depth, live := true }.buf).length = 1 + R.widthhdrop:List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate { buf := buf, depth := depth, live := true }.depth truehdropr: (r : ), List.drop (1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate ({ buf := buf, depth := depth, live := true }.depth - r) truehc:decide ((b :: buf).length = R.width) = falsestateWord R (match true with | false => { buf := buf, depth := depth, live := true } | true => match false with | false => { buf := b :: buf, depth := depth, live := true } | true => match R.arOf (decodeBits (b :: buf)) with | none => { buf := [], depth := depth, live := false } | some r => match decide (r depth) with | false => { buf := [], depth := depth, live := false } | true => { buf := [], depth := depth - r + 1, live := true }) = (match true with | false => false :: bufBits R buf | true => match false with | false => true :: bufBits R (b :: buf) | true => match R.arOf (decodeBits (b :: buf)) with | none => false :: bufBits R [] | some r => match decide (r depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) ++ List.drop (match true with | false => 1 + R.width | true => match false with | false => 1 + R.width | true => match R.arOf (decodeBits (b :: buf)) with | none => 1 + R.width | some r => match decide (r depth) with | false => 1 + R.width | true => 1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true })R:RankedAlphabetb:Boolbuf:List Booldepth:h:{ buf := buf, depth := depth, live := true }.buf.length < R.widthhpre:({ buf := buf, depth := depth, live := true }.live :: bufBits R { buf := buf, depth := depth, live := true }.buf).length = 1 + R.widthhdrop:List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate { buf := buf, depth := depth, live := true }.depth truehdropr: (r : ), List.drop (1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate ({ buf := buf, depth := depth, live := true }.depth - r) truehc:decide ((b :: buf).length = R.width) = truestateWord R (match true with | false => { buf := buf, depth := depth, live := true } | true => match true with | false => { buf := b :: buf, depth := depth, live := true } | true => match R.arOf (decodeBits (b :: buf)) with | none => { buf := [], depth := depth, live := false } | some r => match decide (r depth) with | false => { buf := [], depth := depth, live := false } | true => { buf := [], depth := depth - r + 1, live := true }) = (match true with | false => false :: bufBits R buf | true => match true with | false => true :: bufBits R (b :: buf) | true => match R.arOf (decodeBits (b :: buf)) with | none => false :: bufBits R [] | some r => match decide (r depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) ++ List.drop (match true with | false => 1 + R.width | true => match true with | false => 1 + R.width | true => match R.arOf (decodeBits (b :: buf)) with | none => 1 + R.width | some r => match decide (r depth) with | false => 1 + R.width | true => 1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) R:RankedAlphabetb:Boolbuf:List Booldepth:h:{ buf := buf, depth := depth, live := true }.buf.length < R.widthhpre:({ buf := buf, depth := depth, live := true }.live :: bufBits R { buf := buf, depth := depth, live := true }.buf).length = 1 + R.widthhdrop:List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate { buf := buf, depth := depth, live := true }.depth truehdropr: (r : ), List.drop (1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate ({ buf := buf, depth := depth, live := true }.depth - r) truehc:decide ((b :: buf).length = R.width) = falsestateWord R (match true with | false => { buf := buf, depth := depth, live := true } | true => match false with | false => { buf := b :: buf, depth := depth, live := true } | true => match R.arOf (decodeBits (b :: buf)) with | none => { buf := [], depth := depth, live := false } | some r => match decide (r depth) with | false => { buf := [], depth := depth, live := false } | true => { buf := [], depth := depth - r + 1, live := true }) = (match true with | false => false :: bufBits R buf | true => match false with | false => true :: bufBits R (b :: buf) | true => match R.arOf (decodeBits (b :: buf)) with | none => false :: bufBits R [] | some r => match decide (r depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) ++ List.drop (match true with | false => 1 + R.width | true => match false with | false => 1 + R.width | true => match R.arOf (decodeBits (b :: buf)) with | none => 1 + R.width | some r => match decide (r depth) with | false => 1 + R.width | true => 1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) R:RankedAlphabetb:Boolbuf:List Booldepth:h:{ buf := buf, depth := depth, live := true }.buf.length < R.widthhpre:({ buf := buf, depth := depth, live := true }.live :: bufBits R { buf := buf, depth := depth, live := true }.buf).length = 1 + R.widthhdrop:List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate { buf := buf, depth := depth, live := true }.depth truehdropr: (r : ), List.drop (1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate ({ buf := buf, depth := depth, live := true }.depth - r) truehc:decide ((b :: buf).length = R.width) = falsestateWord R { buf := b :: buf, depth := depth, live := true } = true :: bufBits R (b :: buf) ++ List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := true }) R:RankedAlphabetb:Boolbuf:List Booldepth:h:{ buf := buf, depth := depth, live := true }.buf.length < R.widthhpre:({ buf := buf, depth := depth, live := true }.live :: bufBits R { buf := buf, depth := depth, live := true }.buf).length = 1 + R.widthhdrop:List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate { buf := buf, depth := depth, live := true }.depth truehdropr: (r : ), List.drop (1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate ({ buf := buf, depth := depth, live := true }.depth - r) truehc:decide ((b :: buf).length = R.width) = falsestateWord R { buf := b :: buf, depth := depth, live := true } = true :: bufBits R (b :: buf) ++ List.replicate { buf := buf, depth := depth, live := true }.depth true All goals completed! 🐙 R:RankedAlphabetb:Boolbuf:List Booldepth:h:{ buf := buf, depth := depth, live := true }.buf.length < R.widthhpre:({ buf := buf, depth := depth, live := true }.live :: bufBits R { buf := buf, depth := depth, live := true }.buf).length = 1 + R.widthhdrop:List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate { buf := buf, depth := depth, live := true }.depth truehdropr: (r : ), List.drop (1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate ({ buf := buf, depth := depth, live := true }.depth - r) truehc:decide ((b :: buf).length = R.width) = truestateWord R (match true with | false => { buf := buf, depth := depth, live := true } | true => match true with | false => { buf := b :: buf, depth := depth, live := true } | true => match R.arOf (decodeBits (b :: buf)) with | none => { buf := [], depth := depth, live := false } | some r => match decide (r depth) with | false => { buf := [], depth := depth, live := false } | true => { buf := [], depth := depth - r + 1, live := true }) = (match true with | false => false :: bufBits R buf | true => match true with | false => true :: bufBits R (b :: buf) | true => match R.arOf (decodeBits (b :: buf)) with | none => false :: bufBits R [] | some r => match decide (r depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) ++ List.drop (match true with | false => 1 + R.width | true => match true with | false => 1 + R.width | true => match R.arOf (decodeBits (b :: buf)) with | none => 1 + R.width | some r => match decide (r depth) with | false => 1 + R.width | true => 1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) R:RankedAlphabetb:Boolbuf:List Booldepth:h:{ buf := buf, depth := depth, live := true }.buf.length < R.widthhpre:({ buf := buf, depth := depth, live := true }.live :: bufBits R { buf := buf, depth := depth, live := true }.buf).length = 1 + R.widthhdrop:List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate { buf := buf, depth := depth, live := true }.depth truehdropr: (r : ), List.drop (1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate ({ buf := buf, depth := depth, live := true }.depth - r) truehc:decide ((b :: buf).length = R.width) = truestateWord R (match R.arOf (decodeBits (b :: buf)) with | none => { buf := [], depth := depth, live := false } | some r => match decide (r depth) with | false => { buf := [], depth := depth, live := false } | true => { buf := [], depth := depth - r + 1, live := true }) = (match R.arOf (decodeBits (b :: buf)) with | none => false :: bufBits R [] | some r => match decide (r depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) ++ List.drop (match R.arOf (decodeBits (b :: buf)) with | none => 1 + R.width | some r => match decide (r depth) with | false => 1 + R.width | true => 1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) R:RankedAlphabetb:Boolbuf:List Booldepth:h:{ buf := buf, depth := depth, live := true }.buf.length < R.widthhpre:({ buf := buf, depth := depth, live := true }.live :: bufBits R { buf := buf, depth := depth, live := true }.buf).length = 1 + R.widthhdrop:List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate { buf := buf, depth := depth, live := true }.depth truehdropr: (r : ), List.drop (1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate ({ buf := buf, depth := depth, live := true }.depth - r) truehc:decide ((b :: buf).length = R.width) = truehar:R.arOf (decodeBits (b :: buf)) = nonestateWord R (match none with | none => { buf := [], depth := depth, live := false } | some r => match decide (r depth) with | false => { buf := [], depth := depth, live := false } | true => { buf := [], depth := depth - r + 1, live := true }) = (match none with | none => false :: bufBits R [] | some r => match decide (r depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) ++ List.drop (match none with | none => 1 + R.width | some r => match decide (r depth) with | false => 1 + R.width | true => 1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true })R:RankedAlphabetb:Boolbuf:List Booldepth:h:{ buf := buf, depth := depth, live := true }.buf.length < R.widthhpre:({ buf := buf, depth := depth, live := true }.live :: bufBits R { buf := buf, depth := depth, live := true }.buf).length = 1 + R.widthhdrop:List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate { buf := buf, depth := depth, live := true }.depth truehdropr: (r : ), List.drop (1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate ({ buf := buf, depth := depth, live := true }.depth - r) truehc:decide ((b :: buf).length = R.width) = trueval✝:har:R.arOf (decodeBits (b :: buf)) = some val✝stateWord R (match some val✝ with | none => { buf := [], depth := depth, live := false } | some r => match decide (r depth) with | false => { buf := [], depth := depth, live := false } | true => { buf := [], depth := depth - r + 1, live := true }) = (match some val✝ with | none => false :: bufBits R [] | some r => match decide (r depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) ++ List.drop (match some val✝ with | none => 1 + R.width | some r => match decide (r depth) with | false => 1 + R.width | true => 1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) R:RankedAlphabetb:Boolbuf:List Booldepth:h:{ buf := buf, depth := depth, live := true }.buf.length < R.widthhpre:({ buf := buf, depth := depth, live := true }.live :: bufBits R { buf := buf, depth := depth, live := true }.buf).length = 1 + R.widthhdrop:List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate { buf := buf, depth := depth, live := true }.depth truehdropr: (r : ), List.drop (1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate ({ buf := buf, depth := depth, live := true }.depth - r) truehc:decide ((b :: buf).length = R.width) = truehar:R.arOf (decodeBits (b :: buf)) = nonestateWord R (match none with | none => { buf := [], depth := depth, live := false } | some r => match decide (r depth) with | false => { buf := [], depth := depth, live := false } | true => { buf := [], depth := depth - r + 1, live := true }) = (match none with | none => false :: bufBits R [] | some r => match decide (r depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) ++ List.drop (match none with | none => 1 + R.width | some r => match decide (r depth) with | false => 1 + R.width | true => 1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) R:RankedAlphabetb:Boolbuf:List Booldepth:h:{ buf := buf, depth := depth, live := true }.buf.length < R.widthhpre:({ buf := buf, depth := depth, live := true }.live :: bufBits R { buf := buf, depth := depth, live := true }.buf).length = 1 + R.widthhdrop:List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate { buf := buf, depth := depth, live := true }.depth truehdropr: (r : ), List.drop (1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate ({ buf := buf, depth := depth, live := true }.depth - r) truehc:decide ((b :: buf).length = R.width) = truehar:R.arOf (decodeBits (b :: buf)) = nonestateWord R { buf := [], depth := depth, live := false } = false :: bufBits R [] ++ List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := true }) R:RankedAlphabetb:Boolbuf:List Booldepth:h:{ buf := buf, depth := depth, live := true }.buf.length < R.widthhpre:({ buf := buf, depth := depth, live := true }.live :: bufBits R { buf := buf, depth := depth, live := true }.buf).length = 1 + R.widthhdrop:List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate { buf := buf, depth := depth, live := true }.depth truehdropr: (r : ), List.drop (1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate ({ buf := buf, depth := depth, live := true }.depth - r) truehc:decide ((b :: buf).length = R.width) = truehar:R.arOf (decodeBits (b :: buf)) = nonestateWord R { buf := [], depth := depth, live := false } = false :: bufBits R [] ++ List.replicate { buf := buf, depth := depth, live := true }.depth true All goals completed! 🐙 R:RankedAlphabetb:Boolbuf:List Booldepth:h:{ buf := buf, depth := depth, live := true }.buf.length < R.widthhpre:({ buf := buf, depth := depth, live := true }.live :: bufBits R { buf := buf, depth := depth, live := true }.buf).length = 1 + R.widthhdrop:List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate { buf := buf, depth := depth, live := true }.depth truehdropr: (r : ), List.drop (1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate ({ buf := buf, depth := depth, live := true }.depth - r) truehc:decide ((b :: buf).length = R.width) = trueval✝:har:R.arOf (decodeBits (b :: buf)) = some val✝stateWord R (match some val✝ with | none => { buf := [], depth := depth, live := false } | some r => match decide (r depth) with | false => { buf := [], depth := depth, live := false } | true => { buf := [], depth := depth - r + 1, live := true }) = (match some val✝ with | none => false :: bufBits R [] | some r => match decide (r depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) ++ List.drop (match some val✝ with | none => 1 + R.width | some r => match decide (r depth) with | false => 1 + R.width | true => 1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) R:RankedAlphabetb:Boolbuf:List Booldepth:h:{ buf := buf, depth := depth, live := true }.buf.length < R.widthhpre:({ buf := buf, depth := depth, live := true }.live :: bufBits R { buf := buf, depth := depth, live := true }.buf).length = 1 + R.widthhdrop:List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate { buf := buf, depth := depth, live := true }.depth truehdropr: (r : ), List.drop (1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate ({ buf := buf, depth := depth, live := true }.depth - r) truehc:decide ((b :: buf).length = R.width) = truer:har:R.arOf (decodeBits (b :: buf)) = some val✝stateWord R (match some val✝ with | none => { buf := [], depth := depth, live := false } | some r => match decide (r depth) with | false => { buf := [], depth := depth, live := false } | true => { buf := [], depth := depth - r + 1, live := true }) = (match some val✝ with | none => false :: bufBits R [] | some r => match decide (r depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) ++ List.drop (match some val✝ with | none => 1 + R.width | some r => match decide (r depth) with | false => 1 + R.width | true => 1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) R:RankedAlphabetb:Boolbuf:List Booldepth:h:{ buf := buf, depth := depth, live := true }.buf.length < R.widthhpre:({ buf := buf, depth := depth, live := true }.live :: bufBits R { buf := buf, depth := depth, live := true }.buf).length = 1 + R.widthhdrop:List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate { buf := buf, depth := depth, live := true }.depth truehdropr: (r : ), List.drop (1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate ({ buf := buf, depth := depth, live := true }.depth - r) truehc:decide ((b :: buf).length = R.width) = truer:har:R.arOf (decodeBits (b :: buf)) = some val✝stateWord R (match decide (r depth) with | false => { buf := [], depth := depth, live := false } | true => { buf := [], depth := depth - r + 1, live := true }) = (match decide (r depth) with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) ++ List.drop (match decide (r depth) with | false => 1 + R.width | true => 1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) R:RankedAlphabetb:Boolbuf:List Booldepth:h:{ buf := buf, depth := depth, live := true }.buf.length < R.widthhpre:({ buf := buf, depth := depth, live := true }.live :: bufBits R { buf := buf, depth := depth, live := true }.buf).length = 1 + R.widthhdrop:List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate { buf := buf, depth := depth, live := true }.depth truehdropr: (r : ), List.drop (1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate ({ buf := buf, depth := depth, live := true }.depth - r) truehc:decide ((b :: buf).length = R.width) = truer:har:R.arOf (decodeBits (b :: buf)) = some val✝hle:decide (r depth) = falsestateWord R (match false with | false => { buf := [], depth := depth, live := false } | true => { buf := [], depth := depth - r + 1, live := true }) = (match false with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) ++ List.drop (match false with | false => 1 + R.width | true => 1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true })R:RankedAlphabetb:Boolbuf:List Booldepth:h:{ buf := buf, depth := depth, live := true }.buf.length < R.widthhpre:({ buf := buf, depth := depth, live := true }.live :: bufBits R { buf := buf, depth := depth, live := true }.buf).length = 1 + R.widthhdrop:List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate { buf := buf, depth := depth, live := true }.depth truehdropr: (r : ), List.drop (1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate ({ buf := buf, depth := depth, live := true }.depth - r) truehc:decide ((b :: buf).length = R.width) = truer:har:R.arOf (decodeBits (b :: buf)) = some val✝hle:decide (r depth) = truestateWord R (match true with | false => { buf := [], depth := depth, live := false } | true => { buf := [], depth := depth - r + 1, live := true }) = (match true with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) ++ List.drop (match true with | false => 1 + R.width | true => 1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) R:RankedAlphabetb:Boolbuf:List Booldepth:h:{ buf := buf, depth := depth, live := true }.buf.length < R.widthhpre:({ buf := buf, depth := depth, live := true }.live :: bufBits R { buf := buf, depth := depth, live := true }.buf).length = 1 + R.widthhdrop:List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate { buf := buf, depth := depth, live := true }.depth truehdropr: (r : ), List.drop (1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate ({ buf := buf, depth := depth, live := true }.depth - r) truehc:decide ((b :: buf).length = R.width) = truer:har:R.arOf (decodeBits (b :: buf)) = some val✝hle:decide (r depth) = falsestateWord R (match false with | false => { buf := [], depth := depth, live := false } | true => { buf := [], depth := depth - r + 1, live := true }) = (match false with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) ++ List.drop (match false with | false => 1 + R.width | true => 1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) R:RankedAlphabetb:Boolbuf:List Booldepth:h:{ buf := buf, depth := depth, live := true }.buf.length < R.widthhpre:({ buf := buf, depth := depth, live := true }.live :: bufBits R { buf := buf, depth := depth, live := true }.buf).length = 1 + R.widthhdrop:List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate { buf := buf, depth := depth, live := true }.depth truehdropr: (r : ), List.drop (1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate ({ buf := buf, depth := depth, live := true }.depth - r) truehc:decide ((b :: buf).length = R.width) = truer:har:R.arOf (decodeBits (b :: buf)) = some val✝hle:decide (r depth) = falsestateWord R { buf := [], depth := depth, live := false } = false :: bufBits R [] ++ List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := true }) R:RankedAlphabetb:Boolbuf:List Booldepth:h:{ buf := buf, depth := depth, live := true }.buf.length < R.widthhpre:({ buf := buf, depth := depth, live := true }.live :: bufBits R { buf := buf, depth := depth, live := true }.buf).length = 1 + R.widthhdrop:List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate { buf := buf, depth := depth, live := true }.depth truehdropr: (r : ), List.drop (1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate ({ buf := buf, depth := depth, live := true }.depth - r) truehc:decide ((b :: buf).length = R.width) = truer:har:R.arOf (decodeBits (b :: buf)) = some val✝hle:decide (r depth) = falsestateWord R { buf := [], depth := depth, live := false } = false :: bufBits R [] ++ List.replicate { buf := buf, depth := depth, live := true }.depth true All goals completed! 🐙 R:RankedAlphabetb:Boolbuf:List Booldepth:h:{ buf := buf, depth := depth, live := true }.buf.length < R.widthhpre:({ buf := buf, depth := depth, live := true }.live :: bufBits R { buf := buf, depth := depth, live := true }.buf).length = 1 + R.widthhdrop:List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate { buf := buf, depth := depth, live := true }.depth truehdropr: (r : ), List.drop (1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate ({ buf := buf, depth := depth, live := true }.depth - r) truehc:decide ((b :: buf).length = R.width) = truer:har:R.arOf (decodeBits (b :: buf)) = some val✝hle:decide (r depth) = truestateWord R (match true with | false => { buf := [], depth := depth, live := false } | true => { buf := [], depth := depth - r + 1, live := true }) = (match true with | false => false :: bufBits R [] | true => true :: bufBits R [] ++ [true]) ++ List.drop (match true with | false => 1 + R.width | true => 1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) R:RankedAlphabetb:Boolbuf:List Booldepth:h:{ buf := buf, depth := depth, live := true }.buf.length < R.widthhpre:({ buf := buf, depth := depth, live := true }.live :: bufBits R { buf := buf, depth := depth, live := true }.buf).length = 1 + R.widthhdrop:List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate { buf := buf, depth := depth, live := true }.depth truehdropr: (r : ), List.drop (1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate ({ buf := buf, depth := depth, live := true }.depth - r) truehc:decide ((b :: buf).length = R.width) = truer:har:R.arOf (decodeBits (b :: buf)) = some val✝hle:decide (r depth) = truestateWord R { buf := [], depth := depth - r + 1, live := true } = true :: bufBits R [] ++ [true] ++ List.drop (1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) R:RankedAlphabetb:Boolbuf:List Booldepth:h:{ buf := buf, depth := depth, live := true }.buf.length < R.widthhpre:({ buf := buf, depth := depth, live := true }.live :: bufBits R { buf := buf, depth := depth, live := true }.buf).length = 1 + R.widthhdrop:List.drop (1 + R.width) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate { buf := buf, depth := depth, live := true }.depth truehdropr: (r : ), List.drop (1 + R.width + r) (stateWord R { buf := buf, depth := depth, live := true }) = List.replicate ({ buf := buf, depth := depth, live := true }.depth - r) truehc:decide ((b :: buf).length = R.width) = truer:har:R.arOf (decodeBits (b :: buf)) = some val✝hle:decide (r depth) = true{ buf := [], depth := depth - r + 1, live := true }.live :: bufBits R { buf := [], depth := depth - r + 1, live := true }.buf ++ true :: List.replicate (depth - r) true = true :: bufBits R [] ++ ([true] ++ List.replicate ({ buf := buf, depth := depth, live := true }.depth - r) true) All goals completed! 🐙

One step of the recognizer: dispatch on the state's leading bits, prepend the rebuilt prefix and drop the consumed bits. Every branch has that one shape.

@[`@[expose]` has no effect outside a `module` fileexpose] def rankedStep (R : RankedAlphabet) (b : Bool) : COf 1 := diagOf (casesOf (dispatchWidth R) fun v prependOf (nextPrefix R b (decodeState R v)) (predIterOf (dropCount R b (decodeState R v))))

The recognizer's scan, at the two steps and the growth the state layout allows.

@[`@[expose]` has no effect outside a `module` fileexpose] def rankedSem (R : RankedAlphabet) : Sem 1 := scanSem (constAtOf 0 (stateWord R [], 0, true)) (rankedStep R false) (rankedStep R true) (R.width + 1)

A step of the expression computes a step of the scan, on a state whose incomplete block is short of the width. This is where the decoder, the two capping lemmas and the step lemma meet.

theorem stepWord_rankedStep_of_lt (R : RankedAlphabet) (b : Bool) (s : Scan) (h : s.buf.length < R.width) : stepWord (rankedStep R b) (stateWord R s) = stateWord R (R.scanStep b s) := R:RankedAlphabetb:Bools:Scanh:s.buf.length < R.widthstepWord (rankedStep R b) (stateWord R s) = stateWord R (R.scanStep b s) R:RankedAlphabetb:Bools:Scanh:s.buf.length < R.widthsemAt 2 (casesOf (dispatchWidth R) fun v prependOf (nextPrefix R b (decodeState R v)) (predIterOf (dropCount R b (decodeState R v)))) ![stateWord R s, stateWord R s] = stateWord R (R.scanStep b s) R:RankedAlphabetb:Bools:Scanh:s.buf.length < R.widthcasesSem (dispatchWidth R) (fun v prependOf (nextPrefix R b (decodeState R v)) (predIterOf (dropCount R b (decodeState R v)))) ![stateWord R s, stateWord R s] = stateWord R (R.scanStep b s) All goals completed! 🐙

The expression computes the scan's state word on every input.

theorem rankedSem_eq (R : RankedAlphabet) (w : List Bool) : rankedSem R ![w] = stateWord R (R.scanFinal w) := R:RankedAlphabetw:List BoolrankedSem R ![w] = stateWord R (R.scanFinal w) R:RankedAlphabetw:List BoolList.foldr (scanStepWord (rankedStep R false) (rankedStep R true)) (baseWord (constAtOf 0 (stateWord R { buf := [], depth := 0, live := true }))) w = stateWord R (R.scanFinal w) R:RankedAlphabetw:List BoolList.foldr (scanStepWord (rankedStep R false) (rankedStep R true)) (baseWord (constAtOf 0 (stateWord R { buf := [], depth := 0, live := true }))) [] = stateWord R (R.scanFinal [])R:RankedAlphabetw:List Bool (head : Bool) (tail : List Bool), List.foldr (scanStepWord (rankedStep R false) (rankedStep R true)) (baseWord (constAtOf 0 (stateWord R { buf := [], depth := 0, live := true }))) tail = stateWord R (R.scanFinal tail) List.foldr (scanStepWord (rankedStep R false) (rankedStep R true)) (baseWord (constAtOf 0 (stateWord R { buf := [], depth := 0, live := true }))) (head :: tail) = stateWord R (R.scanFinal (head :: tail)) R:RankedAlphabetw:List BoolList.foldr (scanStepWord (rankedStep R false) (rankedStep R true)) (baseWord (constAtOf 0 (stateWord R { buf := [], depth := 0, live := true }))) [] = stateWord R (R.scanFinal []) All goals completed! 🐙 R:RankedAlphabetw:List Bool (head : Bool) (tail : List Bool), List.foldr (scanStepWord (rankedStep R false) (rankedStep R true)) (baseWord (constAtOf 0 (stateWord R { buf := [], depth := 0, live := true }))) tail = stateWord R (R.scanFinal tail) List.foldr (scanStepWord (rankedStep R false) (rankedStep R true)) (baseWord (constAtOf 0 (stateWord R { buf := [], depth := 0, live := true }))) (head :: tail) = stateWord R (R.scanFinal (head :: tail)) R:RankedAlphabetw:List Boolb:Boolv:List Boolih:List.foldr (scanStepWord (rankedStep R false) (rankedStep R true)) (baseWord (constAtOf 0 (stateWord R { buf := [], depth := 0, live := true }))) v = stateWord R (R.scanFinal v)List.foldr (scanStepWord (rankedStep R false) (rankedStep R true)) (baseWord (constAtOf 0 (stateWord R { buf := [], depth := 0, live := true }))) (b :: v) = stateWord R (R.scanFinal (b :: v)) R:RankedAlphabetw:List Boolb:Boolv:List Boolih:List.foldr (scanStepWord (rankedStep R false) (rankedStep R true)) (baseWord (constAtOf 0 (stateWord R { buf := [], depth := 0, live := true }))) v = stateWord R (R.scanFinal v)scanStepWord (rankedStep R false) (rankedStep R true) b (stateWord R (R.scanFinal v)) = stateWord R (R.scanStep b (R.scanFinal v)) R:RankedAlphabetw:List Boolv:List Boolih:List.foldr (scanStepWord (rankedStep R false) (rankedStep R true)) (baseWord (constAtOf 0 (stateWord R { buf := [], depth := 0, live := true }))) v = stateWord R (R.scanFinal v)scanStepWord (rankedStep R false) (rankedStep R true) false (stateWord R (R.scanFinal v)) = stateWord R (R.scanStep false (R.scanFinal v))R:RankedAlphabetw:List Boolv:List Boolih:List.foldr (scanStepWord (rankedStep R false) (rankedStep R true)) (baseWord (constAtOf 0 (stateWord R { buf := [], depth := 0, live := true }))) v = stateWord R (R.scanFinal v)scanStepWord (rankedStep R false) (rankedStep R true) true (stateWord R (R.scanFinal v)) = stateWord R (R.scanStep true (R.scanFinal v)) R:RankedAlphabetw:List Boolv:List Boolih:List.foldr (scanStepWord (rankedStep R false) (rankedStep R true)) (baseWord (constAtOf 0 (stateWord R { buf := [], depth := 0, live := true }))) v = stateWord R (R.scanFinal v)scanStepWord (rankedStep R false) (rankedStep R true) false (stateWord R (R.scanFinal v)) = stateWord R (R.scanStep false (R.scanFinal v)) All goals completed! 🐙 R:RankedAlphabetw:List Boolv:List Boolih:List.foldr (scanStepWord (rankedStep R false) (rankedStep R true)) (baseWord (constAtOf 0 (stateWord R { buf := [], depth := 0, live := true }))) v = stateWord R (R.scanFinal v)scanStepWord (rankedStep R false) (rankedStep R true) true (stateWord R (R.scanFinal v)) = stateWord R (R.scanStep true (R.scanFinal v)) All goals completed! 🐙

The value never exceeds the input by more than the state's fixed part, so the scanner's recursion bound holds at growth R.width + 1. Stated at scanSem, which is the form Cobham.scan consumes. At the empty word the bound is tight.

theorem length_rankedSem_le (R : RankedAlphabet) (w : List Bool) : (scanSem (constAtOf 0 (stateWord R [], 0, true)) (rankedStep R false) (rankedStep R true) (R.width + 1) ![w]).length w.length + (R.width + 1) := R:RankedAlphabetw:List Bool(scanSem (constAtOf 0 (stateWord R { buf := [], depth := 0, live := true })) (rankedStep R false) (rankedStep R true) (R.width + 1) ![w]).length w.length + (R.width + 1) R:RankedAlphabetw:List Boolhlen:(stateWord R (R.scanFinal w)).length = 1 + R.width + (R.scanFinal w).depth(scanSem (constAtOf 0 (stateWord R { buf := [], depth := 0, live := true })) (rankedStep R false) (rankedStep R true) (R.width + 1) ![w]).length w.length + (R.width + 1) R:RankedAlphabetw:List Boolhlen:(stateWord R (R.scanFinal w)).length = 1 + R.width + (R.scanFinal w).depthhdepth:(R.scanFinal w).depth w.length(scanSem (constAtOf 0 (stateWord R { buf := [], depth := 0, live := true })) (rankedStep R false) (rankedStep R true) (R.width + 1) ![w]).length w.length + (R.width + 1) R:RankedAlphabetw:List Boolhlen:(stateWord R (R.scanFinal w)).length = 1 + R.width + (R.scanFinal w).depthhdepth:(R.scanFinal w).depth w.length1 + R.width + (R.scanFinal w).depth w.length + (R.width + 1) All goals completed! 🐙

The scan as an expression of the class, its recursion bound discharged by length_rankedSem_le.

@[`@[expose]` has no effect outside a `module` fileexpose] def ranked (R : RankedAlphabet) : C := scan (constAtOf 0 (stateWord R [], 0, true)) (rankedStep R false) (rankedStep R true) (R.width + 1) (length_rankedSem_le R)

ranked at its declared arity.

@[`@[expose]` has no effect outside a `module` fileexpose] def rankedOf (R : RankedAlphabet) : COf 1 := scanOf (constAtOf 0 (stateWord R [], 0, true)) (rankedStep R false) (rankedStep R true) (R.width + 1) (length_rankedSem_le R)

The meaning rankedSem reads at the raw tree is the meaning ranked carries.

theorem rankedSem_eq_eval (R : RankedAlphabet) : transport (rankedOf R).2 (rankedOf R).1.eval = rankedSem R := scanSem_eq_eval (constAtOf 0 (stateWord R [], 0, true)) (rankedStep R false) (rankedStep R true) (R.width + 1) (length_rankedSem_le R)

The accepting state's word: live, no incomplete block, one pending subterm.

@[`@[expose]` has no effect outside a `module` fileexpose] def acceptWord (R : RankedAlphabet) : List Bool := stateWord R [], 1, true

The verdict window separates the accepting state from every other state whose block is short of the width. It reads one bit past the accepting word, so a pending count above one is rejected.

theorem ofFn_bits_stateWord_eq_iff (R : RankedAlphabet) (s : Scan) (h : s.buf.length < R.width) : List.ofFn (bits (R.width + 3) (stateWord R s)) = acceptWord R ++ [false] (s.live = true s.buf = [] s.depth = 1) := R:RankedAlphabets:Scanh:s.buf.length < R.widthList.ofFn (bits (R.width + 3) (stateWord R s)) = acceptWord R ++ [false] s.live = true s.buf = [] s.depth = 1 R:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthList.ofFn (bits (R.width + 3) (stateWord R s)) = acceptWord R ++ [false] s.live = true s.buf = [] s.depth = 1 R:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhnil:(bufBits R []).length = R.widthList.ofFn (bits (R.width + 3) (stateWord R s)) = acceptWord R ++ [false] s.live = true s.buf = [] s.depth = 1 R:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhnil:(bufBits R []).length = R.widthhleft:List.ofFn (bits (R.width + 3) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false))List.ofFn (bits (R.width + 3) (stateWord R s)) = acceptWord R ++ [false] s.live = true s.buf = [] s.depth = 1 R:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhnil:(bufBits R []).length = R.widthhleft:List.ofFn (bits (R.width + 3) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false))hright:acceptWord R ++ [false] = true :: (bufBits R [] ++ ([true] ++ [false]))List.ofFn (bits (R.width + 3) (stateWord R s)) = acceptWord R ++ [false] s.live = true s.buf = [] s.depth = 1 R:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhnil:(bufBits R []).length = R.widthhleft:List.ofFn (bits (R.width + 3) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false))hright:acceptWord R ++ [false] = true :: (bufBits R [] ++ ([true] ++ [false]))s.live :: (bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false)) = true :: (bufBits R [] ++ ([true] ++ [false])) s.live = true s.buf = [] s.depth = 1 R:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhnil:(bufBits R []).length = R.widthhleft:List.ofFn (bits (R.width + 3) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false))hright:acceptWord R ++ [false] = true :: (bufBits R [] ++ ([true] ++ [false]))s.live :: (bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false)) = true :: (bufBits R [] ++ ([true] ++ [false])) s.live = true s.buf = [] s.depth = 1R:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhnil:(bufBits R []).length = R.widthhleft:List.ofFn (bits (R.width + 3) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false))hright:acceptWord R ++ [false] = true :: (bufBits R [] ++ ([true] ++ [false]))s.live = true s.buf = [] s.depth = 1 s.live :: (bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false)) = true :: (bufBits R [] ++ ([true] ++ [false])) R:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhnil:(bufBits R []).length = R.widthhleft:List.ofFn (bits (R.width + 3) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false))hright:acceptWord R ++ [false] = true :: (bufBits R [] ++ ([true] ++ [false]))s.live :: (bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false)) = true :: (bufBits R [] ++ ([true] ++ [false])) s.live = true s.buf = [] s.depth = 1 R:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhnil:(bufBits R []).length = R.widthhleft:List.ofFn (bits (R.width + 3) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false))hright:acceptWord R ++ [false] = true :: (bufBits R [] ++ ([true] ++ [false]))heq:s.live :: (bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false)) = true :: (bufBits R [] ++ ([true] ++ [false]))s.live = true s.buf = [] s.depth = 1 R:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhnil:(bufBits R []).length = R.widthhleft:List.ofFn (bits (R.width + 3) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false))hright:acceptWord R ++ [false] = true :: (bufBits R [] ++ ([true] ++ [false]))hhead:s.live = truehtail:bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false) = bufBits R [] ++ ([true] ++ [false])s.live = true s.buf = [] s.depth = 1 R:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhnil:(bufBits R []).length = R.widthhleft:List.ofFn (bits (R.width + 3) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false))hright:acceptWord R ++ [false] = true :: (bufBits R [] ++ ([true] ++ [false]))hhead:s.live = truehtail:bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false) = bufBits R [] ++ ([true] ++ [false])hlen:(bufBits R s.buf).length = (bufBits R []).lengths.live = true s.buf = [] s.depth = 1 R:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhnil:(bufBits R []).length = R.widthhleft:List.ofFn (bits (R.width + 3) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false))hright:acceptWord R ++ [false] = true :: (bufBits R [] ++ ([true] ++ [false]))hhead:s.live = truehtail:bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false) = bufBits R [] ++ ([true] ++ [false])hlen:(bufBits R s.buf).length = (bufBits R []).lengthhslot:bufBits R s.buf = bufBits R []hrest:List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false = [true] ++ [false]s.live = true s.buf = [] s.depth = 1 R:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhnil:(bufBits R []).length = R.widthhleft:List.ofFn (bits (R.width + 3) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false))hright:acceptWord R ++ [false] = true :: (bufBits R [] ++ ([true] ++ [false]))hhead:s.live = truehtail:bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false) = bufBits R [] ++ ([true] ++ [false])hlen:(bufBits R s.buf).length = (bufBits R []).lengthhslot:bufBits R s.buf = bufBits R []hrest:List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false = [true] ++ [false]hbufnil:s.buf = []s.live = true s.buf = [] s.depth = 1 R:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhnil:(bufBits R []).length = R.widthhleft:List.ofFn (bits (R.width + 3) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false))hright:acceptWord R ++ [false] = true :: (bufBits R [] ++ ([true] ++ [false]))hhead:s.live = truehtail:bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false) = bufBits R [] ++ ([true] ++ [false])hlen:(bufBits R s.buf).length = (bufBits R []).lengthhslot:bufBits R s.buf = bufBits R []hrest:List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false = [true] ++ [false]hbufnil:s.buf = []s.depth = 1 match hdep : s.depth with R:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhnil:(bufBits R []).length = R.widthhleft:List.ofFn (bits (R.width + 3) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false))hright:acceptWord R ++ [false] = true :: (bufBits R [] ++ ([true] ++ [false]))hhead:s.live = truehtail:bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false) = bufBits R [] ++ ([true] ++ [false])hlen:(bufBits R s.buf).length = (bufBits R []).lengthhslot:bufBits R s.buf = bufBits R []hrest:List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false = [true] ++ [false]hbufnil:s.buf = []hdep:s.depth = 00 = 1 R:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhnil:(bufBits R []).length = R.widthhleft:List.ofFn (bits (R.width + 3) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false))hright:acceptWord R ++ [false] = true :: (bufBits R [] ++ ([true] ++ [false]))hhead:s.live = truehtail:bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false) = bufBits R [] ++ ([true] ++ [false])hlen:(bufBits R s.buf).length = (bufBits R []).lengthhslot:bufBits R s.buf = bufBits R []hrest:List.replicate (min 2 0) true ++ List.replicate (2 - 0) false = [true] ++ [false]hbufnil:s.buf = []hdep:s.depth = 00 = 1 exact absurd hrest (R:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhnil:(bufBits R []).length = R.widthhleft:List.ofFn (bits (R.width + 3) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false))hright:acceptWord R ++ [false] = true :: (bufBits R [] ++ ([true] ++ [false]))hhead:s.live = truehtail:bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false) = bufBits R [] ++ ([true] ++ [false])hlen:(bufBits R s.buf).length = (bufBits R []).lengthhslot:bufBits R s.buf = bufBits R []hrest:List.replicate (min 2 0) true ++ List.replicate (2 - 0) false = [true] ++ [false]hbufnil:s.buf = []hdep:s.depth = 0¬List.replicate (min 2 0) true ++ List.replicate (2 - 0) false = [true] ++ [false] All goals completed! 🐙) R:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhnil:(bufBits R []).length = R.widthhleft:List.ofFn (bits (R.width + 3) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false))hright:acceptWord R ++ [false] = true :: (bufBits R [] ++ ([true] ++ [false]))hhead:s.live = truehtail:bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false) = bufBits R [] ++ ([true] ++ [false])hlen:(bufBits R s.buf).length = (bufBits R []).lengthhslot:bufBits R s.buf = bufBits R []hrest:List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false = [true] ++ [false]hbufnil:s.buf = []hdep:s.depth = 11 = 1 All goals completed! 🐙 R:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhnil:(bufBits R []).length = R.widthhleft:List.ofFn (bits (R.width + 3) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false))hright:acceptWord R ++ [false] = true :: (bufBits R [] ++ ([true] ++ [false]))hhead:s.live = truehtail:bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false) = bufBits R [] ++ ([true] ++ [false])hlen:(bufBits R s.buf).length = (bufBits R []).lengthhslot:bufBits R s.buf = bufBits R []hrest:List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false = [true] ++ [false]hbufnil:s.buf = []n:hdep:s.depth = n.succ.succn + 2 = 1 R:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhnil:(bufBits R []).length = R.widthhleft:List.ofFn (bits (R.width + 3) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false))hright:acceptWord R ++ [false] = true :: (bufBits R [] ++ ([true] ++ [false]))hhead:s.live = truehtail:bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false) = bufBits R [] ++ ([true] ++ [false])hlen:(bufBits R s.buf).length = (bufBits R []).lengthhslot:bufBits R s.buf = bufBits R []hbufnil:s.buf = []n:hrest:List.replicate 2 true ++ List.replicate 0 false = [true] ++ [false]hdep:s.depth = n.succ.succn + 2 = 1 exact absurd hrest (R:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhnil:(bufBits R []).length = R.widthhleft:List.ofFn (bits (R.width + 3) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false))hright:acceptWord R ++ [false] = true :: (bufBits R [] ++ ([true] ++ [false]))hhead:s.live = truehtail:bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false) = bufBits R [] ++ ([true] ++ [false])hlen:(bufBits R s.buf).length = (bufBits R []).lengthhslot:bufBits R s.buf = bufBits R []hbufnil:s.buf = []n:hrest:List.replicate 2 true ++ List.replicate 0 false = [true] ++ [false]hdep:s.depth = n.succ.succ¬List.replicate 2 true ++ List.replicate 0 false = [true] ++ [false] All goals completed! 🐙) R:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhnil:(bufBits R []).length = R.widthhleft:List.ofFn (bits (R.width + 3) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false))hright:acceptWord R ++ [false] = true :: (bufBits R [] ++ ([true] ++ [false]))s.live = true s.buf = [] s.depth = 1 s.live :: (bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false)) = true :: (bufBits R [] ++ ([true] ++ [false])) R:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhnil:(bufBits R []).length = R.widthhleft:List.ofFn (bits (R.width + 3) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false))hright:acceptWord R ++ [false] = true :: (bufBits R [] ++ ([true] ++ [false]))hs:s.live = true s.buf = [] s.depth = 1s.live :: (bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false)) = true :: (bufBits R [] ++ ([true] ++ [false])) R:RankedAlphabets:Scanh:s.buf.length < R.widthhbuf:(bufBits R s.buf).length = R.widthhnil:(bufBits R []).length = R.widthhleft:List.ofFn (bits (R.width + 3) (stateWord R s)) = s.live :: (bufBits R s.buf ++ (List.replicate (min 2 s.depth) true ++ List.replicate (2 - s.depth) false))hright:acceptWord R ++ [false] = true :: (bufBits R [] ++ ([true] ++ [false]))hs:s.live = true s.buf = [] s.depth = 1true :: (bufBits R [] ++ (List.replicate (min 2 1) true ++ List.replicate (2 - 1) false)) = true :: (bufBits R [] ++ ([true] ++ [false])) All goals completed! 🐙

The verdict test: the branch at the accepting window returns [true], and every other branch the empty bitstring. The decision is taken on List Bool, whose DecidableEq depends on no axiom, rather than on Fin (R.width + 3) → Bool, whose instance routes through Fintype.decidablePiFintype and Classical.choice.

@[`@[expose]` has no effect outside a `module` fileexpose] def acceptTest (R : RankedAlphabet) : COf 1 := diagOf (casesOf (R.width + 3) fun v if List.ofFn v = acceptWord R ++ [false] then constAtOf 1 [true] else constAtOf 1 [])

The verdict test's value at the state it reads.

theorem stepWord_acceptTest (R : RankedAlphabet) (u : List Bool) : stepWord (acceptTest R) u = if List.ofFn (bits (R.width + 3) u) = acceptWord R ++ [false] then [true] else [] := R:RankedAlphabetu:List BoolstepWord (acceptTest R) u = if List.ofFn (bits (R.width + 3) u) = acceptWord R ++ [false] then [true] else [] R:RankedAlphabetu:List BoolsemAt 2 (casesOf (R.width + 3) fun v if List.ofFn v = acceptWord R ++ [false] then constAtOf 1 [true] else constAtOf 1 []) ![u, u] = if List.ofFn (bits (R.width + 3) u) = acceptWord R ++ [false] then [true] else [] R:RankedAlphabetu:List BoolcasesSem (R.width + 3) (fun v if List.ofFn v = acceptWord R ++ [false] then constAtOf 1 [true] else constAtOf 1 []) ![u, u] = if List.ofFn (bits (R.width + 3) u) = acceptWord R ++ [false] then [true] else [] R:RankedAlphabetu:List BoolstepWord (if List.ofFn (bits (R.width + 3) u) = acceptWord R ++ [false] then constAtOf 1 [true] else constAtOf 1 []) u = if List.ofFn (bits (R.width + 3) u) = acceptWord R ++ [false] then [true] else [] R:RankedAlphabetu:List Boolhb:List.ofFn (bits (R.width + 3) u) = acceptWord R ++ [false]stepWord (if List.ofFn (bits (R.width + 3) u) = acceptWord R ++ [false] then constAtOf 1 [true] else constAtOf 1 []) u = if List.ofFn (bits (R.width + 3) u) = acceptWord R ++ [false] then [true] else []R:RankedAlphabetu:List Boolhb:¬List.ofFn (bits (R.width + 3) u) = acceptWord R ++ [false]stepWord (if List.ofFn (bits (R.width + 3) u) = acceptWord R ++ [false] then constAtOf 1 [true] else constAtOf 1 []) u = if List.ofFn (bits (R.width + 3) u) = acceptWord R ++ [false] then [true] else [] R:RankedAlphabetu:List Boolhb:List.ofFn (bits (R.width + 3) u) = acceptWord R ++ [false]stepWord (if List.ofFn (bits (R.width + 3) u) = acceptWord R ++ [false] then constAtOf 1 [true] else constAtOf 1 []) u = if List.ofFn (bits (R.width + 3) u) = acceptWord R ++ [false] then [true] else [] All goals completed! 🐙 R:RankedAlphabetu:List Boolhb:¬List.ofFn (bits (R.width + 3) u) = acceptWord R ++ [false]stepWord (if List.ofFn (bits (R.width + 3) u) = acceptWord R ++ [false] then constAtOf 1 [true] else constAtOf 1 []) u = if List.ofFn (bits (R.width + 3) u) = acceptWord R ++ [false] then [true] else [] All goals completed! 🐙

The raw tree of the recognizer: the verdict test on the scan.

@[`@[expose]` has no effect outside a `module` fileexpose] def isRankedRaw (R : RankedAlphabet) : sig.toPFunctor.W := WType.mk (.comp 1 1) fun d match d with | .inl () => (acceptTest R).1.1.1 | .inr _ => (rankedOf R).1.1.1

The recognizer's tree is admissible, from its two components'. decide does not apply: at a symbolic alphabet nothing reduces, so the pair of a case analysis and the index condition's funext is written out.

theorem wValid_isRankedRaw (R : RankedAlphabet) : sig.WValid (isRankedRaw R) := fun d match d with | .inl () => (acceptTest R).1.1.2 | .inr _ => (rankedOf R).1.1.2, funext fun d match d with | .inl () => (sig.wIndexValid_index_eq_wIndexRoot _).trans (acceptTest R).2 | .inr _ => (sig.wIndexValid_index_eq_wIndexRoot _).trans (rankedOf R).2

The recognizer as an expression of the class: whether a bitstring spells a term of the alphabet.

@[`@[expose]` has no effect outside a `module` fileexpose] def isRanked (R : RankedAlphabet) : C := isRankedRaw R, wValid_isRankedRaw R, trivial, fun d match d with | .inl () => (acceptTest R).1.2 | .inr _ => (rankedOf R).1.2

isRanked at its declared arity.

@[`@[expose]` has no effect outside a `module` fileexpose] def isRankedOf (R : RankedAlphabet) : COf 1 := isRanked R, rfl

The recognizer's meaning at its arity, read at the raw tree.

@[`@[expose]` has no effect outside a `module` fileexpose] def isRankedSem (R : RankedAlphabet) : Sem 1 := semAt 1 isRankedRaw R, wValid_isRankedRaw R rfl

The meaning isRankedSem reads at the raw tree is the meaning isRanked carries.

theorem isRankedSem_eq_eval (R : RankedAlphabet) : transport (isRankedOf R).2 (isRankedOf R).1.eval = isRankedSem R := rfl

One step of the recognizer: the verdict test on the scan's value. The composition applies its head at fun _ : Fin 1 ↦ r while stepWord applies it at ![r], and the two agree only by funext.

theorem isRankedSem_apply (R : RankedAlphabet) (w : List Bool) : isRankedSem R ![w] = stepWord (acceptTest R) (rankedSem R ![w]) := congrArg (semAt 1 (acceptTest R).1.1 (acceptTest R).2) (funext fun i match i with | 0, _ => rfl)

The recognizer's value on both branches: a rejected word receives the empty bitstring, not merely something other than [true].

theorem isRankedSem_eq_ite (R : RankedAlphabet) (w : List Bool) : isRankedSem R ![w] = if R.Valid w then [true] else [] := R:RankedAlphabetw:List BoolisRankedSem R ![w] = if R.Valid w then [true] else [] R:RankedAlphabetw:List Boolhsep:List.ofFn (bits (R.width + 3) (stateWord R (R.scanFinal w))) = acceptWord R ++ [false] (R.scanFinal w).live = true (R.scanFinal w).buf = [] (R.scanFinal w).depth = 1isRankedSem R ![w] = if R.Valid w then [true] else [] R:RankedAlphabetw:List Boolhsep:List.ofFn (bits (R.width + 3) (stateWord R (R.scanFinal w))) = acceptWord R ++ [false] (R.scanFinal w).live = true (R.scanFinal w).buf = [] (R.scanFinal w).depth = 1(if List.ofFn (bits (R.width + 3) (stateWord R (R.scanFinal w))) = acceptWord R ++ [false] then [true] else []) = if R.Valid w then [true] else [] R:RankedAlphabetw:List Boolhsep:List.ofFn (bits (R.width + 3) (stateWord R (R.scanFinal w))) = acceptWord R ++ [false] (R.scanFinal w).live = true (R.scanFinal w).buf = [] (R.scanFinal w).depth = 1hv:R.Valid w(if List.ofFn (bits (R.width + 3) (stateWord R (R.scanFinal w))) = acceptWord R ++ [false] then [true] else []) = if R.Valid w then [true] else []R:RankedAlphabetw:List Boolhsep:List.ofFn (bits (R.width + 3) (stateWord R (R.scanFinal w))) = acceptWord R ++ [false] (R.scanFinal w).live = true (R.scanFinal w).buf = [] (R.scanFinal w).depth = 1hv:¬R.Valid w(if List.ofFn (bits (R.width + 3) (stateWord R (R.scanFinal w))) = acceptWord R ++ [false] then [true] else []) = if R.Valid w then [true] else [] R:RankedAlphabetw:List Boolhsep:List.ofFn (bits (R.width + 3) (stateWord R (R.scanFinal w))) = acceptWord R ++ [false] (R.scanFinal w).live = true (R.scanFinal w).buf = [] (R.scanFinal w).depth = 1hv:R.Valid w(if List.ofFn (bits (R.width + 3) (stateWord R (R.scanFinal w))) = acceptWord R ++ [false] then [true] else []) = if R.Valid w then [true] else [] All goals completed! 🐙 R:RankedAlphabetw:List Boolhsep:List.ofFn (bits (R.width + 3) (stateWord R (R.scanFinal w))) = acceptWord R ++ [false] (R.scanFinal w).live = true (R.scanFinal w).buf = [] (R.scanFinal w).depth = 1hv:¬R.Valid w(if List.ofFn (bits (R.width + 3) (stateWord R (R.scanFinal w))) = acceptWord R ++ [false] then [true] else []) = if R.Valid w then [true] else [] All goals completed! 🐙

The recognizer accepts exactly the words spelling a term.

theorem isRankedSem_eq_singleton_iff_valid (R : RankedAlphabet) (w : List Bool) : isRankedSem R ![w] = [true] R.Valid w := R:RankedAlphabetw:List BoolisRankedSem R ![w] = [true] R.Valid w R:RankedAlphabetw:List Bool(if R.Valid w then [true] else []) = [true] R.Valid w R:RankedAlphabetw:List Boolhv:R.Valid w(if R.Valid w then [true] else []) = [true] R.Valid wR:RankedAlphabetw:List Boolhv:¬R.Valid w(if R.Valid w then [true] else []) = [true] R.Valid w R:RankedAlphabetw:List Boolhv:R.Valid w(if R.Valid w then [true] else []) = [true] R.Valid w R:RankedAlphabetw:List Boolhv:R.Valid w[true] = [true] R.Valid w All goals completed! 🐙 R:RankedAlphabetw:List Boolhv:¬R.Valid w(if R.Valid w then [true] else []) = [true] R.Valid w R:RankedAlphabetw:List Boolhv:¬R.Valid w[] = [true] R.Valid w exact fun hw absurd hw (R:RankedAlphabetw:List Boolhv:¬R.Valid whw:[] = [true]¬[] = [true] All goals completed! 🐙), fun h absurd h hv

At the two-symbol alphabet the generic recognizer accepts the language the recognizer of Cobham/Tree.lean accepts. Both links relate semantic predicates on List Bool, and both name one scan, so neither binRanked's width and maxArity nor a pair of failure conventions need reconciling.

theorem isRankedSem_binRanked_eq_singleton_iff_isTreeSem (w : List Bool) : isRankedSem RankedAlphabet.Binary.binRanked ![w] = [true] isTreeSem ![w] = [true] := (isRankedSem_eq_singleton_iff_valid _ w).trans (isTreeSem_eq_singleton_iff_valid w).symm
endend Cobham