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.Data.Tree.Ranked.Code public import Mathlib.Algebra.BigOperators.Ring.List public import Mathlib.Computability.Encoding

The preorder encoding of ranked terms

A symbol is spelled by its block followed by its children's spellings, in index order. The encoding is a bijection onto the words a single right-to-left scan accepts, the scan carrying an incomplete block, the count of pending subterms and a liveness flag.

The idea is that of prefix notation, in which a symbol is followed by exactly as many operands as its arity. RankedAlphabet.Binary is the case of one symbol of arity zero and one of arity two.

Validity is stated as three conditions, in the manner of mathlib's DyckWord, whose fields count_U_eq_count_D and count_D_le_count_U play the roles the pending count and the liveness flag play here, and in the direction a single right-to-left pass carrying a counter can scan. valid_iff_scanFinal adds a third, that the incomplete block is empty: at a general width that condition is not implied by the other two, so stating validity as only the first two, as DyckWord does, would be false here.

A boundedRec of a Cobham-style function algebra processes a list from its far end, so in that reading a symbol's block is read before the blocks of its children and the symbol is applied after them: prefix notation in list order is postfix notation in processing order.

Main definitions

    RankedAlphabet.spell — the encoding.

    RankedAlphabet.decodeBlock, RankedAlphabet.parseChildren, RankedAlphabet.parseStep, RankedAlphabet.parseAux, RankedAlphabet.parse — the fuel-bounded recursive-descent decoding.

    RankedAlphabet.encoding — the two as a Computability.Encoding.

    RankedAlphabet.Scan, RankedAlphabet.scanStep, RankedAlphabet.scanFrom, RankedAlphabet.scanFinal — the scan.

    RankedAlphabet.validBool, RankedAlphabet.Valid — what it accepts.

    DecidablePred RankedAlphabet.Valid — the instance deciding it.

Main statements

    RankedAlphabet.parse_spell — the retraction law.

    RankedAlphabet.parse_eq_some_iff — the decoding inverts the encoding.

    RankedAlphabet.spell_injective — distinct terms have distinct spellings.

    RankedAlphabet.valid_spell — every spelling is valid.

    RankedAlphabet.valid_iff_exists_spell — the valid words are exactly the spellings.

    RankedAlphabet.valid_iff_isSome_parse — the descent decides validity.

    RankedAlphabet.length_buf_scanFinal_of_live — a live scan's incomplete block holds the word's length modulo the width.

    RankedAlphabet.length_buf_scanFinal_lt — the incomplete block never fills.

    RankedAlphabet.depth_scanFinal_le_length — the pending count is at most the word's length.

    RankedAlphabet.valid_iff_scanFinal — validity as three conditions on the final state.

Implementation notes

parseAux recurses on an explicit bound rather than on its input: each child is parsed from a remainder the previous call computes, which is not a structural subterm. parse supplies the input's length, and length_spell with width_pos shows that bound admits every word spell emits.

Fuel exhaustion is not a rejection mechanism of its own. Each parseStep layer consumes a whole block, which width_pos makes at least one bit, so the invariant that the fuel is at least the remaining length holds from parse's initial w.length down to wherever the descent stops. The descent's own rejections are decodeBlock's two — the input falls short of a block, or the block spells no symbol — together with a child's failure and the trailing input parse rejects.

parseChildren is a Nat.rec and decodeBits a List.rec, so neither has generated equation lemmas; parseChildren_succ and decodeBits_cons are stated for the rewrites that need them.

scanStep matches on Bool values and Valid is a Bool equation rather than an equation of Scan. Both are required by kernel reduction: an equation of Scan would be decided through a derived DecidableEq, which at a symbolic fold leaves decide stuck on the instance rather than reducing it, so Scan derives none. A decidable test is not itself the obstruction, as decodeBlock shows by branching on one and reducing.

exists_spell_append_of_live_of_buf_nil_of_one_le_depth is likewise bounded by an explicit and driven by Nat.rec. Its step applies the hypothesis once per child of the head symbol, through exists_children_append_of_le_depth, which takes that hypothesis as an argument; every use sits at the same bound, so no well-founded recursion is needed. The step splits off the word's leading block rather than its trailing one: spell is prefix notation while the scan reads right to left, so the head symbol's block is read last, from the state the scan of everything after it leaves.

The base case ascribes w.length ≤ 0 to hzero before appealing to omega: Nat.rec's base case presents the bound as w.length ≤ Nat.zero, and omega treats the unreduced Nat.zero as an opaque atom, so the ascription at the literal 0 is what makes the hypothesis usable.

spell_injective is derived from Computability.Encoding.encode_injective through encoding rather than proved directly, the encoding and its descent being exactly that structure's three fields.

Tags

ranked alphabet, preorder, prefix notation, encoding, retraction, scan

namespace RankedAlphabetpublic section

The preorder encoding: a symbol's block followed by its children's spellings, in index order.

@[`@[expose]` has no effect outside a `module` fileexpose] def spell (R : RankedAlphabet) : R.Term List Bool := WType.elim (List Bool) fun x R.code x.1 ++ (List.ofFn x.2).flatten
@[simp] theorem spell_mk (R : RankedAlphabet) (i : Fin R.card) (ch : Fin (R.arity i) R.Term) : R.spell (Term.mk R i ch) = R.code i ++ (List.ofFn fun d R.spell (ch d)).flatten := rfl

A spelling's length is the alphabet's width times the term's node count, so the input length is fuel enough for the descent to read anything spell emits.

theorem length_spell (R : RankedAlphabet) (t : R.Term) : (R.spell t).length = R.width * t.size := Term.induction (motive := fun t (R.spell t).length = R.width * t.size) (fun i ch ih R:RankedAlphabett:R.Termi:Fin R.cardch:Fin (R.arity i) R.Termih: (d : Fin (R.arity i)), (R.spell (ch d)).length = R.width * (ch d).size(R.spell (Term.mk R i ch)).length = R.width * (Term.mk R i ch).size R:RankedAlphabett:R.Termi:Fin R.cardch:Fin (R.arity i) R.Termih: (d : Fin (R.arity i)), (R.spell (ch d)).length = R.width * (ch d).sizeR.width + (List.ofFn fun d R.spell (ch d)).flatten.length = R.width + R.width * (List.ofFn fun d (ch d).size).sum R:RankedAlphabett:R.Termi:Fin R.cardch:Fin (R.arity i) R.Termih: (d : Fin (R.arity i)), (R.spell (ch d)).length = R.width * (ch d).size(List.ofFn fun d R.spell (ch d)).flatten.length = R.width * (List.ofFn fun d (ch d).size).sum R:RankedAlphabett:R.Termi:Fin R.cardch:Fin (R.arity i) R.Termih: (d : Fin (R.arity i)), (R.spell (ch d)).length = R.width * (ch d).size(List.ofFn (List.length fun d R.spell (ch d))).sum = R.width * (List.ofFn fun d (ch d).size).sum R:RankedAlphabett:R.Termi:Fin R.cardch:Fin (R.arity i) R.Termih: (d : Fin (R.arity i)), (R.spell (ch d)).length = R.width * (ch d).size(List.ofFn fun x R.width * (ch x).size).sum = R.width * (List.ofFn fun d (ch d).size).sum All goals completed! 🐙) t

Read one block: the symbol it spells and the unconsumed remainder, absent when the word is short of a block or the block spells no symbol.

@[`@[expose]` has no effect outside a `module` fileexpose] def decodeBlock (R : RankedAlphabet) (w : List Bool) : Option (Fin R.card × List Bool) := if h : decodeBits (w.take R.width) < R.card R.width w.length then some (decodeBits (w.take R.width), h.1, w.drop R.width) else none

Read n children in index order, delegating each to child.

@[`@[expose]` has no effect outside a `module` fileexpose] def parseChildren {R : RankedAlphabet} (child : List Bool Option (R.Term × List Bool)) : (n : ) List Bool Option ((Fin n R.Term) × List Bool) := Nat.rec (fun w some (Fin.elim0, w)) fun _ ih w match child w with | none => none | some (t, w₁) => match ih w₁ with | none => none | some (f, w₂) => some (Fin.cons t f, w₂)

parseChildren unfolded on a positive count. parseChildren is a bare Nat.rec, for which Lean generates no equation lemma.

theorem parseChildren_succ {R : RankedAlphabet} (child : List Bool Option (R.Term × List Bool)) (n : ) (w : List Bool) : parseChildren child (n + 1) w = (match child w with | none => none | some (t, w₁) => match parseChildren child n w₁ with | none => none | some (f, w₂) => some (Fin.cons t f, w₂)) := rfl

One layer of the recursive descent: read one block, then as many children as its symbol's arity.

@[`@[expose]` has no effect outside a `module` fileexpose] def parseStep (R : RankedAlphabet) (child : List Bool Option (R.Term × List Bool)) (w : List Bool) : Option (R.Term × List Bool) := match R.decodeBlock w with | none => none | some (i, rest) => match parseChildren child (R.arity i) rest with | none => none | some (f, rest') => some (Term.mk R i f, rest')

Recursive descent bounded by an explicit .

@[`@[expose]` has no effect outside a `module` fileexpose] def parseAux (R : RankedAlphabet) : List Bool Option (R.Term × List Bool) := Nat.rec (fun _ none) fun _ ih R.parseStep ih
theorem parseAux_succ (R : RankedAlphabet) (f : ) : R.parseAux (f + 1) = R.parseStep (R.parseAux f) := rfl

The decoding, rejecting trailing input.

@[`@[expose]` has no effect outside a `module` fileexpose] def parse (R : RankedAlphabet) (w : List Bool) : Option R.Term := match R.parseAux w.length w with | some (t, []) => some t | _ => none

A block followed by anything is read as its own symbol, leaving what follows.

theorem decodeBlock_code_append (R : RankedAlphabet) (i : Fin R.card) (rest : List Bool) : R.decodeBlock (R.code i ++ rest) = some (i, rest) := R:RankedAlphabeti:Fin R.cardrest:List BoolR.decodeBlock (R.code i ++ rest) = some (i, rest) R:RankedAlphabeti:Fin R.cardrest:List Boolhtake:List.take R.width (R.code i ++ rest) = R.code iR.decodeBlock (R.code i ++ rest) = some (i, rest) R:RankedAlphabeti:Fin R.cardrest:List Boolhtake:List.take R.width (R.code i ++ rest) = R.code ihdrop:List.drop R.width (R.code i ++ rest) = restR.decodeBlock (R.code i ++ rest) = some (i, rest) R:RankedAlphabeti:Fin R.cardrest:List Boolhtake:List.take R.width (R.code i ++ rest) = R.code ihdrop:List.drop R.width (R.code i ++ rest) = resthlen:R.width (R.code i ++ rest).lengthR.decodeBlock (R.code i ++ rest) = some (i, rest) R:RankedAlphabeti:Fin R.cardrest:List Boolhtake:List.take R.width (R.code i ++ rest) = R.code ihdrop:List.drop R.width (R.code i ++ rest) = resthlen:R.width (R.code i ++ rest).lengthsome (decodeBits (R.code i), , rest) = some (i, rest) R:RankedAlphabeti:Fin R.cardrest:List Boolhtake:List.take R.width (R.code i ++ rest) = R.code ihdrop:List.drop R.width (R.code i ++ rest) = resthlen:R.width (R.code i ++ rest).length(decodeBits (R.code i), , rest) = (i, rest) All goals completed! 🐙

Reading n children off the concatenation of their spellings returns them and the remainder.

theorem parseChildren_flatten (R : RankedAlphabet) {n : } (ch : Fin n R.Term) (ih : d f rest, (ch d).size f R.parseAux f (R.spell (ch d) ++ rest) = some (ch d, rest)) (f : ) (rest : List Bool) (hf : d, (ch d).size f) : parseChildren (R.parseAux f) n ((List.ofFn fun d R.spell (ch d)).flatten ++ rest) = some (ch, rest) := R:RankedAlphabetn:ch:Fin n R.Termih: (d : Fin n) (f : ) (rest : List Bool), (ch d).size f R.parseAux f (R.spell (ch d) ++ rest) = some (ch d, rest)f:rest:List Boolhf: (d : Fin n), (ch d).size fparseChildren (R.parseAux f) n ((List.ofFn fun d R.spell (ch d)).flatten ++ rest) = some (ch, rest) R:RankedAlphabetn:ch:Fin n R.Termih: (d : Fin n) (f : ) (rest : List Bool), (ch d).size f R.parseAux f (R.spell (ch d) ++ rest) = some (ch d, rest)f:rest:List Boolhf: (d : Fin n), (ch d).size f (ch : Fin Nat.zero R.Term), (∀ (d : Fin Nat.zero) (f' : ) (rest' : List Bool), (ch d).size f' R.parseAux f' (R.spell (ch d) ++ rest') = some (ch d, rest')) (∀ (d : Fin Nat.zero), (ch d).size f) parseChildren (R.parseAux f) Nat.zero ((List.ofFn fun d R.spell (ch d)).flatten ++ rest) = some (ch, rest)R:RankedAlphabetn:ch:Fin n R.Termih: (d : Fin n) (f : ) (rest : List Bool), (ch d).size f R.parseAux f (R.spell (ch d) ++ rest) = some (ch d, rest)f:rest:List Boolhf: (d : Fin n), (ch d).size f (n : ), (∀ (ch : Fin n R.Term), (∀ (d : Fin n) (f' : ) (rest' : List Bool), (ch d).size f' R.parseAux f' (R.spell (ch d) ++ rest') = some (ch d, rest')) (∀ (d : Fin n), (ch d).size f) parseChildren (R.parseAux f) n ((List.ofFn fun d R.spell (ch d)).flatten ++ rest) = some (ch, rest)) (ch : Fin n.succ R.Term), (∀ (d : Fin n.succ) (f' : ) (rest' : List Bool), (ch d).size f' R.parseAux f' (R.spell (ch d) ++ rest') = some (ch d, rest')) (∀ (d : Fin n.succ), (ch d).size f) parseChildren (R.parseAux f) n.succ ((List.ofFn fun d R.spell (ch d)).flatten ++ rest) = some (ch, rest) R:RankedAlphabetn:ch:Fin n R.Termih: (d : Fin n) (f : ) (rest : List Bool), (ch d).size f R.parseAux f (R.spell (ch d) ++ rest) = some (ch d, rest)f:rest:List Boolhf: (d : Fin n), (ch d).size f (ch : Fin Nat.zero R.Term), (∀ (d : Fin Nat.zero) (f' : ) (rest' : List Bool), (ch d).size f' R.parseAux f' (R.spell (ch d) ++ rest') = some (ch d, rest')) (∀ (d : Fin Nat.zero), (ch d).size f) parseChildren (R.parseAux f) Nat.zero ((List.ofFn fun d R.spell (ch d)).flatten ++ rest) = some (ch, rest) R:RankedAlphabetn:ch✝:Fin n R.Termih: (d : Fin n) (f : ) (rest : List Bool), (ch d).size f R.parseAux f (R.spell (ch d) ++ rest) = some (ch d, rest)f:rest:List Boolhf: (d : Fin n), (ch d).size fch:Fin Nat.zero R.Terma✝¹: (d : Fin Nat.zero) (f' : ) (rest' : List Bool), (ch d).size f' R.parseAux f' (R.spell (ch d) ++ rest') = some (ch d, rest')a✝: (d : Fin Nat.zero), (ch d).size fparseChildren (R.parseAux f) Nat.zero ((List.ofFn fun d R.spell (ch d)).flatten ++ rest) = some (ch, rest) R:RankedAlphabetn:ch✝:Fin n R.Termih: (d : Fin n) (f : ) (rest : List Bool), (ch d).size f R.parseAux f (R.spell (ch d) ++ rest) = some (ch d, rest)f:rest:List Boolhf: (d : Fin n), (ch d).size fch:Fin Nat.zero R.Terma✝¹: (d : Fin Nat.zero) (f' : ) (rest' : List Bool), (ch d).size f' R.parseAux f' (R.spell (ch d) ++ rest') = some (ch d, rest')a✝: (d : Fin Nat.zero), (ch d).size fsome (Fin.elim0, rest) = some (ch, rest) All goals completed! 🐙 R:RankedAlphabetn:ch:Fin n R.Termih: (d : Fin n) (f : ) (rest : List Bool), (ch d).size f R.parseAux f (R.spell (ch d) ++ rest) = some (ch d, rest)f:rest:List Boolhf: (d : Fin n), (ch d).size f (n : ), (∀ (ch : Fin n R.Term), (∀ (d : Fin n) (f' : ) (rest' : List Bool), (ch d).size f' R.parseAux f' (R.spell (ch d) ++ rest') = some (ch d, rest')) (∀ (d : Fin n), (ch d).size f) parseChildren (R.parseAux f) n ((List.ofFn fun d R.spell (ch d)).flatten ++ rest) = some (ch, rest)) (ch : Fin n.succ R.Term), (∀ (d : Fin n.succ) (f' : ) (rest' : List Bool), (ch d).size f' R.parseAux f' (R.spell (ch d) ++ rest') = some (ch d, rest')) (∀ (d : Fin n.succ), (ch d).size f) parseChildren (R.parseAux f) n.succ ((List.ofFn fun d R.spell (ch d)).flatten ++ rest) = some (ch, rest) R:RankedAlphabetn✝:ch✝:Fin n R.Termih: (d : Fin n) (f : ) (rest : List Bool), (ch d).size f R.parseAux f (R.spell (ch d) ++ rest) = some (ch d, rest)f:rest:List Boolhf: (d : Fin n), (ch d).size fn:ihn: (ch : Fin n R.Term), (∀ (d : Fin n) (f' : ) (rest' : List Bool), (ch d).size f' R.parseAux f' (R.spell (ch d) ++ rest') = some (ch d, rest')) (∀ (d : Fin n), (ch d).size f) parseChildren (R.parseAux f) n ((List.ofFn fun d R.spell (ch d)).flatten ++ rest) = some (ch, rest)ch:Fin n.succ R.Termihch: (d : Fin n.succ) (f' : ) (rest' : List Bool), (ch d).size f' R.parseAux f' (R.spell (ch d) ++ rest') = some (ch d, rest')hch: (d : Fin n.succ), (ch d).size fparseChildren (R.parseAux f) n.succ ((List.ofFn fun d R.spell (ch d)).flatten ++ rest) = some (ch, rest) R:RankedAlphabetn✝:ch✝:Fin n R.Termih: (d : Fin n) (f : ) (rest : List Bool), (ch d).size f R.parseAux f (R.spell (ch d) ++ rest) = some (ch d, rest)f:rest:List Boolhf: (d : Fin n), (ch d).size fn:ihn: (ch : Fin n R.Term), (∀ (d : Fin n) (f' : ) (rest' : List Bool), (ch d).size f' R.parseAux f' (R.spell (ch d) ++ rest') = some (ch d, rest')) (∀ (d : Fin n), (ch d).size f) parseChildren (R.parseAux f) n ((List.ofFn fun d R.spell (ch d)).flatten ++ rest) = some (ch, rest)ch:Fin n.succ R.Termihch: (d : Fin n.succ) (f' : ) (rest' : List Bool), (ch d).size f' R.parseAux f' (R.spell (ch d) ++ rest') = some (ch d, rest')hch: (d : Fin n.succ), (ch d).size f(match some (ch 0, (List.ofFn fun i R.spell (ch i.succ)).flatten ++ rest) with | none => none | some (t, w₁) => match parseChildren (R.parseAux f) n w₁ with | none => none | some (f, w₂) => some (Fin.cons t f, w₂)) = some (ch, rest) R:RankedAlphabetn✝:ch✝:Fin n R.Termih: (d : Fin n) (f : ) (rest : List Bool), (ch d).size f R.parseAux f (R.spell (ch d) ++ rest) = some (ch d, rest)f:rest:List Boolhf: (d : Fin n), (ch d).size fn:ihn: (ch : Fin n R.Term), (∀ (d : Fin n) (f' : ) (rest' : List Bool), (ch d).size f' R.parseAux f' (R.spell (ch d) ++ rest') = some (ch d, rest')) (∀ (d : Fin n), (ch d).size f) parseChildren (R.parseAux f) n ((List.ofFn fun d R.spell (ch d)).flatten ++ rest) = some (ch, rest)ch:Fin n.succ R.Termihch: (d : Fin n.succ) (f' : ) (rest' : List Bool), (ch d).size f' R.parseAux f' (R.spell (ch d) ++ rest') = some (ch d, rest')hch: (d : Fin n.succ), (ch d).size f(match parseChildren (R.parseAux f) n ((List.ofFn fun i R.spell (ch i.succ)).flatten ++ rest) with | none => none | some (f, w₂) => some (Fin.cons (ch 0) f, w₂)) = some (ch, rest) R:RankedAlphabetn✝:ch✝:Fin n R.Termih: (d : Fin n) (f : ) (rest : List Bool), (ch d).size f R.parseAux f (R.spell (ch d) ++ rest) = some (ch d, rest)f:rest:List Boolhf: (d : Fin n), (ch d).size fn:ihn: (ch : Fin n R.Term), (∀ (d : Fin n) (f' : ) (rest' : List Bool), (ch d).size f' R.parseAux f' (R.spell (ch d) ++ rest') = some (ch d, rest')) (∀ (d : Fin n), (ch d).size f) parseChildren (R.parseAux f) n ((List.ofFn fun d R.spell (ch d)).flatten ++ rest) = some (ch, rest)ch:Fin n.succ R.Termihch: (d : Fin n.succ) (f' : ) (rest' : List Bool), (ch d).size f' R.parseAux f' (R.spell (ch d) ++ rest') = some (ch d, rest')hch: (d : Fin n.succ), (ch d).size f(match some (fun i ch i.succ, rest) with | none => none | some (f, w₂) => some (Fin.cons (ch 0) f, w₂)) = some (ch, rest) All goals completed! 🐙

The descent inverts the spelling on spelled input, given fuel at least the term's node count, and returns the unconsumed remainder.

theorem parseAux_spell (R : RankedAlphabet) (t : R.Term) : (f : ) (rest : List Bool), t.size f R.parseAux f (R.spell t ++ rest) = some (t, rest) := Term.induction (motive := fun t (f : ) (rest : List Bool), t.size f R.parseAux f (R.spell t ++ rest) = some (t, rest)) (fun i ch ih f rest hf R:RankedAlphabett:R.Termi:Fin R.cardch:Fin (R.arity i) R.Termih: (d : Fin (R.arity i)) (f : ) (rest : List Bool), (ch d).size f R.parseAux f (R.spell (ch d) ++ rest) = some (ch d, rest)f:rest:List Boolhf:(Term.mk R i ch).size fR.parseAux f (R.spell (Term.mk R i ch) ++ rest) = some (Term.mk R i ch, rest) cases f with R:RankedAlphabett:R.Termi:Fin R.cardch:Fin (R.arity i) R.Termih: (d : Fin (R.arity i)) (f : ) (rest : List Bool), (ch d).size f R.parseAux f (R.spell (ch d) ++ rest) = some (ch d, rest)rest:List Boolhf:(Term.mk R i ch).size 0R.parseAux 0 (R.spell (Term.mk R i ch) ++ rest) = some (Term.mk R i ch, rest) exact absurd hf (R:RankedAlphabett:R.Termi:Fin R.cardch:Fin (R.arity i) R.Termih: (d : Fin (R.arity i)) (f : ) (rest : List Bool), (ch d).size f R.parseAux f (R.spell (ch d) ++ rest) = some (ch d, rest)rest:List Boolhf:(Term.mk R i ch).size 0¬(Term.mk R i ch).size 0 R:RankedAlphabett:R.Termi:Fin R.cardch:Fin (R.arity i) R.Termih: (d : Fin (R.arity i)) (f : ) (rest : List Bool), (ch d).size f R.parseAux f (R.spell (ch d) ++ rest) = some (ch d, rest)rest:List Boolhf:(Term.mk R i ch).size 0¬(List.ofFn fun d (ch d).size).sum + 1 0; All goals completed! 🐙) R:RankedAlphabett:R.Termi:Fin R.cardch:Fin (R.arity i) R.Termih: (d : Fin (R.arity i)) (f : ) (rest : List Bool), (ch d).size f R.parseAux f (R.spell (ch d) ++ rest) = some (ch d, rest)rest:List Boolf:hf:(Term.mk R i ch).size f + 1R.parseAux (f + 1) (R.spell (Term.mk R i ch) ++ rest) = some (Term.mk R i ch, rest) R:RankedAlphabett:R.Termi:Fin R.cardch:Fin (R.arity i) R.Termih: (d : Fin (R.arity i)) (f : ) (rest : List Bool), (ch d).size f R.parseAux f (R.spell (ch d) ++ rest) = some (ch d, rest)rest:List Boolf:hf:(Term.mk R i ch).size f + 1(match some (i, (List.ofFn fun d R.spell (ch d)).flatten ++ rest) with | none => none | some (i, rest) => match parseChildren (R.parseAux f) (R.arity i) rest with | none => none | some (f, rest') => some (Term.mk R i f, rest')) = some (Term.mk R i ch, rest) R:RankedAlphabett:R.Termi:Fin R.cardch:Fin (R.arity i) R.Termih: (d : Fin (R.arity i)) (f : ) (rest : List Bool), (ch d).size f R.parseAux f (R.spell (ch d) ++ rest) = some (ch d, rest)rest:List Boolf:hf:(Term.mk R i ch).size f + 1hchild: (d : Fin (R.arity i)), (ch d).size f(match some (i, (List.ofFn fun d R.spell (ch d)).flatten ++ rest) with | none => none | some (i, rest) => match parseChildren (R.parseAux f) (R.arity i) rest with | none => none | some (f, rest') => some (Term.mk R i f, rest')) = some (Term.mk R i ch, rest) R:RankedAlphabett:R.Termi:Fin R.cardch:Fin (R.arity i) R.Termih: (d : Fin (R.arity i)) (f : ) (rest : List Bool), (ch d).size f R.parseAux f (R.spell (ch d) ++ rest) = some (ch d, rest)rest:List Boolf:hf:(Term.mk R i ch).size f + 1hchild: (d : Fin (R.arity i)), (ch d).size f(match parseChildren (R.parseAux f) (R.arity i) ((List.ofFn fun d R.spell (ch d)).flatten ++ rest) with | none => none | some (f, rest') => some (Term.mk R i f, rest')) = some (Term.mk R i ch, rest) All goals completed! 🐙) t

The retraction law: the descent recovers every term the encoding spells.

theorem parse_spell (R : RankedAlphabet) (t : R.Term) : R.parse (R.spell t) = some t := R:RankedAlphabett:R.TermR.parse (R.spell t) = some t R:RankedAlphabett:R.Termhf:t.size (R.spell t).lengthR.parse (R.spell t) = some t R:RankedAlphabett:R.Termhf:t.size (R.spell t).lengthh:R.parseAux (R.spell t).length (R.spell t ++ []) = some (t, [])R.parse (R.spell t) = some t R:RankedAlphabett:R.Termhf:t.size (R.spell t).lengthh:R.parseAux (R.spell t).length (R.spell t) = some (t, [])R.parse (R.spell t) = some t All goals completed! 🐙

The encoding and its descent as a Computability.Encoding, whose three fields they are.

@[`@[expose]` has no effect outside a `module` fileexpose] def encoding (R : RankedAlphabet) : Computability.Encoding R.Term Bool where encode := R.spell decode := R.parse decode_encode := parse_spell R

Distinct terms have distinct spellings.

theorem spell_injective (R : RankedAlphabet) : Function.Injective R.spell := (R.encoding).encode_injective

Whatever a block read returns, it reads that symbol's block.

theorem decodeBlock_eq_some (R : RankedAlphabet) {w rest : List Bool} {i : Fin R.card} (h : R.decodeBlock w = some (i, rest)) : R.code i ++ rest = w := R:RankedAlphabetw:List Boolrest:List Booli:Fin R.cardh:R.decodeBlock w = some (i, rest)R.code i ++ rest = w R:RankedAlphabetw:List Boolrest:List Booli:Fin R.cardh:(if h : decodeBits (List.take R.width w) < R.card R.width w.length then some (decodeBits (List.take R.width w), , List.drop R.width w) else none) = some (i, rest)R.code i ++ rest = w R:RankedAlphabetw:List Boolrest:List Booli:Fin R.cardh✝:decodeBits (List.take R.width w) < R.card R.width w.lengthh:some (decodeBits (List.take R.width w), , List.drop R.width w) = some (i, rest)R.code i ++ rest = wR:RankedAlphabetw:List Boolrest:List Booli:Fin R.cardh✝:¬(decodeBits (List.take R.width w) < R.card R.width w.length)h:none = some (i, rest)R.code i ++ rest = w R:RankedAlphabetw:List Boolrest:List Booli:Fin R.cardh✝:decodeBits (List.take R.width w) < R.card R.width w.lengthh:some (decodeBits (List.take R.width w), , List.drop R.width w) = some (i, rest)R.code i ++ rest = w R:RankedAlphabetw:List Boolrest:List Booli:Fin R.cardhcond:decodeBits (List.take R.width w) < R.card R.width w.lengthh:some (decodeBits (List.take R.width w), , List.drop R.width w) = some (i, rest)R.code i ++ rest = w R:RankedAlphabetw:List Boolrest:List Booli:Fin R.cardhcond:decodeBits (List.take R.width w) < R.card R.width w.lengthh:some (decodeBits (List.take R.width w), , List.drop R.width w) = some (i, rest)heq:(decodeBits (List.take R.width w), , List.drop R.width w) = (i, rest)R.code i ++ rest = w R:RankedAlphabetw:List Boolrest:List Booli:Fin R.cardhcond:decodeBits (List.take R.width w) < R.card R.width w.lengthh:some (decodeBits (List.take R.width w), , List.drop R.width w) = some (i, rest)heq:(decodeBits (List.take R.width w), , List.drop R.width w) = (i, rest)hi:decodeBits (List.take R.width w) = iR.code i ++ rest = w R:RankedAlphabetw:List Boolrest:List Booli:Fin R.cardhcond:decodeBits (List.take R.width w) < R.card R.width w.lengthh:some (decodeBits (List.take R.width w), , List.drop R.width w) = some (i, rest)heq:(decodeBits (List.take R.width w), , List.drop R.width w) = (i, rest)hi:decodeBits (List.take R.width w) = ihrest:List.drop R.width w = restR.code i ++ rest = w R:RankedAlphabetw:List Boolrest:List Booli:Fin R.cardhcond:decodeBits (List.take R.width w) < R.card R.width w.lengthh:some (decodeBits (List.take R.width w), , List.drop R.width w) = some (i, rest)heq:(decodeBits (List.take R.width w), , List.drop R.width w) = (i, rest)hi:decodeBits (List.take R.width w) = ihrest:List.drop R.width w = resthlen:(R.code i).length = (List.take R.width w).lengthR.code i ++ rest = w R:RankedAlphabetw:List Boolrest:List Booli:Fin R.cardhcond:decodeBits (List.take R.width w) < R.card R.width w.lengthh:some (decodeBits (List.take R.width w), , List.drop R.width w) = some (i, rest)heq:(decodeBits (List.take R.width w), , List.drop R.width w) = (i, rest)hi:decodeBits (List.take R.width w) = ihrest:List.drop R.width w = resthlen:(R.code i).length = (List.take R.width w).lengthhcode:R.code i = List.take R.width wR.code i ++ rest = w All goals completed! 🐙 R:RankedAlphabetw:List Boolrest:List Booli:Fin R.cardh✝:¬(decodeBits (List.take R.width w) < R.card R.width w.length)h:none = some (i, rest)R.code i ++ rest = w All goals completed! 🐙

Whatever parseChildren returns, it reads the concatenation of the children's spellings.

theorem parseChildren_eq_some (R : RankedAlphabet) (f : ) (ih : w t rest, R.parseAux f w = some (t, rest) R.spell t ++ rest = w) : (n : ) (w : List Bool) (g : Fin n R.Term) (rest : List Bool), parseChildren (R.parseAux f) n w = some (g, rest) (List.ofFn fun d R.spell (g d)).flatten ++ rest = w := Nat.rec (fun w g rest h R:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = ww:List Boolg:Fin Nat.zero R.Termrest:List Boolh:parseChildren (R.parseAux f) Nat.zero w = some (g, rest)(List.ofFn fun d R.spell (g d)).flatten ++ rest = w R:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = ww:List Boolg:Fin Nat.zero R.Termrest:List Boolh:some (Fin.elim0, w) = some (g, rest)(List.ofFn fun d R.spell (g d)).flatten ++ rest = w R:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = ww:List Boolg:Fin Nat.zero R.Termrest:List Boolh:some (Fin.elim0, w) = some (g, rest)heq:(Fin.elim0, w) = (g, rest)(List.ofFn fun d R.spell (g d)).flatten ++ rest = w R:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = ww:List Boolg:Fin Nat.zero R.Termrest:List Boolh:some (Fin.elim0, w) = some (g, rest)heq:(Fin.elim0, w) = (g, rest)hw:w = rest(List.ofFn fun d R.spell (g d)).flatten ++ rest = w All goals completed! 🐙) (fun n ihn w g rest h R:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = wn:ihn: (w : List Bool) (g : Fin n R.Term) (rest : List Bool), parseChildren (R.parseAux f) n w = some (g, rest) (List.ofFn fun d R.spell (g d)).flatten ++ rest = ww:List Boolg:Fin n.succ R.Termrest:List Boolh:parseChildren (R.parseAux f) n.succ w = some (g, rest)(List.ofFn fun d R.spell (g d)).flatten ++ rest = w R:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = wn:ihn: (w : List Bool) (g : Fin n R.Term) (rest : List Bool), parseChildren (R.parseAux f) n w = some (g, rest) (List.ofFn fun d R.spell (g d)).flatten ++ rest = ww:List Boolg:Fin n.succ R.Termrest:List Boolh:(match R.parseAux f w with | none => none | some (t, w₁) => match parseChildren (R.parseAux f) n w₁ with | none => none | some (f, w₂) => some (Fin.cons t f, w₂)) = some (g, rest)(List.ofFn fun d R.spell (g d)).flatten ++ rest = w R:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = wn:ihn: (w : List Bool) (g : Fin n R.Term) (rest : List Bool), parseChildren (R.parseAux f) n w = some (g, rest) (List.ofFn fun d R.spell (g d)).flatten ++ rest = ww:List Boolg:Fin n.succ R.Termrest:List Boolx✝:Option (R.Term × List Bool)heq✝:R.parseAux f w = noneh:none = some (g, rest)(List.ofFn fun d R.spell (g d)).flatten ++ rest = wR:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = wn:ihn: (w : List Bool) (g : Fin n R.Term) (rest : List Bool), parseChildren (R.parseAux f) n w = some (g, rest) (List.ofFn fun d R.spell (g d)).flatten ++ rest = ww:List Boolg:Fin n.succ R.Termrest:List Boolx✝:Option (R.Term × List Bool)t✝:R.Termw₁✝:List Boolheq✝:R.parseAux f w = some (t✝, w₁✝)h:(match parseChildren (R.parseAux f) n w₁✝ with | none => none | some (f, w₂) => some (Fin.cons t✝ f, w₂)) = some (g, rest)(List.ofFn fun d R.spell (g d)).flatten ++ rest = w R:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = wn:ihn: (w : List Bool) (g : Fin n R.Term) (rest : List Bool), parseChildren (R.parseAux f) n w = some (g, rest) (List.ofFn fun d R.spell (g d)).flatten ++ rest = ww:List Boolg:Fin n.succ R.Termrest:List Boolx✝:Option (R.Term × List Bool)heq✝:R.parseAux f w = noneh:none = some (g, rest)(List.ofFn fun d R.spell (g d)).flatten ++ rest = w All goals completed! 🐙 R:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = wn:ihn: (w : List Bool) (g : Fin n R.Term) (rest : List Bool), parseChildren (R.parseAux f) n w = some (g, rest) (List.ofFn fun d R.spell (g d)).flatten ++ rest = ww:List Boolg:Fin n.succ R.Termrest:List Boolx✝:Option (R.Term × List Bool)t✝:R.Termw₁✝:List Boolheq✝:R.parseAux f w = some (t✝, w₁✝)h:(match parseChildren (R.parseAux f) n w₁✝ with | none => none | some (f, w₂) => some (Fin.cons t✝ f, w₂)) = some (g, rest)(List.ofFn fun d R.spell (g d)).flatten ++ rest = w R:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = wn:ihn: (w : List Bool) (g : Fin n R.Term) (rest : List Bool), parseChildren (R.parseAux f) n w = some (g, rest) (List.ofFn fun d R.spell (g d)).flatten ++ rest = ww:List Boolg:Fin n.succ R.Termrest:List Boolx✝:Option (R.Term × List Bool)t:R.Termw₁:List Boolh₁:R.parseAux f w = some (t✝, w₁✝)h:(match parseChildren (R.parseAux f) n w₁✝ with | none => none | some (f, w₂) => some (Fin.cons t✝ f, w₂)) = some (g, rest)(List.ofFn fun d R.spell (g d)).flatten ++ rest = w R:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = wn:ihn: (w : List Bool) (g : Fin n R.Term) (rest : List Bool), parseChildren (R.parseAux f) n w = some (g, rest) (List.ofFn fun d R.spell (g d)).flatten ++ rest = ww:List Boolg:Fin n.succ R.Termrest:List Boolx✝¹:Option (R.Term × List Bool)t:R.Termw₁:List Boolh₁:R.parseAux f w = some (t✝, w₁✝)x✝:Option ((Fin n R.Term) × List Bool)heq✝:parseChildren (R.parseAux f) n w₁ = noneh:none = some (g, rest)(List.ofFn fun d R.spell (g d)).flatten ++ rest = wR:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = wn:ihn: (w : List Bool) (g : Fin n R.Term) (rest : List Bool), parseChildren (R.parseAux f) n w = some (g, rest) (List.ofFn fun d R.spell (g d)).flatten ++ rest = ww:List Boolg:Fin n.succ R.Termrest:List Boolx✝¹:Option (R.Term × List Bool)t:R.Termw₁:List Boolh₁:R.parseAux f w = some (t✝, w₁✝)x✝:Option ((Fin n R.Term) × List Bool)f✝:Fin n R.Termw₂✝:List Boolheq✝:parseChildren (R.parseAux f) n w₁ = some (f✝, w₂✝)h:some (Fin.cons t f✝, w₂✝) = some (g, rest)(List.ofFn fun d R.spell (g d)).flatten ++ rest = w R:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = wn:ihn: (w : List Bool) (g : Fin n R.Term) (rest : List Bool), parseChildren (R.parseAux f) n w = some (g, rest) (List.ofFn fun d R.spell (g d)).flatten ++ rest = ww:List Boolg:Fin n.succ R.Termrest:List Boolx✝¹:Option (R.Term × List Bool)t:R.Termw₁:List Boolh₁:R.parseAux f w = some (t✝, w₁✝)x✝:Option ((Fin n R.Term) × List Bool)heq✝:parseChildren (R.parseAux f) n w₁ = noneh:none = some (g, rest)(List.ofFn fun d R.spell (g d)).flatten ++ rest = w All goals completed! 🐙 R:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = wn:ihn: (w : List Bool) (g : Fin n R.Term) (rest : List Bool), parseChildren (R.parseAux f) n w = some (g, rest) (List.ofFn fun d R.spell (g d)).flatten ++ rest = ww:List Boolg:Fin n.succ R.Termrest:List Boolx✝¹:Option (R.Term × List Bool)t:R.Termw₁:List Boolh₁:R.parseAux f w = some (t✝, w₁✝)x✝:Option ((Fin n R.Term) × List Bool)f✝:Fin n R.Termw₂✝:List Boolheq✝:parseChildren (R.parseAux f) n w₁ = some (f✝, w₂✝)h:some (Fin.cons t f✝, w₂✝) = some (g, rest)(List.ofFn fun d R.spell (g d)).flatten ++ rest = w R:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = wn:ihn: (w : List Bool) (g : Fin n R.Term) (rest : List Bool), parseChildren (R.parseAux f) n w = some (g, rest) (List.ofFn fun d R.spell (g d)).flatten ++ rest = ww:List Boolg:Fin n.succ R.Termrest:List Boolx✝¹:Option (R.Term × List Bool)t:R.Termw₁:List Boolh₁:R.parseAux f w = some (t✝, w₁✝)x✝:Option ((Fin n R.Term) × List Bool)g':Fin n R.Termw₂:List Boolh₂:parseChildren (R.parseAux f) n w₁ = some (f✝, w₂✝)h:some (Fin.cons t f✝, w₂✝) = some (g, rest)(List.ofFn fun d R.spell (g d)).flatten ++ rest = w R:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = wn:ihn: (w : List Bool) (g : Fin n R.Term) (rest : List Bool), parseChildren (R.parseAux f) n w = some (g, rest) (List.ofFn fun d R.spell (g d)).flatten ++ rest = ww:List Boolg:Fin n.succ R.Termrest:List Boolx✝¹:Option (R.Term × List Bool)t:R.Termw₁:List Boolh₁:R.parseAux f w = some (t✝, w₁✝)x✝:Option ((Fin n R.Term) × List Bool)g':Fin n R.Termw₂:List Boolh₂:parseChildren (R.parseAux f) n w₁ = some (f✝, w₂✝)h:some (Fin.cons t f✝, w₂✝) = some (g, rest)heq:(Fin.cons t g', w₂) = (g, rest)(List.ofFn fun d R.spell (g d)).flatten ++ rest = w R:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = wn:ihn: (w : List Bool) (g : Fin n R.Term) (rest : List Bool), parseChildren (R.parseAux f) n w = some (g, rest) (List.ofFn fun d R.spell (g d)).flatten ++ rest = ww:List Boolg:Fin n.succ R.Termrest:List Boolx✝¹:Option (R.Term × List Bool)t:R.Termw₁:List Boolh₁:R.parseAux f w = some (t✝, w₁✝)x✝:Option ((Fin n R.Term) × List Bool)g':Fin n R.Termw₂:List Boolh₂:parseChildren (R.parseAux f) n w₁ = some (f✝, w₂✝)h:some (Fin.cons t f✝, w₂✝) = some (g, rest)heq:(Fin.cons t g', w₂) = (g, rest)hg:Fin.cons t g' = g(List.ofFn fun d R.spell (g d)).flatten ++ rest = w R:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = wn:ihn: (w : List Bool) (g : Fin n R.Term) (rest : List Bool), parseChildren (R.parseAux f) n w = some (g, rest) (List.ofFn fun d R.spell (g d)).flatten ++ rest = ww:List Boolg:Fin n.succ R.Termrest:List Boolx✝¹:Option (R.Term × List Bool)t:R.Termw₁:List Boolh₁:R.parseAux f w = some (t✝, w₁✝)x✝:Option ((Fin n R.Term) × List Bool)g':Fin n R.Termw₂:List Boolh₂:parseChildren (R.parseAux f) n w₁ = some (f✝, w₂✝)h:some (Fin.cons t f✝, w₂✝) = some (g, rest)heq:(Fin.cons t g', w₂) = (g, rest)hg:Fin.cons t g' = ghrest:w₂ = rest(List.ofFn fun d R.spell (g d)).flatten ++ rest = w R:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = wn:ihn: (w : List Bool) (g : Fin n R.Term) (rest : List Bool), parseChildren (R.parseAux f) n w = some (g, rest) (List.ofFn fun d R.spell (g d)).flatten ++ rest = ww:List Boolrest:List Boolx✝¹:Option (R.Term × List Bool)t:R.Termw₁:List Boolh₁:R.parseAux f w = some (t✝, w₁✝)x✝:Option ((Fin n R.Term) × List Bool)g':Fin n R.Termw₂:List Boolh₂:parseChildren (R.parseAux f) n w₁ = some (f✝, w₂✝)hrest:w₂ = resth:some (Fin.cons t g', w₂) = some (Fin.cons t g', rest)heq:(Fin.cons t g', w₂) = (Fin.cons t g', rest)(List.ofFn fun d R.spell (Fin.cons t g' d)).flatten ++ rest = w R:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = wn:ihn: (w : List Bool) (g : Fin n R.Term) (rest : List Bool), parseChildren (R.parseAux f) n w = some (g, rest) (List.ofFn fun d R.spell (g d)).flatten ++ rest = ww:List Boolrest:List Boolx✝¹:Option (R.Term × List Bool)t:R.Termw₁:List Boolh₁:R.parseAux f w = some (t✝, w₁✝)x✝:Option ((Fin n R.Term) × List Bool)g':Fin n R.Termw₂:List Boolh₂:parseChildren (R.parseAux f) n w₁ = some (f✝, w₂✝)hrest:w₂ = resth:some (Fin.cons t g', w₂) = some (Fin.cons t g', rest)heq:(Fin.cons t g', w₂) = (Fin.cons t g', rest)R.spell (Fin.cons t g' 0) ++ ((List.ofFn fun i R.spell (Fin.cons t g' i.succ)).flatten ++ w₂) = w R:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = wn:ihn: (w : List Bool) (g : Fin n R.Term) (rest : List Bool), parseChildren (R.parseAux f) n w = some (g, rest) (List.ofFn fun d R.spell (g d)).flatten ++ rest = ww:List Boolrest:List Boolx✝¹:Option (R.Term × List Bool)t:R.Termw₁:List Boolh₁:R.parseAux f w = some (t✝, w₁✝)x✝:Option ((Fin n R.Term) × List Bool)g':Fin n R.Termw₂:List Boolh₂:parseChildren (R.parseAux f) n w₁ = some (f✝, w₂✝)hrest:w₂ = resth:some (Fin.cons t g', w₂) = some (Fin.cons t g', rest)heq:(Fin.cons t g', w₂) = (Fin.cons t g', rest)R.spell t ++ ((List.ofFn fun i R.spell (g' i)).flatten ++ w₂) = w All goals completed! 🐙)

Whatever the descent reads, it reads a spelling.

theorem parseAux_eq_some (R : RankedAlphabet) : (f : ) (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = w := Nat.rec (fun _ _ _ h nomatch h) (fun f ih w t rest h R:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = ww:List Boolt:R.Termrest:List Boolh:R.parseAux f.succ w = some (t, rest)R.spell t ++ rest = w R:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = ww:List Boolt:R.Termrest:List Boolh:(match R.decodeBlock w with | none => none | some (i, rest) => match parseChildren (R.parseAux f) (R.arity i) rest with | none => none | some (f, rest') => some (Term.mk R i f, rest')) = some (t, rest)R.spell t ++ rest = w R:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = ww:List Boolt:R.Termrest:List Boolx✝:Option (Fin R.card × List Bool)heq✝:R.decodeBlock w = noneh:none = some (t, rest)R.spell t ++ rest = wR:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = ww:List Boolt:R.Termrest:List Boolx✝:Option (Fin R.card × List Bool)i✝:Fin R.cardrest✝:List Boolheq✝:R.decodeBlock w = some (i✝, rest✝)h:(match parseChildren (R.parseAux f) (R.arity i✝) rest✝ with | none => none | some (f, rest') => some (Term.mk R i✝ f, rest')) = some (t, rest)R.spell t ++ rest = w R:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = ww:List Boolt:R.Termrest:List Boolx✝:Option (Fin R.card × List Bool)heq✝:R.decodeBlock w = noneh:none = some (t, rest)R.spell t ++ rest = w All goals completed! 🐙 R:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = ww:List Boolt:R.Termrest:List Boolx✝:Option (Fin R.card × List Bool)i✝:Fin R.cardrest✝:List Boolheq✝:R.decodeBlock w = some (i✝, rest✝)h:(match parseChildren (R.parseAux f) (R.arity i✝) rest✝ with | none => none | some (f, rest') => some (Term.mk R i✝ f, rest')) = some (t, rest)R.spell t ++ rest = w R:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = ww:List Boolt:R.Termrest:List Boolx✝:Option (Fin R.card × List Bool)i:Fin R.cardrest₁:List Boolhb:R.decodeBlock w = some (i✝, rest✝)h:(match parseChildren (R.parseAux f) (R.arity i✝) rest✝ with | none => none | some (f, rest') => some (Term.mk R i✝ f, rest')) = some (t, rest)R.spell t ++ rest = w R:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = ww:List Boolt:R.Termrest:List Boolx✝¹:Option (Fin R.card × List Bool)i:Fin R.cardrest₁:List Boolhb:R.decodeBlock w = some (i✝, rest✝)x✝:Option ((Fin (R.arity i) R.Term) × List Bool)heq✝:parseChildren (R.parseAux f) (R.arity i) rest₁ = noneh:none = some (t, rest)R.spell t ++ rest = wR:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = ww:List Boolt:R.Termrest:List Boolx✝¹:Option (Fin R.card × List Bool)i:Fin R.cardrest₁:List Boolhb:R.decodeBlock w = some (i✝, rest✝)x✝:Option ((Fin (R.arity i) R.Term) × List Bool)f✝:Fin (R.arity i) R.Termrest'✝:List Boolheq✝:parseChildren (R.parseAux f) (R.arity i) rest₁ = some (f✝, rest'✝)h:some (Term.mk R i f✝, rest'✝) = some (t, rest)R.spell t ++ rest = w R:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = ww:List Boolt:R.Termrest:List Boolx✝¹:Option (Fin R.card × List Bool)i:Fin R.cardrest₁:List Boolhb:R.decodeBlock w = some (i✝, rest✝)x✝:Option ((Fin (R.arity i) R.Term) × List Bool)heq✝:parseChildren (R.parseAux f) (R.arity i) rest₁ = noneh:none = some (t, rest)R.spell t ++ rest = w All goals completed! 🐙 R:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = ww:List Boolt:R.Termrest:List Boolx✝¹:Option (Fin R.card × List Bool)i:Fin R.cardrest₁:List Boolhb:R.decodeBlock w = some (i✝, rest✝)x✝:Option ((Fin (R.arity i) R.Term) × List Bool)f✝:Fin (R.arity i) R.Termrest'✝:List Boolheq✝:parseChildren (R.parseAux f) (R.arity i) rest₁ = some (f✝, rest'✝)h:some (Term.mk R i f✝, rest'✝) = some (t, rest)R.spell t ++ rest = w R:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = ww:List Boolt:R.Termrest:List Boolx✝¹:Option (Fin R.card × List Bool)i:Fin R.cardrest₁:List Boolhb:R.decodeBlock w = some (i✝, rest✝)x✝:Option ((Fin (R.arity i) R.Term) × List Bool)g:Fin (R.arity i) R.Termrest₂:List Boolhc:parseChildren (R.parseAux f) (R.arity i) rest₁ = some (f✝, rest'✝)h:some (Term.mk R i f✝, rest'✝) = some (t, rest)R.spell t ++ rest = w R:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = ww:List Boolt:R.Termrest:List Boolx✝¹:Option (Fin R.card × List Bool)i:Fin R.cardrest₁:List Boolhb:R.decodeBlock w = some (i✝, rest✝)x✝:Option ((Fin (R.arity i) R.Term) × List Bool)g:Fin (R.arity i) R.Termrest₂:List Boolhc:parseChildren (R.parseAux f) (R.arity i) rest₁ = some (f✝, rest'✝)h:some (Term.mk R i f✝, rest'✝) = some (t, rest)heq:(Term.mk R i g, rest₂) = (t, rest)R.spell t ++ rest = w R:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = ww:List Boolt:R.Termrest:List Boolx✝¹:Option (Fin R.card × List Bool)i:Fin R.cardrest₁:List Boolhb:R.decodeBlock w = some (i✝, rest✝)x✝:Option ((Fin (R.arity i) R.Term) × List Bool)g:Fin (R.arity i) R.Termrest₂:List Boolhc:parseChildren (R.parseAux f) (R.arity i) rest₁ = some (f✝, rest'✝)h:some (Term.mk R i f✝, rest'✝) = some (t, rest)heq:(Term.mk R i g, rest₂) = (t, rest)ht:Term.mk R i g = tR.spell t ++ rest = w R:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = ww:List Boolt:R.Termrest:List Boolx✝¹:Option (Fin R.card × List Bool)i:Fin R.cardrest₁:List Boolhb:R.decodeBlock w = some (i✝, rest✝)x✝:Option ((Fin (R.arity i) R.Term) × List Bool)g:Fin (R.arity i) R.Termrest₂:List Boolhc:parseChildren (R.parseAux f) (R.arity i) rest₁ = some (f✝, rest'✝)h:some (Term.mk R i f✝, rest'✝) = some (t, rest)heq:(Term.mk R i g, rest₂) = (t, rest)ht:Term.mk R i g = threst:rest₂ = restR.spell t ++ rest = w R:RankedAlphabetf:ih: (w : List Bool) (t : R.Term) (rest : List Bool), R.parseAux f w = some (t, rest) R.spell t ++ rest = ww:List Boolrest:List Boolx✝¹:Option (Fin R.card × List Bool)i:Fin R.cardrest₁:List Boolhb:R.decodeBlock w = some (i✝, rest✝)x✝:Option ((Fin (R.arity i) R.Term) × List Bool)g:Fin (R.arity i) R.Termrest₂:List Boolhc:parseChildren (R.parseAux f) (R.arity i) rest₁ = some (f✝, rest'✝)hrest:rest₂ = resth:some (Term.mk R i g, rest₂) = some (Term.mk R i g, rest)heq:(Term.mk R i g, rest₂) = (Term.mk R i g, rest)R.spell (Term.mk R i g) ++ rest = w All goals completed! 🐙)

The descent succeeds exactly on the spellings, returning the term spelled.

theorem parse_eq_some_iff (R : RankedAlphabet) {w : List Bool} {t : R.Term} : R.parse w = some t R.spell t = w := R:RankedAlphabetw:List Boolt:R.TermR.parse w = some t R.spell t = w R:RankedAlphabetw:List Boolt:R.Termh:R.parse w = some tR.spell t = w R:RankedAlphabetw:List Boolt:R.Termh:(match R.parseAux w.length w with | some (t, []) => some t | x => none) = some tR.spell t = w R:RankedAlphabetw:List Boolt:R.Termx✝:Option (R.Term × List Bool)t✝:R.Termheq✝:R.parseAux w.length w = some (t✝, [])h:some t✝ = some tR.spell t = wR:RankedAlphabetw:List Boolt:R.Termx✝¹:Option (R.Term × List Bool)x✝: (t : R.Term), R.parseAux w.length w = some (t, []) Falseh:none = some tR.spell t = w R:RankedAlphabetw:List Boolt:R.Termx✝:Option (R.Term × List Bool)t✝:R.Termheq✝:R.parseAux w.length w = some (t✝, [])h:some t✝ = some tR.spell t = w R:RankedAlphabetw:List Boolt:R.Termx✝:Option (R.Term × List Bool)t':R.Termhp:R.parseAux w.length w = some (t✝, [])h:some t✝ = some tR.spell t = w R:RankedAlphabetw:List Boolt:R.Termx✝:Option (R.Term × List Bool)t':R.Termhp:R.parseAux w.length w = some (t✝, [])h:some t✝ = some tR.spell t' = w All goals completed! 🐙 R:RankedAlphabetw:List Boolt:R.Termx✝¹:Option (R.Term × List Bool)x✝: (t : R.Term), R.parseAux w.length w = some (t, []) Falseh:none = some tR.spell t = w All goals completed! 🐙

The state of the validity scan: the bits of an incomplete block, the count of pending subterms, and whether the scan has failed.

The bits of an incomplete block, most recently read first.

The count of pending subterms.

Whether the scan has not yet failed.

@[ext] structure Scan where buf : List Bool depth : live : Bool

One step of the scan, reading one bit. A failed state absorbs. An incomplete block takes the bit; a complete one is decoded, and its symbol pops its arity and pushes one, failing when the block spells no symbol or the pending count is short of the arity.

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

The scan of a word from a given state. foldr reads the word's last bit first, which is the processing order of a right-to-left scan.

@[`@[expose]` has no effect outside a `module` fileexpose] def scanFrom (R : RankedAlphabet) (w : List Bool) (s : Scan) : Scan := w.foldr R.scanStep s

The scan of a word from the initial state.

@[`@[expose]` has no effect outside a `module` fileexpose] def scanFinal (R : RankedAlphabet) (w : List Bool) : Scan := R.scanFrom w [], 0, true

Whether a word spells a term: the scan ends live, with no incomplete block and exactly one pending subterm.

@[`@[expose]` has no effect outside a `module` fileexpose] def validBool (R : RankedAlphabet) (w : List Bool) : Bool := (R.scanFinal w).live && (R.scanFinal w).buf.isEmpty && (R.scanFinal w).depth == 1

A word spells a term.

@[`@[expose]` has no effect outside a `module` fileexpose] def Valid (R : RankedAlphabet) (w : List Bool) : Prop := R.validBool w = true

Valid is a Bool equation, so membership is decidable. Instance search does not unfold the def, so the instance is supplied.

instance (R : RankedAlphabet) : DecidablePred R.Valid := fun _ inferInstanceAs (Decidable (_ = true))
@[simp] theorem scanFrom_nil (R : RankedAlphabet) (s : Scan) : R.scanFrom [] s = s := rfl@[simp] theorem scanFrom_cons (R : RankedAlphabet) (b : Bool) (w : List Bool) (s : Scan) : R.scanFrom (b :: w) s = R.scanStep b (R.scanFrom w s) := rfl@[simp] theorem scanFinal_nil (R : RankedAlphabet) : R.scanFinal [] = [], 0, true := rfl@[simp] theorem scanFinal_cons (R : RankedAlphabet) (b : Bool) (w : List Bool) : R.scanFinal (b :: w) = R.scanStep b (R.scanFinal w) := rfl

The scan of a concatenation reads the later part first.

theorem scanFrom_append (R : RankedAlphabet) (u v : List Bool) (s : Scan) : R.scanFrom (u ++ v) s = R.scanFrom u (R.scanFrom v s) := List.rec rfl (fun b w ih R:RankedAlphabetu:List Boolv:List Bools:Scanb:Boolw:List Boolih:R.scanFrom (w ++ v) s = R.scanFrom w (R.scanFrom v s)R.scanFrom (b :: w ++ v) s = R.scanFrom (b :: w) (R.scanFrom v s) All goals completed! 🐙) u

Failure absorbs: no further input restores a failed scan.

theorem scanFrom_not_live (R : RankedAlphabet) (u : List Bool) (s : Scan) (h : s.live = false) : (R.scanFrom u s).live = false := List.rec h (fun b v ih R:RankedAlphabetu:List Bools:Scanh:s.live = falseb:Boolv:List Boolih:(R.scanFrom v s).live = false(R.scanFrom (b :: v) s).live = false R:RankedAlphabetu:List Bools:Scanh:s.live = falseb:Boolv:List Boolih:(R.scanFrom v s).live = false(match false with | false => R.scanFrom v s | true => match decide ((b :: (R.scanFrom v s).buf).length = R.width) with | false => { buf := b :: (R.scanFrom v s).buf, depth := (R.scanFrom v s).depth, live := true } | true => match R.arOf (decodeBits (b :: (R.scanFrom v s).buf)) with | none => { buf := [], depth := (R.scanFrom v s).depth, live := false } | some r => match decide (r (R.scanFrom v s).depth) with | false => { buf := [], depth := (R.scanFrom v s).depth, live := false } | true => { buf := [], depth := (R.scanFrom v s).depth - r + 1, live := true }).live = false; All goals completed! 🐙) u

A word shorter than a block only accumulates.

theorem scanFrom_short (R : RankedAlphabet) (d : ) (bs : List Bool) : u : List Bool, u.length + bs.length < R.width R.scanFrom u bs, d, true = u ++ bs, d, true := List.rec (fun _ rfl) (fun b v ih hv R:RankedAlphabetd:bs:List Boolb:Boolv:List Boolih:v.length + bs.length < R.width R.scanFrom v { buf := bs, depth := d, live := true } = { buf := v ++ bs, depth := d, live := true }hv:(b :: v).length + bs.length < R.widthR.scanFrom (b :: v) { buf := bs, depth := d, live := true } = { buf := b :: v ++ bs, depth := d, live := true } R:RankedAlphabetd:bs:List Boolb:Boolv:List Boolih:v.length + bs.length < R.width R.scanFrom v { buf := bs, depth := d, live := true } = { buf := v ++ bs, depth := d, live := true }hv:(b :: v).length + bs.length < R.width(match { buf := v ++ bs, depth := d, live := true }.live with | false => { buf := v ++ bs, depth := d, live := true } | true => match decide ((b :: { buf := v ++ bs, depth := d, live := true }.buf).length = R.width) with | false => { buf := b :: { buf := v ++ bs, depth := d, live := true }.buf, depth := { buf := v ++ bs, depth := d, live := true }.depth, live := true } | true => match R.arOf (decodeBits (b :: { buf := v ++ bs, depth := d, live := true }.buf)) with | none => { buf := [], depth := { buf := v ++ bs, depth := d, live := true }.depth, live := false } | some r => match decide (r { buf := v ++ bs, depth := d, live := true }.depth) with | false => { buf := [], depth := { buf := v ++ bs, depth := d, live := true }.depth, live := false } | true => { buf := [], depth := { buf := v ++ bs, depth := d, live := true }.depth - r + 1, live := true }) = { buf := b :: v ++ bs, depth := d, live := true } R:RankedAlphabetd:bs:List Boolb:Boolv:List Boolih:v.length + bs.length < R.width R.scanFrom v { buf := bs, depth := d, live := true } = { buf := v ++ bs, depth := d, live := true }hv:(b :: v).length + bs.length < R.width(match decide ((b :: (v ++ bs)).length = R.width) with | false => { buf := b :: (v ++ bs), depth := d, live := true } | true => match R.arOf (decodeBits (b :: (v ++ bs))) with | none => { buf := [], depth := d, live := false } | some r => match decide (r d) with | false => { buf := [], depth := d, live := false } | true => { buf := [], depth := d - r + 1, live := true }) = { buf := b :: v ++ bs, depth := d, live := true } R:RankedAlphabetd:bs:List Boolb:Boolv:List Boolih:v.length + bs.length < R.width R.scanFrom v { buf := bs, depth := d, live := true } = { buf := v ++ bs, depth := d, live := true }hv:(b :: v).length + bs.length < R.width(match false with | false => { buf := b :: (v ++ bs), depth := d, live := true } | true => match R.arOf (decodeBits (b :: (v ++ bs))) with | none => { buf := [], depth := d, live := false } | some r => match decide (r d) with | false => { buf := [], depth := d, live := false } | true => { buf := [], depth := d - r + 1, live := true }) = { buf := b :: v ++ bs, depth := d, live := true } All goals completed! 🐙)

Reading a symbol's block from a state with no incomplete block and at least the symbol's arity pending pops that arity and pushes one.

theorem scanFrom_code (R : RankedAlphabet) (i : Fin R.card) (d : ) (h : R.arity i d) : R.scanFrom (R.code i) [], d, true = [], d - R.arity i + 1, true := R:RankedAlphabeti:Fin R.cardd:h:R.arity i dR.scanFrom (R.code i) { buf := [], depth := d, live := true } = { buf := [], depth := d - R.arity i + 1, live := true } R:RankedAlphabeti:Fin R.cardd:h:R.arity i db:Boolv:List Boolhcode:R.code i = b :: vR.scanFrom (R.code i) { buf := [], depth := d, live := true } = { buf := [], depth := d - R.arity i + 1, live := true } R:RankedAlphabeti:Fin R.cardd:h:R.arity i db:Boolv:List Boolhcode:R.code i = b :: vhw:(R.code i).length = R.widthR.scanFrom (R.code i) { buf := [], depth := d, live := true } = { buf := [], depth := d - R.arity i + 1, live := true } R:RankedAlphabeti:Fin R.cardd:h:R.arity i db:Boolv:List Boolhcode:R.code i = b :: vhw:v.length + 1 = R.widthR.scanFrom (R.code i) { buf := [], depth := d, live := true } = { buf := [], depth := d - R.arity i + 1, live := true } R:RankedAlphabeti:Fin R.cardd:h:R.arity i db:Boolv:List Boolhcode:R.code i = b :: vhw:v.length + 1 = R.width(match { buf := v ++ [], depth := d, live := true }.live with | false => { buf := v ++ [], depth := d, live := true } | true => match decide ((b :: { buf := v ++ [], depth := d, live := true }.buf).length = R.width) with | false => { buf := b :: { buf := v ++ [], depth := d, live := true }.buf, depth := { buf := v ++ [], depth := d, live := true }.depth, live := true } | true => match R.arOf (decodeBits (b :: { buf := v ++ [], depth := d, live := true }.buf)) with | none => { buf := [], depth := { buf := v ++ [], depth := d, live := true }.depth, live := false } | some r => match decide (r { buf := v ++ [], depth := d, live := true }.depth) with | false => { buf := [], depth := { buf := v ++ [], depth := d, live := true }.depth, live := false } | true => { buf := [], depth := { buf := v ++ [], depth := d, live := true }.depth - r + 1, live := true }) = { buf := [], depth := d - R.arity i + 1, live := true } R:RankedAlphabeti:Fin R.cardd:h:R.arity i db:Boolv:List Boolhcode:R.code i = b :: vhw:v.length + 1 = R.width(match decide ((b :: v).length = R.width) with | false => { buf := b :: v, depth := d, live := true } | true => match R.arOf (decodeBits (b :: v)) with | none => { buf := [], depth := d, live := false } | some r => match decide (r d) with | false => { buf := [], depth := d, live := false } | true => { buf := [], depth := d - r + 1, live := true }) = { buf := [], depth := d - R.arity i + 1, live := true } R:RankedAlphabeti:Fin R.cardd:h:R.arity i db:Boolv:List Boolhcode:R.code i = b :: vhw:v.length + 1 = R.width(match true with | false => { buf := b :: v, depth := d, live := true } | true => match R.arOf (decodeBits (b :: v)) with | none => { buf := [], depth := d, live := false } | some r => match decide (r d) with | false => { buf := [], depth := d, live := false } | true => { buf := [], depth := d - r + 1, live := true }) = { buf := [], depth := d - R.arity i + 1, live := true } R:RankedAlphabeti:Fin R.cardd:h:R.arity i db:Boolv:List Boolhcode:R.code i = b :: vhw:v.length + 1 = R.width(match R.arOf (decodeBits (b :: v)) with | none => { buf := [], depth := d, live := false } | some r => match decide (r d) with | false => { buf := [], depth := d, live := false } | true => { buf := [], depth := d - r + 1, live := true }) = { buf := [], depth := d - R.arity i + 1, live := true } R:RankedAlphabeti:Fin R.cardd:h:R.arity i db:Boolv:List Boolhcode:R.code i = b :: vhw:v.length + 1 = R.width(match some (R.arity i) with | none => { buf := [], depth := d, live := false } | some r => match decide (r d) with | false => { buf := [], depth := d, live := false } | true => { buf := [], depth := d - r + 1, live := true }) = { buf := [], depth := d - R.arity i + 1, live := true } R:RankedAlphabeti:Fin R.cardd:h:R.arity i db:Boolv:List Boolhcode:R.code i = b :: vhw:v.length + 1 = R.width(match decide (R.arity i d) with | false => { buf := [], depth := d, live := false } | true => { buf := [], depth := d - R.arity i + 1, live := true }) = { buf := [], depth := d - R.arity i + 1, live := true } All goals completed! 🐙

The scan of a list of spellings, each raising the pending count by one, raises it by their number.

theorem scanFrom_flatten (R : RankedAlphabet) (ws : List (List Bool)) (hw : u ws, d, R.scanFrom u [], d, true = [], d + 1, true) (d : ) : R.scanFrom ws.flatten [], d, true = [], d + ws.length, true := List.rec (motive := fun l ( u l, d, R.scanFrom u [], d, true = [], d + 1, true) R.scanFrom l.flatten [], d, true = [], d + l.length, true) (fun _ R:RankedAlphabetws:List (List Bool)hw: u ws, (d : ), R.scanFrom u { buf := [], depth := d, live := true } = { buf := [], depth := d + 1, live := true }d:x✝: u [], (d : ), R.scanFrom u { buf := [], depth := d, live := true } = { buf := [], depth := d + 1, live := true }R.scanFrom [].flatten { buf := [], depth := d, live := true } = { buf := [], depth := d + [].length, live := true } All goals completed! 🐙) (fun u l ih hl R:RankedAlphabetws:List (List Bool)hw: u ws, (d : ), R.scanFrom u { buf := [], depth := d, live := true } = { buf := [], depth := d + 1, live := true }d:u:List Booll:List (List Bool)ih:(∀ u l, (d : ), R.scanFrom u { buf := [], depth := d, live := true } = { buf := [], depth := d + 1, live := true }) R.scanFrom l.flatten { buf := [], depth := d, live := true } = { buf := [], depth := d + l.length, live := true }hl: u_1 u :: l, (d : ), R.scanFrom u_1 { buf := [], depth := d, live := true } = { buf := [], depth := d + 1, live := true }R.scanFrom (u :: l).flatten { buf := [], depth := d, live := true } = { buf := [], depth := d + (u :: l).length, live := true } R:RankedAlphabetws:List (List Bool)hw: u ws, (d : ), R.scanFrom u { buf := [], depth := d, live := true } = { buf := [], depth := d + 1, live := true }d:u:List Booll:List (List Bool)ih:(∀ u l, (d : ), R.scanFrom u { buf := [], depth := d, live := true } = { buf := [], depth := d + 1, live := true }) R.scanFrom l.flatten { buf := [], depth := d, live := true } = { buf := [], depth := d + l.length, live := true }hl: u_1 u :: l, (d : ), R.scanFrom u_1 { buf := [], depth := d, live := true } = { buf := [], depth := d + 1, live := true }{ buf := [], depth := d + l.length + 1, live := true } = { buf := [], depth := d + (l.length + 1), live := true } All goals completed! 🐙) ws hw

A spelling raises the pending count by one, whatever the count before it.

theorem scanFrom_spell (R : RankedAlphabet) (t : R.Term) (d : ) : R.scanFrom (R.spell t) [], d, true = [], d + 1, true := Term.induction (motive := fun t d, R.scanFrom (R.spell t) [], d, true = [], d + 1, true) (fun i ch ih d R:RankedAlphabett:R.Termd✝:i:Fin R.cardch:Fin (R.arity i) R.Termih: (d : Fin (R.arity i)) (d_1 : ), R.scanFrom (R.spell (ch d)) { buf := [], depth := d_1, live := true } = { buf := [], depth := d_1 + 1, live := true }d:R.scanFrom (R.spell (Term.mk R i ch)) { buf := [], depth := d, live := true } = { buf := [], depth := d + 1, live := true } R:RankedAlphabett:R.Termd✝:i:Fin R.cardch:Fin (R.arity i) R.Termih: (d : Fin (R.arity i)) (d_1 : ), R.scanFrom (R.spell (ch d)) { buf := [], depth := d_1, live := true } = { buf := [], depth := d_1 + 1, live := true }d:{ buf := [], depth := d + R.arity i - R.arity i + 1, live := true } = { buf := [], depth := d + 1, live := true } R:RankedAlphabett:R.Termd✝:i:Fin R.cardch:Fin (R.arity i) R.Termih: (d : Fin (R.arity i)) (d_1 : ), R.scanFrom (R.spell (ch d)) { buf := [], depth := d_1, live := true } = { buf := [], depth := d_1 + 1, live := true }d:d + R.arity i - R.arity i + 1 = d + 1 All goals completed! 🐙) t d

Every spelling is valid.

theorem valid_spell (R : RankedAlphabet) (t : R.Term) : R.Valid (R.spell t) := R:RankedAlphabett:R.TermR.Valid (R.spell t) R:RankedAlphabett:R.Term({ buf := [], depth := 0 + 1, live := true }.live && { buf := [], depth := 0 + 1, live := true }.buf.isEmpty && { buf := [], depth := 0 + 1, live := true }.depth == 1) = true All goals completed! 🐙

The residue of a successor, in terms of the residue. Stated here rather than taken from Nat's division API for the reason mod_two_mul is: the modulus is a variable, so omega cannot discharge it, and the lemmas of that API which do state it depend on Classical.choice.

theorem add_one_mod (a n : ) (hn : 0 < n) : (a + 1) % n = if a % n + 1 = n then 0 else a % n + 1 := a:n:hn:0 < n(a + 1) % n = if a % n + 1 = n then 0 else a % n + 1 a:n:hn:0 < nhsplit:(a + 1) % n = (a % n + 1) % n(a + 1) % n = if a % n + 1 = n then 0 else a % n + 1 a:n:hn:0 < nhsplit:(a + 1) % n = (a % n + 1) % n(a % n + 1) % n = if a % n + 1 = n then 0 else a % n + 1 a:n:hn:0 < nhsplit:(a + 1) % n = (a % n + 1) % nh✝:a % n + 1 = n(a % n + 1) % n = 0a:n:hn:0 < nhsplit:(a + 1) % n = (a % n + 1) % nh✝:¬a % n + 1 = n(a % n + 1) % n = a % n + 1 a:n:hn:0 < nhsplit:(a + 1) % n = (a % n + 1) % nh✝:a % n + 1 = n(a % n + 1) % n = 0 a:n:hn:0 < nhsplit:(a + 1) % n = (a % n + 1) % nh:a % n + 1 = n(a % n + 1) % n = 0 All goals completed! 🐙 a:n:hn:0 < nhsplit:(a + 1) % n = (a % n + 1) % nh✝:¬a % n + 1 = n(a % n + 1) % n = a % n + 1 a:n:hn:0 < nhsplit:(a + 1) % n = (a % n + 1) % nh:¬a % n + 1 = n(a % n + 1) % n = a % n + 1 a:n:hn:0 < nhsplit:(a + 1) % n = (a % n + 1) % nh:¬a % n + 1 = nhr:a % n < n(a % n + 1) % n = a % n + 1 exact Nat.mod_eq_of_lt (a:n:hn:0 < nhsplit:(a + 1) % n = (a % n + 1) % nh:¬a % n + 1 = nhr:a % n < na % n + 1 < n All goals completed! 🐙)

A step leaving the scan live: the state before it was live, and the step either accumulated the bit into an incomplete block or completed one, in which case its symbol popped that symbol's arity and pushed one.

theorem scanStep_eq_of_live (R : RankedAlphabet) (b : Bool) (s : Scan) (h : (R.scanStep b s).live = true) : s.live = true (((b :: s.buf).length R.width R.scanStep b s = b :: s.buf, s.depth, true) r, (b :: s.buf).length = R.width R.arOf (decodeBits (b :: s.buf)) = some r r s.depth R.scanStep b s = [], s.depth - r + 1, true) := R:RankedAlphabetb:Bools:Scanh:(R.scanStep b s).live = trues.live = true ((b :: s.buf).length R.width R.scanStep b s = { buf := b :: s.buf, depth := s.depth, live := true } r, (b :: s.buf).length = R.width R.arOf (decodeBits (b :: s.buf)) = some r r s.depth R.scanStep b s = { buf := [], depth := s.depth - r + 1, live := true }) cases hlive : s.live with R:RankedAlphabetb:Bools:Scanh:(R.scanStep b s).live = truehlive:s.live = falsefalse = true ((b :: s.buf).length R.width R.scanStep b s = { buf := b :: s.buf, depth := s.depth, live := true } r, (b :: s.buf).length = R.width R.arOf (decodeBits (b :: s.buf)) = some r r s.depth R.scanStep b s = { buf := [], depth := s.depth - r + 1, live := true }) R:RankedAlphabetb:Bools:Scanhlive:s.live = falseh:false = truefalse = true ((b :: s.buf).length R.width R.scanStep b s = { buf := b :: s.buf, depth := s.depth, live := true } r, (b :: s.buf).length = R.width R.arOf (decodeBits (b :: s.buf)) = some r r s.depth R.scanStep b s = { buf := [], depth := s.depth - r + 1, live := true }) All goals completed! 🐙 R:RankedAlphabetb:Bools:Scanh:(R.scanStep b s).live = truehlive:s.live = truetrue = true ((b :: s.buf).length R.width R.scanStep b s = { buf := b :: s.buf, depth := s.depth, live := true } r, (b :: s.buf).length = R.width R.arOf (decodeBits (b :: s.buf)) = some r r s.depth R.scanStep b s = { buf := [], depth := s.depth - r + 1, live := true }) R:RankedAlphabetb:Bools:Scanh:(R.scanStep b s).live = truehlive:s.live = true(b :: s.buf).length R.width R.scanStep b s = { buf := b :: s.buf, depth := s.depth, live := true } r, (b :: s.buf).length = R.width R.arOf (decodeBits (b :: s.buf)) = some r r s.depth R.scanStep b s = { buf := [], depth := s.depth - r + 1, live := true } cases hc : decide ((b :: s.buf).length = R.width) with R:RankedAlphabetb:Bools:Scanh:(R.scanStep b s).live = truehlive:s.live = truehc:decide ((b :: s.buf).length = R.width) = false(b :: s.buf).length R.width R.scanStep b s = { buf := b :: s.buf, depth := s.depth, live := true } r, (b :: s.buf).length = R.width R.arOf (decodeBits (b :: s.buf)) = some r r s.depth R.scanStep b s = { buf := [], depth := s.depth - r + 1, live := true } R:RankedAlphabetb:Bools:Scanh:(R.scanStep b s).live = truehlive:s.live = truehc:decide ((b :: s.buf).length = R.width) = falseR.scanStep b s = { buf := b :: s.buf, depth := s.depth, live := true } All goals completed! 🐙 R:RankedAlphabetb:Bools:Scanh:(R.scanStep b s).live = truehlive:s.live = truehc:decide ((b :: s.buf).length = R.width) = true(b :: s.buf).length R.width R.scanStep b s = { buf := b :: s.buf, depth := s.depth, live := true } r, (b :: s.buf).length = R.width R.arOf (decodeBits (b :: s.buf)) = some r r s.depth R.scanStep b s = { buf := [], depth := s.depth - r + 1, live := true } cases har : R.arOf (decodeBits (b :: s.buf)) with R:RankedAlphabetb:Bools:Scanh:(R.scanStep b s).live = truehlive:s.live = truehc:decide ((b :: s.buf).length = R.width) = truehar:R.arOf (decodeBits (b :: s.buf)) = none(b :: s.buf).length R.width R.scanStep b s = { buf := b :: s.buf, depth := s.depth, live := true } r, (b :: s.buf).length = R.width none = some r r s.depth R.scanStep b s = { buf := [], depth := s.depth - r + 1, live := true } R:RankedAlphabetb:Bools:Scanhlive:s.live = truehc:decide ((b :: s.buf).length = R.width) = truehar:R.arOf (decodeBits (b :: s.buf)) = noneh:false = true(b :: s.buf).length R.width R.scanStep b s = { buf := b :: s.buf, depth := s.depth, live := true } r, (b :: s.buf).length = R.width none = some r r s.depth R.scanStep b s = { buf := [], depth := s.depth - r + 1, live := true } All goals completed! 🐙 R:RankedAlphabetb:Bools:Scanh:(R.scanStep b s).live = truehlive:s.live = truehc:decide ((b :: s.buf).length = R.width) = truer:har:R.arOf (decodeBits (b :: s.buf)) = some r(b :: s.buf).length R.width R.scanStep b s = { buf := b :: s.buf, depth := s.depth, live := true } r_1, (b :: s.buf).length = R.width some r = some r_1 r_1 s.depth R.scanStep b s = { buf := [], depth := s.depth - r_1 + 1, live := true } cases hle : decide (r s.depth) with R:RankedAlphabetb:Bools:Scanh:(R.scanStep b s).live = truehlive:s.live = truehc:decide ((b :: s.buf).length = R.width) = truer:har:R.arOf (decodeBits (b :: s.buf)) = some rhle:decide (r s.depth) = false(b :: s.buf).length R.width R.scanStep b s = { buf := b :: s.buf, depth := s.depth, live := true } r_1, (b :: s.buf).length = R.width some r = some r_1 r_1 s.depth R.scanStep b s = { buf := [], depth := s.depth - r_1 + 1, live := true } R:RankedAlphabetb:Bools:Scanhlive:s.live = truehc:decide ((b :: s.buf).length = R.width) = truer:har:R.arOf (decodeBits (b :: s.buf)) = some rhle:decide (r s.depth) = falseh:false = true(b :: s.buf).length R.width R.scanStep b s = { buf := b :: s.buf, depth := s.depth, live := true } r_1, (b :: s.buf).length = R.width some r = some r_1 r_1 s.depth R.scanStep b s = { buf := [], depth := s.depth - r_1 + 1, live := true } All goals completed! 🐙 R:RankedAlphabetb:Bools:Scanh:(R.scanStep b s).live = truehlive:s.live = truehc:decide ((b :: s.buf).length = R.width) = truer:har:R.arOf (decodeBits (b :: s.buf)) = some rhle:decide (r s.depth) = true(b :: s.buf).length R.width R.scanStep b s = { buf := b :: s.buf, depth := s.depth, live := true } r_1, (b :: s.buf).length = R.width some r = some r_1 r_1 s.depth R.scanStep b s = { buf := [], depth := s.depth - r_1 + 1, live := true } exact Or.inr r, of_decide_eq_true hc, rfl, of_decide_eq_true hle, R:RankedAlphabetb:Bools:Scanh:(R.scanStep b s).live = truehlive:s.live = truehc:decide ((b :: s.buf).length = R.width) = truer:har:R.arOf (decodeBits (b :: s.buf)) = some rhle:decide (r s.depth) = trueR.scanStep b s = { buf := [], depth := s.depth - r + 1, live := true } All goals completed! 🐙

A live scan's incomplete block holds the word's length modulo the width: block boundaries align with the word's right end.

theorem length_buf_scanFinal_of_live (R : RankedAlphabet) : w : List Bool, (R.scanFinal w).live = true (R.scanFinal w).buf.length = w.length % R.width := List.rec (fun _ R:RankedAlphabetx✝:(R.scanFinal []).live = true(R.scanFinal []).buf.length = [].length % R.width All goals completed! 🐙) (fun b v ih hlive R:RankedAlphabetb:Boolv:List Boolih:(R.scanFinal v).live = true (R.scanFinal v).buf.length = v.length % R.widthhlive:(R.scanFinal (b :: v)).live = true(R.scanFinal (b :: v)).buf.length = (b :: v).length % R.width R:RankedAlphabetb:Boolv:List Boolih:(R.scanFinal v).live = true (R.scanFinal v).buf.length = v.length % R.widthhlive:(R.scanStep b (R.scanFinal v)).live = true(R.scanStep b (R.scanFinal v)).buf.length = (b :: v).length % R.width R:RankedAlphabetb:Boolv:List Boolih:(R.scanFinal v).live = true (R.scanFinal v).buf.length = v.length % R.widthhlive:(R.scanStep b (R.scanFinal v)).live = truehv:(R.scanFinal v).live = truehcase:(b :: (R.scanFinal v).buf).length R.width R.scanStep b (R.scanFinal v) = { buf := b :: (R.scanFinal v).buf, depth := (R.scanFinal v).depth, live := true } r, (b :: (R.scanFinal v).buf).length = R.width R.arOf (decodeBits (b :: (R.scanFinal v).buf)) = some r r (R.scanFinal v).depth R.scanStep b (R.scanFinal v) = { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }(R.scanStep b (R.scanFinal v)).buf.length = (b :: v).length % R.width R:RankedAlphabetb:Boolv:List Boolih:(R.scanFinal v).live = true (R.scanFinal v).buf.length = v.length % R.widthhlive:(R.scanStep b (R.scanFinal v)).live = truehv:(R.scanFinal v).live = truehcase:(b :: (R.scanFinal v).buf).length R.width R.scanStep b (R.scanFinal v) = { buf := b :: (R.scanFinal v).buf, depth := (R.scanFinal v).depth, live := true } r, (b :: (R.scanFinal v).buf).length = R.width R.arOf (decodeBits (b :: (R.scanFinal v).buf)) = some r r (R.scanFinal v).depth R.scanStep b (R.scanFinal v) = { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }ihv:(R.scanFinal v).buf.length = v.length % R.width(R.scanStep b (R.scanFinal v)).buf.length = (b :: v).length % R.width R:RankedAlphabetb:Boolv:List Boolih:(R.scanFinal v).live = true (R.scanFinal v).buf.length = v.length % R.widthhlive:(R.scanStep b (R.scanFinal v)).live = truehv:(R.scanFinal v).live = trueihv:(R.scanFinal v).buf.length = v.length % R.widthhne:(b :: (R.scanFinal v).buf).length R.widthheq:R.scanStep b (R.scanFinal v) = { buf := b :: (R.scanFinal v).buf, depth := (R.scanFinal v).depth, live := true }(R.scanStep b (R.scanFinal v)).buf.length = (b :: v).length % R.widthR:RankedAlphabetb:Boolv:List Boolih:(R.scanFinal v).live = true (R.scanFinal v).buf.length = v.length % R.widthhlive:(R.scanStep b (R.scanFinal v)).live = truehv:(R.scanFinal v).live = trueihv:(R.scanFinal v).buf.length = v.length % R.widthr:hlen:(b :: (R.scanFinal v).buf).length = R.widthleft✝¹:R.arOf (decodeBits (b :: (R.scanFinal v).buf)) = some rleft✝:r (R.scanFinal v).depthheq:R.scanStep b (R.scanFinal v) = { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }(R.scanStep b (R.scanFinal v)).buf.length = (b :: v).length % R.width R:RankedAlphabetb:Boolv:List Boolih:(R.scanFinal v).live = true (R.scanFinal v).buf.length = v.length % R.widthhlive:(R.scanStep b (R.scanFinal v)).live = truehv:(R.scanFinal v).live = trueihv:(R.scanFinal v).buf.length = v.length % R.widthhne:(b :: (R.scanFinal v).buf).length R.widthheq:R.scanStep b (R.scanFinal v) = { buf := b :: (R.scanFinal v).buf, depth := (R.scanFinal v).depth, live := true }(R.scanStep b (R.scanFinal v)).buf.length = (b :: v).length % R.width R:RankedAlphabetb:Boolv:List Boolih:(R.scanFinal v).live = true (R.scanFinal v).buf.length = v.length % R.widthhlive:(R.scanStep b (R.scanFinal v)).live = truehv:(R.scanFinal v).live = trueihv:(R.scanFinal v).buf.length = v.length % R.widthhne:(R.scanFinal v).buf.length + 1 R.widthheq:R.scanStep b (R.scanFinal v) = { buf := b :: (R.scanFinal v).buf, depth := (R.scanFinal v).depth, live := true }(R.scanFinal v).buf.length + 1 = (v.length + 1) % R.width R:RankedAlphabetb:Boolv:List Boolih:(R.scanFinal v).live = true (R.scanFinal v).buf.length = v.length % R.widthhlive:(R.scanStep b (R.scanFinal v)).live = truehv:(R.scanFinal v).live = trueihv:(R.scanFinal v).buf.length = v.length % R.widthhne:v.length % R.width + 1 R.widthheq:R.scanStep b (R.scanFinal v) = { buf := b :: (R.scanFinal v).buf, depth := (R.scanFinal v).depth, live := true }(R.scanFinal v).buf.length + 1 = (v.length + 1) % R.width All goals completed! 🐙 R:RankedAlphabetb:Boolv:List Boolih:(R.scanFinal v).live = true (R.scanFinal v).buf.length = v.length % R.widthhlive:(R.scanStep b (R.scanFinal v)).live = truehv:(R.scanFinal v).live = trueihv:(R.scanFinal v).buf.length = v.length % R.widthr:hlen:(b :: (R.scanFinal v).buf).length = R.widthleft✝¹:R.arOf (decodeBits (b :: (R.scanFinal v).buf)) = some rleft✝:r (R.scanFinal v).depthheq:R.scanStep b (R.scanFinal v) = { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }(R.scanStep b (R.scanFinal v)).buf.length = (b :: v).length % R.width R:RankedAlphabetb:Boolv:List Boolih:(R.scanFinal v).live = true (R.scanFinal v).buf.length = v.length % R.widthhlive:(R.scanStep b (R.scanFinal v)).live = truehv:(R.scanFinal v).live = trueihv:(R.scanFinal v).buf.length = v.length % R.widthr:hlen:(R.scanFinal v).buf.length + 1 = R.widthleft✝¹:R.arOf (decodeBits (b :: (R.scanFinal v).buf)) = some rleft✝:r (R.scanFinal v).depthheq:R.scanStep b (R.scanFinal v) = { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }(R.scanStep b (R.scanFinal v)).buf.length = (b :: v).length % R.width R:RankedAlphabetb:Boolv:List Boolih:(R.scanFinal v).live = true (R.scanFinal v).buf.length = v.length % R.widthhlive:(R.scanStep b (R.scanFinal v)).live = truehv:(R.scanFinal v).live = trueihv:(R.scanFinal v).buf.length = v.length % R.widthr:hlen:v.length % R.width + 1 = R.widthleft✝¹:R.arOf (decodeBits (b :: (R.scanFinal v).buf)) = some rleft✝:r (R.scanFinal v).depthheq:R.scanStep b (R.scanFinal v) = { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }(R.scanStep b (R.scanFinal v)).buf.length = (b :: v).length % R.width R:RankedAlphabetb:Boolv:List Boolih:(R.scanFinal v).live = true (R.scanFinal v).buf.length = v.length % R.widthhlive:(R.scanStep b (R.scanFinal v)).live = truehv:(R.scanFinal v).live = trueihv:(R.scanFinal v).buf.length = v.length % R.widthr:hlen:v.length % R.width + 1 = R.widthleft✝¹:R.arOf (decodeBits (b :: (R.scanFinal v).buf)) = some rleft✝:r (R.scanFinal v).depthheq:R.scanStep b (R.scanFinal v) = { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }0 = (v.length + 1) % R.width All goals completed! 🐙)

The incomplete block never fills, whether or not the scan has failed. Stated unconditionally, which is the form a bitstring layout of the state consumes; the List.rec below establishes the live and failed cases at once rather than through length_buf_scanFinal_of_live.

theorem length_buf_scanFinal_lt (R : RankedAlphabet) (w : List Bool) : (R.scanFinal w).buf.length < R.width := List.rec R.width_pos (fun b v ih R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).buf.length < R.width(R.scanFinal (b :: v)).buf.length < R.width R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).buf.length < R.width(match (R.scanFinal v).live with | false => R.scanFinal v | true => match decide ((b :: (R.scanFinal v).buf).length = R.width) with | false => { buf := b :: (R.scanFinal v).buf, depth := (R.scanFinal v).depth, live := true } | true => match R.arOf (decodeBits (b :: (R.scanFinal v).buf)) with | none => { buf := [], depth := (R.scanFinal v).depth, live := false } | some r => match decide (r (R.scanFinal v).depth) with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }).buf.length < R.width R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).buf.length < R.width(match false with | false => R.scanFinal v | true => match decide ((b :: (R.scanFinal v).buf).length = R.width) with | false => { buf := b :: (R.scanFinal v).buf, depth := (R.scanFinal v).depth, live := true } | true => match R.arOf (decodeBits (b :: (R.scanFinal v).buf)) with | none => { buf := [], depth := (R.scanFinal v).depth, live := false } | some r => match decide (r (R.scanFinal v).depth) with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }).buf.length < R.widthR:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).buf.length < R.width(match true with | false => R.scanFinal v | true => match decide ((b :: (R.scanFinal v).buf).length = R.width) with | false => { buf := b :: (R.scanFinal v).buf, depth := (R.scanFinal v).depth, live := true } | true => match R.arOf (decodeBits (b :: (R.scanFinal v).buf)) with | none => { buf := [], depth := (R.scanFinal v).depth, live := false } | some r => match decide (r (R.scanFinal v).depth) with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }).buf.length < R.width R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).buf.length < R.width(match false with | false => R.scanFinal v | true => match decide ((b :: (R.scanFinal v).buf).length = R.width) with | false => { buf := b :: (R.scanFinal v).buf, depth := (R.scanFinal v).depth, live := true } | true => match R.arOf (decodeBits (b :: (R.scanFinal v).buf)) with | none => { buf := [], depth := (R.scanFinal v).depth, live := false } | some r => match decide (r (R.scanFinal v).depth) with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }).buf.length < R.width All goals completed! 🐙 R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).buf.length < R.width(match true with | false => R.scanFinal v | true => match decide ((b :: (R.scanFinal v).buf).length = R.width) with | false => { buf := b :: (R.scanFinal v).buf, depth := (R.scanFinal v).depth, live := true } | true => match R.arOf (decodeBits (b :: (R.scanFinal v).buf)) with | none => { buf := [], depth := (R.scanFinal v).depth, live := false } | some r => match decide (r (R.scanFinal v).depth) with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }).buf.length < R.width R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).buf.length < R.width(match decide ((b :: (R.scanFinal v).buf).length = R.width) with | false => { buf := b :: (R.scanFinal v).buf, depth := (R.scanFinal v).depth, live := true } | true => match R.arOf (decodeBits (b :: (R.scanFinal v).buf)) with | none => { buf := [], depth := (R.scanFinal v).depth, live := false } | some r => match decide (r (R.scanFinal v).depth) with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }).buf.length < R.width R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).buf.length < R.widthhc:decide ((b :: (R.scanFinal v).buf).length = R.width) = false(match false with | false => { buf := b :: (R.scanFinal v).buf, depth := (R.scanFinal v).depth, live := true } | true => match R.arOf (decodeBits (b :: (R.scanFinal v).buf)) with | none => { buf := [], depth := (R.scanFinal v).depth, live := false } | some r => match decide (r (R.scanFinal v).depth) with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }).buf.length < R.widthR:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).buf.length < R.widthhc:decide ((b :: (R.scanFinal v).buf).length = R.width) = true(match true with | false => { buf := b :: (R.scanFinal v).buf, depth := (R.scanFinal v).depth, live := true } | true => match R.arOf (decodeBits (b :: (R.scanFinal v).buf)) with | none => { buf := [], depth := (R.scanFinal v).depth, live := false } | some r => match decide (r (R.scanFinal v).depth) with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }).buf.length < R.width R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).buf.length < R.widthhc:decide ((b :: (R.scanFinal v).buf).length = R.width) = false(match false with | false => { buf := b :: (R.scanFinal v).buf, depth := (R.scanFinal v).depth, live := true } | true => match R.arOf (decodeBits (b :: (R.scanFinal v).buf)) with | none => { buf := [], depth := (R.scanFinal v).depth, live := false } | some r => match decide (r (R.scanFinal v).depth) with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }).buf.length < R.width R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).buf.length < R.widthhc:decide ((R.scanFinal v).buf.length + 1 = R.width) = false(R.scanFinal v).buf.length + 1 < R.width R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).buf.length < R.widthhc:decide ((R.scanFinal v).buf.length + 1 = R.width) = falsethis:¬(R.scanFinal v).buf.length + 1 = R.width(R.scanFinal v).buf.length + 1 < R.width All goals completed! 🐙 R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).buf.length < R.widthhc:decide ((b :: (R.scanFinal v).buf).length = R.width) = true(match true with | false => { buf := b :: (R.scanFinal v).buf, depth := (R.scanFinal v).depth, live := true } | true => match R.arOf (decodeBits (b :: (R.scanFinal v).buf)) with | none => { buf := [], depth := (R.scanFinal v).depth, live := false } | some r => match decide (r (R.scanFinal v).depth) with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }).buf.length < R.width R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).buf.length < R.widthhc:decide ((b :: (R.scanFinal v).buf).length = R.width) = true(match R.arOf (decodeBits (b :: (R.scanFinal v).buf)) with | none => { buf := [], depth := (R.scanFinal v).depth, live := false } | some r => match decide (r (R.scanFinal v).depth) with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }).buf.length < R.width R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).buf.length < R.widthhc:decide ((b :: (R.scanFinal v).buf).length = R.width) = true(match none with | none => { buf := [], depth := (R.scanFinal v).depth, live := false } | some r => match decide (r (R.scanFinal v).depth) with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }).buf.length < R.widthR:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).buf.length < R.widthhc:decide ((b :: (R.scanFinal v).buf).length = R.width) = trueval✝:(match some val✝ with | none => { buf := [], depth := (R.scanFinal v).depth, live := false } | some r => match decide (r (R.scanFinal v).depth) with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }).buf.length < R.width R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).buf.length < R.widthhc:decide ((b :: (R.scanFinal v).buf).length = R.width) = true(match none with | none => { buf := [], depth := (R.scanFinal v).depth, live := false } | some r => match decide (r (R.scanFinal v).depth) with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }).buf.length < R.width All goals completed! 🐙 R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).buf.length < R.widthhc:decide ((b :: (R.scanFinal v).buf).length = R.width) = trueval✝:(match some val✝ with | none => { buf := [], depth := (R.scanFinal v).depth, live := false } | some r => match decide (r (R.scanFinal v).depth) with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }).buf.length < R.width R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).buf.length < R.widthhc:decide ((b :: (R.scanFinal v).buf).length = R.width) = trueval✝:(match decide (val✝ (R.scanFinal v).depth) with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - val✝ + 1, live := true }).buf.length < R.width R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).buf.length < R.widthhc:decide ((b :: (R.scanFinal v).buf).length = R.width) = trueval✝:(match false with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - val✝ + 1, live := true }).buf.length < R.widthR:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).buf.length < R.widthhc:decide ((b :: (R.scanFinal v).buf).length = R.width) = trueval✝:(match true with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - val✝ + 1, live := true }).buf.length < R.width R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).buf.length < R.widthhc:decide ((b :: (R.scanFinal v).buf).length = R.width) = trueval✝:(match false with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - val✝ + 1, live := true }).buf.length < R.widthR:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).buf.length < R.widthhc:decide ((b :: (R.scanFinal v).buf).length = R.width) = trueval✝:(match true with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - val✝ + 1, live := true }).buf.length < R.width All goals completed! 🐙) w

The pending count is at most the word's length: every clause but the pop leaves it alone, and the pop raises it by at most one.

theorem depth_scanFinal_le_length (R : RankedAlphabet) (w : List Bool) : (R.scanFinal w).depth w.length := List.rec (Nat.le_refl 0) (fun b v ih R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).depth v.length(R.scanFinal (b :: v)).depth (b :: v).length R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).depth v.lengthhlen:(b :: v).length = v.length + 1(R.scanFinal (b :: v)).depth (b :: v).length R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).depth v.lengthhlen:(b :: v).length = v.length + 1(match (R.scanFinal v).live with | false => R.scanFinal v | true => match decide ((b :: (R.scanFinal v).buf).length = R.width) with | false => { buf := b :: (R.scanFinal v).buf, depth := (R.scanFinal v).depth, live := true } | true => match R.arOf (decodeBits (b :: (R.scanFinal v).buf)) with | none => { buf := [], depth := (R.scanFinal v).depth, live := false } | some r => match decide (r (R.scanFinal v).depth) with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }).depth (b :: v).length R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).depth v.lengthhlen:(b :: v).length = v.length + 1(match false with | false => R.scanFinal v | true => match decide ((b :: (R.scanFinal v).buf).length = R.width) with | false => { buf := b :: (R.scanFinal v).buf, depth := (R.scanFinal v).depth, live := true } | true => match R.arOf (decodeBits (b :: (R.scanFinal v).buf)) with | none => { buf := [], depth := (R.scanFinal v).depth, live := false } | some r => match decide (r (R.scanFinal v).depth) with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }).depth (b :: v).lengthR:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).depth v.lengthhlen:(b :: v).length = v.length + 1(match true with | false => R.scanFinal v | true => match decide ((b :: (R.scanFinal v).buf).length = R.width) with | false => { buf := b :: (R.scanFinal v).buf, depth := (R.scanFinal v).depth, live := true } | true => match R.arOf (decodeBits (b :: (R.scanFinal v).buf)) with | none => { buf := [], depth := (R.scanFinal v).depth, live := false } | some r => match decide (r (R.scanFinal v).depth) with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }).depth (b :: v).length R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).depth v.lengthhlen:(b :: v).length = v.length + 1(match false with | false => R.scanFinal v | true => match decide ((b :: (R.scanFinal v).buf).length = R.width) with | false => { buf := b :: (R.scanFinal v).buf, depth := (R.scanFinal v).depth, live := true } | true => match R.arOf (decodeBits (b :: (R.scanFinal v).buf)) with | none => { buf := [], depth := (R.scanFinal v).depth, live := false } | some r => match decide (r (R.scanFinal v).depth) with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }).depth (b :: v).length R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).depth v.lengthhlen:(b :: v).length = v.length + 1(R.scanFinal v).depth (b :: v).length All goals completed! 🐙 R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).depth v.lengthhlen:(b :: v).length = v.length + 1(match true with | false => R.scanFinal v | true => match decide ((b :: (R.scanFinal v).buf).length = R.width) with | false => { buf := b :: (R.scanFinal v).buf, depth := (R.scanFinal v).depth, live := true } | true => match R.arOf (decodeBits (b :: (R.scanFinal v).buf)) with | none => { buf := [], depth := (R.scanFinal v).depth, live := false } | some r => match decide (r (R.scanFinal v).depth) with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }).depth (b :: v).length R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).depth v.lengthhlen:(b :: v).length = v.length + 1(match decide ((b :: (R.scanFinal v).buf).length = R.width) with | false => { buf := b :: (R.scanFinal v).buf, depth := (R.scanFinal v).depth, live := true } | true => match R.arOf (decodeBits (b :: (R.scanFinal v).buf)) with | none => { buf := [], depth := (R.scanFinal v).depth, live := false } | some r => match decide (r (R.scanFinal v).depth) with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }).depth (b :: v).length R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).depth v.lengthhlen:(b :: v).length = v.length + 1(match false with | false => { buf := b :: (R.scanFinal v).buf, depth := (R.scanFinal v).depth, live := true } | true => match R.arOf (decodeBits (b :: (R.scanFinal v).buf)) with | none => { buf := [], depth := (R.scanFinal v).depth, live := false } | some r => match decide (r (R.scanFinal v).depth) with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }).depth (b :: v).lengthR:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).depth v.lengthhlen:(b :: v).length = v.length + 1(match true with | false => { buf := b :: (R.scanFinal v).buf, depth := (R.scanFinal v).depth, live := true } | true => match R.arOf (decodeBits (b :: (R.scanFinal v).buf)) with | none => { buf := [], depth := (R.scanFinal v).depth, live := false } | some r => match decide (r (R.scanFinal v).depth) with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }).depth (b :: v).length R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).depth v.lengthhlen:(b :: v).length = v.length + 1(match false with | false => { buf := b :: (R.scanFinal v).buf, depth := (R.scanFinal v).depth, live := true } | true => match R.arOf (decodeBits (b :: (R.scanFinal v).buf)) with | none => { buf := [], depth := (R.scanFinal v).depth, live := false } | some r => match decide (r (R.scanFinal v).depth) with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }).depth (b :: v).length R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).depth v.lengthhlen:(b :: v).length = v.length + 1(R.scanFinal v).depth (b :: v).length All goals completed! 🐙 R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).depth v.lengthhlen:(b :: v).length = v.length + 1(match true with | false => { buf := b :: (R.scanFinal v).buf, depth := (R.scanFinal v).depth, live := true } | true => match R.arOf (decodeBits (b :: (R.scanFinal v).buf)) with | none => { buf := [], depth := (R.scanFinal v).depth, live := false } | some r => match decide (r (R.scanFinal v).depth) with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }).depth (b :: v).length R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).depth v.lengthhlen:(b :: v).length = v.length + 1(match R.arOf (decodeBits (b :: (R.scanFinal v).buf)) with | none => { buf := [], depth := (R.scanFinal v).depth, live := false } | some r => match decide (r (R.scanFinal v).depth) with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }).depth (b :: v).length R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).depth v.lengthhlen:(b :: v).length = v.length + 1(match none with | none => { buf := [], depth := (R.scanFinal v).depth, live := false } | some r => match decide (r (R.scanFinal v).depth) with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }).depth (b :: v).lengthR:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).depth v.lengthhlen:(b :: v).length = v.length + 1val✝:(match some val✝ with | none => { buf := [], depth := (R.scanFinal v).depth, live := false } | some r => match decide (r (R.scanFinal v).depth) with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }).depth (b :: v).length R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).depth v.lengthhlen:(b :: v).length = v.length + 1(match none with | none => { buf := [], depth := (R.scanFinal v).depth, live := false } | some r => match decide (r (R.scanFinal v).depth) with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }).depth (b :: v).length R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).depth v.lengthhlen:(b :: v).length = v.length + 1(R.scanFinal v).depth (b :: v).length All goals completed! 🐙 R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).depth v.lengthhlen:(b :: v).length = v.length + 1val✝:(match some val✝ with | none => { buf := [], depth := (R.scanFinal v).depth, live := false } | some r => match decide (r (R.scanFinal v).depth) with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }).depth (b :: v).length R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).depth v.lengthhlen:(b :: v).length = v.length + 1val✝:(match decide (val✝ (R.scanFinal v).depth) with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - val✝ + 1, live := true }).depth (b :: v).length R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).depth v.lengthhlen:(b :: v).length = v.length + 1val✝:(match false with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - val✝ + 1, live := true }).depth (b :: v).lengthR:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).depth v.lengthhlen:(b :: v).length = v.length + 1val✝:(match true with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - val✝ + 1, live := true }).depth (b :: v).length R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).depth v.lengthhlen:(b :: v).length = v.length + 1val✝:(match false with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - val✝ + 1, live := true }).depth (b :: v).length R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).depth v.lengthhlen:(b :: v).length = v.length + 1val✝:(R.scanFinal v).depth (b :: v).length All goals completed! 🐙 R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).depth v.lengthhlen:(b :: v).length = v.length + 1val✝:(match true with | false => { buf := [], depth := (R.scanFinal v).depth, live := false } | true => { buf := [], depth := (R.scanFinal v).depth - val✝ + 1, live := true }).depth (b :: v).length R:RankedAlphabetw:List Boolb:Boolv:List Boolih:(R.scanFinal v).depth v.lengthhlen:(b :: v).length = v.length + 1val✝:(R.scanFinal v).depth - val✝ + 1 (b :: v).length All goals completed! 🐙) w

Validity as the three conditions on the final state, which is the form a statement about the state word consumes. The two directions take different routes: the forward one splits validBool's conjunction and reads each component, and the backward one closes by reduction once the fields are substituted.

theorem valid_iff_scanFinal (R : RankedAlphabet) (w : List Bool) : R.Valid w ((R.scanFinal w).live = true (R.scanFinal w).buf = [] (R.scanFinal w).depth = 1) := R:RankedAlphabetw:List BoolR.Valid w (R.scanFinal w).live = true (R.scanFinal w).buf = [] (R.scanFinal w).depth = 1 R:RankedAlphabetw:List BoolR.Valid w (R.scanFinal w).live = true (R.scanFinal w).buf = [] (R.scanFinal w).depth = 1R:RankedAlphabetw:List Bool(R.scanFinal w).live = true (R.scanFinal w).buf = [] (R.scanFinal w).depth = 1 R.Valid w R:RankedAlphabetw:List BoolR.Valid w (R.scanFinal w).live = true (R.scanFinal w).buf = [] (R.scanFinal w).depth = 1 R:RankedAlphabetw:List Boolhv:R.Valid w(R.scanFinal w).live = true (R.scanFinal w).buf = [] (R.scanFinal w).depth = 1 R:RankedAlphabetw:List Boolhv:R.Valid whb:((R.scanFinal w).live && (R.scanFinal w).buf.isEmpty && (R.scanFinal w).depth == 1) = true(R.scanFinal w).live = true (R.scanFinal w).buf = [] (R.scanFinal w).depth = 1 R:RankedAlphabetw:List Boolhv:R.Valid whb:((R.scanFinal w).live = true (R.scanFinal w).buf.isEmpty = true) ((R.scanFinal w).depth == 1) = true(R.scanFinal w).live = true (R.scanFinal w).buf = [] (R.scanFinal w).depth = 1 All goals completed! 🐙 R:RankedAlphabetw:List Bool(R.scanFinal w).live = true (R.scanFinal w).buf = [] (R.scanFinal w).depth = 1 R.Valid w R:RankedAlphabetw:List Boolhf:(R.scanFinal w).live = true (R.scanFinal w).buf = [] (R.scanFinal w).depth = 1R.Valid w R:RankedAlphabetw:List Boolhf:(R.scanFinal w).live = true (R.scanFinal w).buf = [] (R.scanFinal w).depth = 1((R.scanFinal w).live && (R.scanFinal w).buf.isEmpty && (R.scanFinal w).depth == 1) = true R:RankedAlphabetw:List Boolhf:(R.scanFinal w).live = true (R.scanFinal w).buf = [] (R.scanFinal w).depth = 1(true && [].isEmpty && 1 == 1) = true All goals completed! 🐙

The converse of scanFrom_code: a live scan over a full block exhibits that block as a symbol's code.

theorem exists_code_of_scanFrom_live (R : RankedAlphabet) (blk : List Bool) (s : Scan) (hlen : blk.length = R.width) (hbuf : s.buf = []) (hs : s.live = true) (h : (R.scanFrom blk s).live = true) : i : Fin R.card, R.code i = blk R.arity i s.depth R.scanFrom blk s = [], s.depth - R.arity i + 1, true := R:RankedAlphabetblk:List Bools:Scanhlen:blk.length = R.widthhbuf:s.buf = []hs:s.live = trueh:(R.scanFrom blk s).live = true i, R.code i = blk R.arity i s.depth R.scanFrom blk s = { buf := [], depth := s.depth - R.arity i + 1, live := true } R:RankedAlphabetblk:List Boolhlen:blk.length = R.widthsbuf:List Boolsdepth:slive:Boolhbuf:{ buf := sbuf, depth := sdepth, live := slive }.buf = []hs:{ buf := sbuf, depth := sdepth, live := slive }.live = trueh:(R.scanFrom blk { buf := sbuf, depth := sdepth, live := slive }).live = true i, R.code i = blk R.arity i { buf := sbuf, depth := sdepth, live := slive }.depth R.scanFrom blk { buf := sbuf, depth := sdepth, live := slive } = { buf := [], depth := { buf := sbuf, depth := sdepth, live := slive }.depth - R.arity i + 1, live := true } R:RankedAlphabetblk:List Boolhlen:blk.length = R.widthsbuf:List Boolsdepth:slive:Boolhbuf:sbuf = []hs:slive = trueh:(R.scanFrom blk { buf := sbuf, depth := sdepth, live := slive }).live = true i, R.code i = blk R.arity i { buf := sbuf, depth := sdepth, live := slive }.depth R.scanFrom blk { buf := sbuf, depth := sdepth, live := slive } = { buf := [], depth := { buf := sbuf, depth := sdepth, live := slive }.depth - R.arity i + 1, live := true } R:RankedAlphabetblk:List Boolhlen:blk.length = R.widthsdepth:slive:Boolhs:slive = trueh:(R.scanFrom blk { buf := [], depth := sdepth, live := slive }).live = true i, R.code i = blk R.arity i { buf := [], depth := sdepth, live := slive }.depth R.scanFrom blk { buf := [], depth := sdepth, live := slive } = { buf := [], depth := { buf := [], depth := sdepth, live := slive }.depth - R.arity i + 1, live := true } R:RankedAlphabetblk:List Boolhlen:blk.length = R.widthsdepth:h:(R.scanFrom blk { buf := [], depth := sdepth, live := true }).live = true i, R.code i = blk R.arity i { buf := [], depth := sdepth, live := true }.depth R.scanFrom blk { buf := [], depth := sdepth, live := true } = { buf := [], depth := { buf := [], depth := sdepth, live := true }.depth - R.arity i + 1, live := true } R:RankedAlphabetblk:List Boolhlen:blk.length = R.widthsdepth:h:(R.scanFrom blk { buf := [], depth := sdepth, live := true }).live = trueb:Boolv:List Boolhblk:blk = b :: v i, R.code i = blk R.arity i { buf := [], depth := sdepth, live := true }.depth R.scanFrom blk { buf := [], depth := sdepth, live := true } = { buf := [], depth := { buf := [], depth := sdepth, live := true }.depth - R.arity i + 1, live := true } R:RankedAlphabetsdepth:b:Boolv:List Boolhlen:(b :: v).length = R.widthh:(R.scanFrom (b :: v) { buf := [], depth := sdepth, live := true }).live = true i, R.code i = b :: v R.arity i { buf := [], depth := sdepth, live := true }.depth R.scanFrom (b :: v) { buf := [], depth := sdepth, live := true } = { buf := [], depth := { buf := [], depth := sdepth, live := true }.depth - R.arity i + 1, live := true } R:RankedAlphabetsdepth:b:Boolv:List Boolhlen:(b :: v).length = R.widthh:(R.scanFrom (b :: v) { buf := [], depth := sdepth, live := true }).live = truehshort:v.length + [].length < R.width i, R.code i = b :: v R.arity i { buf := [], depth := sdepth, live := true }.depth R.scanFrom (b :: v) { buf := [], depth := sdepth, live := true } = { buf := [], depth := { buf := [], depth := sdepth, live := true }.depth - R.arity i + 1, live := true } R:RankedAlphabetsdepth:b:Boolv:List Boolhlen:(b :: v).length = R.widthh:(R.scanStep b { buf := v, depth := sdepth, live := true }).live = truehshort:v.length + [].length < R.width i, R.code i = b :: v R.arity i { buf := [], depth := sdepth, live := true }.depth R.scanStep b { buf := v, depth := sdepth, live := true } = { buf := [], depth := { buf := [], depth := sdepth, live := true }.depth - R.arity i + 1, live := true } R:RankedAlphabetsdepth:b:Boolv:List Boolhlen:(b :: v).length = R.widthh:(R.scanStep b { buf := v, depth := sdepth, live := true }).live = truehshort:v.length + [].length < R.widthhcase:(b :: { buf := v, depth := sdepth, live := true }.buf).length R.width R.scanStep b { buf := v, depth := sdepth, live := true } = { buf := b :: { buf := v, depth := sdepth, live := true }.buf, depth := { buf := v, depth := sdepth, live := true }.depth, live := true } r, (b :: { buf := v, depth := sdepth, live := true }.buf).length = R.width R.arOf (decodeBits (b :: { buf := v, depth := sdepth, live := true }.buf)) = some r r { buf := v, depth := sdepth, live := true }.depth R.scanStep b { buf := v, depth := sdepth, live := true } = { buf := [], depth := { buf := v, depth := sdepth, live := true }.depth - r + 1, live := true } i, R.code i = b :: v R.arity i { buf := [], depth := sdepth, live := true }.depth R.scanStep b { buf := v, depth := sdepth, live := true } = { buf := [], depth := { buf := [], depth := sdepth, live := true }.depth - R.arity i + 1, live := true } R:RankedAlphabetsdepth:b:Boolv:List Boolhlen:(b :: v).length = R.widthh:(R.scanStep b { buf := v, depth := sdepth, live := true }).live = truehshort:v.length + [].length < R.widthhcase:(b :: v).length R.width R.scanStep b { buf := v, depth := sdepth, live := true } = { buf := b :: v, depth := sdepth, live := true } r, (b :: v).length = R.width R.arOf (decodeBits (b :: v)) = some r r sdepth R.scanStep b { buf := v, depth := sdepth, live := true } = { buf := [], depth := sdepth - r + 1, live := true } i, R.code i = b :: v R.arity i { buf := [], depth := sdepth, live := true }.depth R.scanStep b { buf := v, depth := sdepth, live := true } = { buf := [], depth := { buf := [], depth := sdepth, live := true }.depth - R.arity i + 1, live := true } R:RankedAlphabetsdepth:b:Boolv:List Boolhlen:(b :: v).length = R.widthh:(R.scanStep b { buf := v, depth := sdepth, live := true }).live = truehshort:v.length + [].length < R.widthhne:(b :: v).length R.width i, R.code i = b :: v R.arity i { buf := [], depth := sdepth, live := true }.depth R.scanStep b { buf := v, depth := sdepth, live := true } = { buf := [], depth := { buf := [], depth := sdepth, live := true }.depth - R.arity i + 1, live := true }R:RankedAlphabetsdepth:b:Boolv:List Boolhlen:(b :: v).length = R.widthh:(R.scanStep b { buf := v, depth := sdepth, live := true }).live = truehshort:v.length + [].length < R.widthr:har:R.arOf (decodeBits (b :: v)) = some rhle:r sdepthheq:R.scanStep b { buf := v, depth := sdepth, live := true } = { buf := [], depth := sdepth - r + 1, live := true } i, R.code i = b :: v R.arity i { buf := [], depth := sdepth, live := true }.depth R.scanStep b { buf := v, depth := sdepth, live := true } = { buf := [], depth := { buf := [], depth := sdepth, live := true }.depth - R.arity i + 1, live := true } R:RankedAlphabetsdepth:b:Boolv:List Boolhlen:(b :: v).length = R.widthh:(R.scanStep b { buf := v, depth := sdepth, live := true }).live = truehshort:v.length + [].length < R.widthhne:(b :: v).length R.width i, R.code i = b :: v R.arity i { buf := [], depth := sdepth, live := true }.depth R.scanStep b { buf := v, depth := sdepth, live := true } = { buf := [], depth := { buf := [], depth := sdepth, live := true }.depth - R.arity i + 1, live := true } All goals completed! 🐙 R:RankedAlphabetsdepth:b:Boolv:List Boolhlen:(b :: v).length = R.widthh:(R.scanStep b { buf := v, depth := sdepth, live := true }).live = truehshort:v.length + [].length < R.widthr:har:R.arOf (decodeBits (b :: v)) = some rhle:r sdepthheq:R.scanStep b { buf := v, depth := sdepth, live := true } = { buf := [], depth := sdepth - r + 1, live := true } i, R.code i = b :: v R.arity i { buf := [], depth := sdepth, live := true }.depth R.scanStep b { buf := v, depth := sdepth, live := true } = { buf := [], depth := { buf := [], depth := sdepth, live := true }.depth - R.arity i + 1, live := true } R:RankedAlphabetsdepth:b:Boolv:List Boolhlen:(b :: v).length = R.widthh:(R.scanStep b { buf := v, depth := sdepth, live := true }).live = truehshort:v.length + [].length < R.widthr:har:(if h : decodeBits (b :: v) < R.card then some (R.arity decodeBits (b :: v), h) else none) = some rhle:r sdepthheq:R.scanStep b { buf := v, depth := sdepth, live := true } = { buf := [], depth := sdepth - r + 1, live := true } i, R.code i = b :: v R.arity i { buf := [], depth := sdepth, live := true }.depth R.scanStep b { buf := v, depth := sdepth, live := true } = { buf := [], depth := { buf := [], depth := sdepth, live := true }.depth - R.arity i + 1, live := true } R:RankedAlphabetsdepth:b:Boolv:List Boolhlen:(b :: v).length = R.widthh:(R.scanStep b { buf := v, depth := sdepth, live := true }).live = truehshort:v.length + [].length < R.widthr:hle:r sdepthheq:R.scanStep b { buf := v, depth := sdepth, live := true } = { buf := [], depth := sdepth - r + 1, live := true }h✝:decodeBits (b :: v) < R.cardhar:some (R.arity decodeBits (b :: v), h✝) = some r i, R.code i = b :: v R.arity i { buf := [], depth := sdepth, live := true }.depth R.scanStep b { buf := v, depth := sdepth, live := true } = { buf := [], depth := { buf := [], depth := sdepth, live := true }.depth - R.arity i + 1, live := true }R:RankedAlphabetsdepth:b:Boolv:List Boolhlen:(b :: v).length = R.widthh:(R.scanStep b { buf := v, depth := sdepth, live := true }).live = truehshort:v.length + [].length < R.widthr:hle:r sdepthheq:R.scanStep b { buf := v, depth := sdepth, live := true } = { buf := [], depth := sdepth - r + 1, live := true }h✝:¬decodeBits (b :: v) < R.cardhar:none = some r i, R.code i = b :: v R.arity i { buf := [], depth := sdepth, live := true }.depth R.scanStep b { buf := v, depth := sdepth, live := true } = { buf := [], depth := { buf := [], depth := sdepth, live := true }.depth - R.arity i + 1, live := true } R:RankedAlphabetsdepth:b:Boolv:List Boolhlen:(b :: v).length = R.widthh:(R.scanStep b { buf := v, depth := sdepth, live := true }).live = truehshort:v.length + [].length < R.widthr:hle:r sdepthheq:R.scanStep b { buf := v, depth := sdepth, live := true } = { buf := [], depth := sdepth - r + 1, live := true }h✝:decodeBits (b :: v) < R.cardhar:some (R.arity decodeBits (b :: v), h✝) = some r i, R.code i = b :: v R.arity i { buf := [], depth := sdepth, live := true }.depth R.scanStep b { buf := v, depth := sdepth, live := true } = { buf := [], depth := { buf := [], depth := sdepth, live := true }.depth - R.arity i + 1, live := true } R:RankedAlphabetsdepth:b:Boolv:List Boolhlen:(b :: v).length = R.widthh:(R.scanStep b { buf := v, depth := sdepth, live := true }).live = truehshort:v.length + [].length < R.widthr:hle:r sdepthheq:R.scanStep b { buf := v, depth := sdepth, live := true } = { buf := [], depth := sdepth - r + 1, live := true }hlt:decodeBits (b :: v) < R.cardhar:some (R.arity decodeBits (b :: v), h✝) = some r i, R.code i = b :: v R.arity i { buf := [], depth := sdepth, live := true }.depth R.scanStep b { buf := v, depth := sdepth, live := true } = { buf := [], depth := { buf := [], depth := sdepth, live := true }.depth - R.arity i + 1, live := true } R:RankedAlphabetsdepth:b:Boolv:List Boolhlen:(b :: v).length = R.widthh:(R.scanStep b { buf := v, depth := sdepth, live := true }).live = truehshort:v.length + [].length < R.widthr:hle:r sdepthheq:R.scanStep b { buf := v, depth := sdepth, live := true } = { buf := [], depth := sdepth - r + 1, live := true }hlt:decodeBits (b :: v) < R.cardhar:some (R.arity decodeBits (b :: v), h✝) = some rhr:R.arity decodeBits (b :: v), hlt = r i, R.code i = b :: v R.arity i { buf := [], depth := sdepth, live := true }.depth R.scanStep b { buf := v, depth := sdepth, live := true } = { buf := [], depth := { buf := [], depth := sdepth, live := true }.depth - R.arity i + 1, live := true } R:RankedAlphabetsdepth:b:Boolv:List Boolhlen:(b :: v).length = R.widthh:(R.scanStep b { buf := v, depth := sdepth, live := true }).live = truehshort:v.length + [].length < R.widthr:hle:r sdepthheq:R.scanStep b { buf := v, depth := sdepth, live := true } = { buf := [], depth := sdepth - r + 1, live := true }hlt:decodeBits (b :: v) < R.cardhar:some (R.arity decodeBits (b :: v), h✝) = some rhr:R.arity decodeBits (b :: v), hlt = rR.code decodeBits (b :: v), hlt = b :: vR:RankedAlphabetsdepth:b:Boolv:List Boolhlen:(b :: v).length = R.widthh:(R.scanStep b { buf := v, depth := sdepth, live := true }).live = truehshort:v.length + [].length < R.widthr:hle:r sdepthheq:R.scanStep b { buf := v, depth := sdepth, live := true } = { buf := [], depth := sdepth - r + 1, live := true }hlt:decodeBits (b :: v) < R.cardhar:some (R.arity decodeBits (b :: v), h✝) = some rhr:R.arity decodeBits (b :: v), hlt = rR.scanStep b { buf := v, depth := sdepth, live := true } = { buf := [], depth := { buf := [], depth := sdepth, live := true }.depth - R.arity decodeBits (b :: v), hlt + 1, live := true } R:RankedAlphabetsdepth:b:Boolv:List Boolhlen:(b :: v).length = R.widthh:(R.scanStep b { buf := v, depth := sdepth, live := true }).live = truehshort:v.length + [].length < R.widthr:hle:r sdepthheq:R.scanStep b { buf := v, depth := sdepth, live := true } = { buf := [], depth := sdepth - r + 1, live := true }hlt:decodeBits (b :: v) < R.cardhar:some (R.arity decodeBits (b :: v), h✝) = some rhr:R.arity decodeBits (b :: v), hlt = rR.code decodeBits (b :: v), hlt = b :: v refine List.ext_getElem (R:RankedAlphabetsdepth:b:Boolv:List Boolhlen:(b :: v).length = R.widthh:(R.scanStep b { buf := v, depth := sdepth, live := true }).live = truehshort:v.length + [].length < R.widthr:hle:r sdepthheq:R.scanStep b { buf := v, depth := sdepth, live := true } = { buf := [], depth := sdepth - r + 1, live := true }hlt:decodeBits (b :: v) < R.cardhar:some (R.arity decodeBits (b :: v), h✝) = some rhr:R.arity decodeBits (b :: v), hlt = r(R.code decodeBits (b :: v), hlt).length = (b :: v).length All goals completed! 🐙) ?_ R:RankedAlphabetsdepth:b:Boolv:List Boolhlen:(b :: v).length = R.widthh:(R.scanStep b { buf := v, depth := sdepth, live := true }).live = truehshort:v.length + [].length < R.widthr:hle:r sdepthheq:R.scanStep b { buf := v, depth := sdepth, live := true } = { buf := [], depth := sdepth - r + 1, live := true }hlt:decodeBits (b :: v) < R.cardhar:some (R.arity decodeBits (b :: v), h✝) = some rhr:R.arity decodeBits (b :: v), hlt = rn:h₁:n < (R.code decodeBits (b :: v), hlt).lengthh₂:n < (b :: v).length(R.code decodeBits (b :: v), hlt)[n] = (b :: v)[n] All goals completed! 🐙 R:RankedAlphabetsdepth:b:Boolv:List Boolhlen:(b :: v).length = R.widthh:(R.scanStep b { buf := v, depth := sdepth, live := true }).live = truehshort:v.length + [].length < R.widthr:hle:r sdepthheq:R.scanStep b { buf := v, depth := sdepth, live := true } = { buf := [], depth := sdepth - r + 1, live := true }hlt:decodeBits (b :: v) < R.cardhar:some (R.arity decodeBits (b :: v), h✝) = some rhr:R.arity decodeBits (b :: v), hlt = rR.scanStep b { buf := v, depth := sdepth, live := true } = { buf := [], depth := { buf := [], depth := sdepth, live := true }.depth - R.arity decodeBits (b :: v), hlt + 1, live := true } All goals completed! 🐙 R:RankedAlphabetsdepth:b:Boolv:List Boolhlen:(b :: v).length = R.widthh:(R.scanStep b { buf := v, depth := sdepth, live := true }).live = truehshort:v.length + [].length < R.widthr:hle:r sdepthheq:R.scanStep b { buf := v, depth := sdepth, live := true } = { buf := [], depth := sdepth - r + 1, live := true }h✝:¬decodeBits (b :: v) < R.cardhar:none = some r i, R.code i = b :: v R.arity i { buf := [], depth := sdepth, live := true }.depth R.scanStep b { buf := v, depth := sdepth, live := true } = { buf := [], depth := { buf := [], depth := sdepth, live := true }.depth - R.arity i + 1, live := true } exact absurd har (R:RankedAlphabetsdepth:b:Boolv:List Boolhlen:(b :: v).length = R.widthh:(R.scanStep b { buf := v, depth := sdepth, live := true }).live = truehshort:v.length + [].length < R.widthr:hle:r sdepthheq:R.scanStep b { buf := v, depth := sdepth, live := true } = { buf := [], depth := sdepth - r + 1, live := true }h✝:¬decodeBits (b :: v) < R.cardhar:none = some r¬none = some r All goals completed! 🐙)

A live scan with no incomplete block and nothing pending has read nothing.

theorem eq_nil_of_live_of_buf_nil_of_depth_eq_zero (R : RankedAlphabet) (w : List Bool) (hlive : (R.scanFinal w).live = true) (hbuf : (R.scanFinal w).buf = []) (hd : (R.scanFinal w).depth = 0) : w = [] := R:RankedAlphabetw:List Boolhlive:(R.scanFinal w).live = truehbuf:(R.scanFinal w).buf = []hd:(R.scanFinal w).depth = 0w = [] match w with R:RankedAlphabetw:List Boolhlive:(R.scanFinal []).live = truehbuf:(R.scanFinal []).buf = []hd:(R.scanFinal []).depth = 0[] = [] All goals completed! 🐙 R:RankedAlphabetw:List Boolb:Boolv:List Boolhlive:(R.scanFinal (b :: v)).live = truehbuf:(R.scanFinal (b :: v)).buf = []hd:(R.scanFinal (b :: v)).depth = 0b :: v = [] R:RankedAlphabetw:List Boolb:Boolv:List Boolhlive:(R.scanStep b (R.scanFinal v)).live = truehbuf:(R.scanStep b (R.scanFinal v)).buf = []hd:(R.scanStep b (R.scanFinal v)).depth = 0b :: v = [] R:RankedAlphabetw:List Boolb:Boolv:List Boolhlive:(R.scanStep b (R.scanFinal v)).live = truehbuf:(R.scanStep b (R.scanFinal v)).buf = []hd:(R.scanStep b (R.scanFinal v)).depth = 0hcase:(b :: (R.scanFinal v).buf).length R.width R.scanStep b (R.scanFinal v) = { buf := b :: (R.scanFinal v).buf, depth := (R.scanFinal v).depth, live := true } r, (b :: (R.scanFinal v).buf).length = R.width R.arOf (decodeBits (b :: (R.scanFinal v).buf)) = some r r (R.scanFinal v).depth R.scanStep b (R.scanFinal v) = { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }b :: v = [] R:RankedAlphabetw:List Boolb:Boolv:List Boolhlive:(R.scanStep b (R.scanFinal v)).live = truehbuf:(R.scanStep b (R.scanFinal v)).buf = []hd:(R.scanStep b (R.scanFinal v)).depth = 0heq:R.scanStep b (R.scanFinal v) = { buf := b :: (R.scanFinal v).buf, depth := (R.scanFinal v).depth, live := true }b :: v = []R:RankedAlphabetw:List Boolb:Boolv:List Boolhlive:(R.scanStep b (R.scanFinal v)).live = truehbuf:(R.scanStep b (R.scanFinal v)).buf = []hd:(R.scanStep b (R.scanFinal v)).depth = 0r:heq:R.scanStep b (R.scanFinal v) = { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }b :: v = [] R:RankedAlphabetw:List Boolb:Boolv:List Boolhlive:(R.scanStep b (R.scanFinal v)).live = truehbuf:(R.scanStep b (R.scanFinal v)).buf = []hd:(R.scanStep b (R.scanFinal v)).depth = 0heq:R.scanStep b (R.scanFinal v) = { buf := b :: (R.scanFinal v).buf, depth := (R.scanFinal v).depth, live := true }b :: v = [] R:RankedAlphabetw:List Boolb:Boolv:List Boolhlive:(R.scanStep b (R.scanFinal v)).live = truehbuf:{ buf := b :: (R.scanFinal v).buf, depth := (R.scanFinal v).depth, live := true }.buf = []hd:(R.scanStep b (R.scanFinal v)).depth = 0heq:R.scanStep b (R.scanFinal v) = { buf := b :: (R.scanFinal v).buf, depth := (R.scanFinal v).depth, live := true }b :: v = [] exact absurd hbuf (R:RankedAlphabetw:List Boolb:Boolv:List Boolhlive:(R.scanStep b (R.scanFinal v)).live = truehbuf:{ buf := b :: (R.scanFinal v).buf, depth := (R.scanFinal v).depth, live := true }.buf = []hd:(R.scanStep b (R.scanFinal v)).depth = 0heq:R.scanStep b (R.scanFinal v) = { buf := b :: (R.scanFinal v).buf, depth := (R.scanFinal v).depth, live := true }¬{ buf := b :: (R.scanFinal v).buf, depth := (R.scanFinal v).depth, live := true }.buf = [] All goals completed! 🐙) R:RankedAlphabetw:List Boolb:Boolv:List Boolhlive:(R.scanStep b (R.scanFinal v)).live = truehbuf:(R.scanStep b (R.scanFinal v)).buf = []hd:(R.scanStep b (R.scanFinal v)).depth = 0r:heq:R.scanStep b (R.scanFinal v) = { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }b :: v = [] R:RankedAlphabetw:List Boolb:Boolv:List Boolhlive:(R.scanStep b (R.scanFinal v)).live = truehbuf:(R.scanStep b (R.scanFinal v)).buf = []r:hd:{ buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }.depth = 0heq:R.scanStep b (R.scanFinal v) = { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }b :: v = [] exact absurd hd (R:RankedAlphabetw:List Boolb:Boolv:List Boolhlive:(R.scanStep b (R.scanFinal v)).live = truehbuf:(R.scanStep b (R.scanFinal v)).buf = []r:hd:{ buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }.depth = 0heq:R.scanStep b (R.scanFinal v) = { buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }¬{ buf := [], depth := (R.scanFinal v).depth - r + 1, live := true }.depth = 0 All goals completed! 🐙)

Reading off as many complete subterms as the pending count allows: a live scan with no incomplete block and at least k pending subterms has k spellings as a prefix. The extraction of one subterm is the hypothesis ih, at the same bound, as in parseChildren_flatten.

theorem exists_children_append_of_le_depth (R : RankedAlphabet) (n : ) (ih : w : List Bool, w.length n (R.scanFinal w).live = true (R.scanFinal w).buf = [] 1 (R.scanFinal w).depth t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depth) : (k : ) (v : List Bool), v.length n (R.scanFinal v).live = true (R.scanFinal v).buf = [] k (R.scanFinal v).depth (ch : Fin k R.Term) (rest : List Bool), (List.ofFn fun d R.spell (ch d)).flatten ++ rest = v (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + k = (R.scanFinal v).depth := Nat.rec (fun v _ hlive hbuf _ Fin.elim0, v, R:RankedAlphabetn:ih: (w : List Bool), w.length n (R.scanFinal w).live = true (R.scanFinal w).buf = [] 1 (R.scanFinal w).depth t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depthv:List Boolx✝¹:v.length nhlive:(R.scanFinal v).live = truehbuf:(R.scanFinal v).buf = []x✝:Nat.zero (R.scanFinal v).depth(List.ofFn fun d R.spell d.elim0).flatten ++ v = v All goals completed! 🐙, hlive, hbuf, rfl) (fun k ihk v hv hlive hbuf hk R:RankedAlphabetn:ih: (w : List Bool), w.length n (R.scanFinal w).live = true (R.scanFinal w).buf = [] 1 (R.scanFinal w).depth t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depthk:ihk: (v : List Bool), v.length n (R.scanFinal v).live = true (R.scanFinal v).buf = [] k (R.scanFinal v).depth ch rest, (List.ofFn fun d R.spell (ch d)).flatten ++ rest = v (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + k = (R.scanFinal v).depthv:List Boolhv:v.length nhlive:(R.scanFinal v).live = truehbuf:(R.scanFinal v).buf = []hk:k.succ (R.scanFinal v).depth ch rest, (List.ofFn fun d R.spell (ch d)).flatten ++ rest = v (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + k.succ = (R.scanFinal v).depth R:RankedAlphabetn:ih: (w : List Bool), w.length n (R.scanFinal w).live = true (R.scanFinal w).buf = [] 1 (R.scanFinal w).depth t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depthk:ihk: (v : List Bool), v.length n (R.scanFinal v).live = true (R.scanFinal v).buf = [] k (R.scanFinal v).depth ch rest, (List.ofFn fun d R.spell (ch d)).flatten ++ rest = v (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + k = (R.scanFinal v).depthv:List Boolhv:v.length nhlive:(R.scanFinal v).live = truehbuf:(R.scanFinal v).buf = []hk:k.succ (R.scanFinal v).deptht:R.Termv₁:List Boolht:R.spell t ++ v₁ = vhlive₁:(R.scanFinal v₁).live = truehbuf₁:(R.scanFinal v₁).buf = []hd₁:(R.scanFinal v₁).depth + 1 = (R.scanFinal v).depth ch rest, (List.ofFn fun d R.spell (ch d)).flatten ++ rest = v (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + k.succ = (R.scanFinal v).depth R:RankedAlphabetn:ih: (w : List Bool), w.length n (R.scanFinal w).live = true (R.scanFinal w).buf = [] 1 (R.scanFinal w).depth t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depthk:ihk: (v : List Bool), v.length n (R.scanFinal v).live = true (R.scanFinal v).buf = [] k (R.scanFinal v).depth ch rest, (List.ofFn fun d R.spell (ch d)).flatten ++ rest = v (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + k = (R.scanFinal v).depthv:List Boolhv:v.length nhlive:(R.scanFinal v).live = truehbuf:(R.scanFinal v).buf = []hk:k.succ (R.scanFinal v).deptht:R.Termv₁:List Boolht:R.spell t ++ v₁ = vhlive₁:(R.scanFinal v₁).live = truehbuf₁:(R.scanFinal v₁).buf = []hd₁:(R.scanFinal v₁).depth + 1 = (R.scanFinal v).depthhv₁:v₁.length n ch rest, (List.ofFn fun d R.spell (ch d)).flatten ++ rest = v (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + k.succ = (R.scanFinal v).depth R:RankedAlphabetn:ih: (w : List Bool), w.length n (R.scanFinal w).live = true (R.scanFinal w).buf = [] 1 (R.scanFinal w).depth t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depthk:ihk: (v : List Bool), v.length n (R.scanFinal v).live = true (R.scanFinal v).buf = [] k (R.scanFinal v).depth ch rest, (List.ofFn fun d R.spell (ch d)).flatten ++ rest = v (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + k = (R.scanFinal v).depthv:List Boolhv:v.length nhlive:(R.scanFinal v).live = truehbuf:(R.scanFinal v).buf = []hk:k.succ (R.scanFinal v).deptht:R.Termv₁:List Boolht:R.spell t ++ v₁ = vhlive₁:(R.scanFinal v₁).live = truehbuf₁:(R.scanFinal v₁).buf = []hd₁:(R.scanFinal v₁).depth + 1 = (R.scanFinal v).depthhv₁:v₁.length nch:Fin k R.Termrest:List Boolhch:(List.ofFn fun d R.spell (ch d)).flatten ++ rest = v₁hlive₂:(R.scanFinal rest).live = truehbuf₂:(R.scanFinal rest).buf = []hd₂:(R.scanFinal rest).depth + k = (R.scanFinal v₁).depth ch rest, (List.ofFn fun d R.spell (ch d)).flatten ++ rest = v (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + k.succ = (R.scanFinal v).depth refine Fin.cons t ch, rest, ?_, hlive₂, hbuf₂, R:RankedAlphabetn:ih: (w : List Bool), w.length n (R.scanFinal w).live = true (R.scanFinal w).buf = [] 1 (R.scanFinal w).depth t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depthk:ihk: (v : List Bool), v.length n (R.scanFinal v).live = true (R.scanFinal v).buf = [] k (R.scanFinal v).depth ch rest, (List.ofFn fun d R.spell (ch d)).flatten ++ rest = v (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + k = (R.scanFinal v).depthv:List Boolhv:v.length nhlive:(R.scanFinal v).live = truehbuf:(R.scanFinal v).buf = []hk:k.succ (R.scanFinal v).deptht:R.Termv₁:List Boolht:R.spell t ++ v₁ = vhlive₁:(R.scanFinal v₁).live = truehbuf₁:(R.scanFinal v₁).buf = []hd₁:(R.scanFinal v₁).depth + 1 = (R.scanFinal v).depthhv₁:v₁.length nch:Fin k R.Termrest:List Boolhch:(List.ofFn fun d R.spell (ch d)).flatten ++ rest = v₁hlive₂:(R.scanFinal rest).live = truehbuf₂:(R.scanFinal rest).buf = []hd₂:(R.scanFinal rest).depth + k = (R.scanFinal v₁).depth(R.scanFinal rest).depth + k.succ = (R.scanFinal v).depth All goals completed! 🐙 R:RankedAlphabetn:ih: (w : List Bool), w.length n (R.scanFinal w).live = true (R.scanFinal w).buf = [] 1 (R.scanFinal w).depth t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depthk:ihk: (v : List Bool), v.length n (R.scanFinal v).live = true (R.scanFinal v).buf = [] k (R.scanFinal v).depth ch rest, (List.ofFn fun d R.spell (ch d)).flatten ++ rest = v (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + k = (R.scanFinal v).depthv:List Boolhv:v.length nhlive:(R.scanFinal v).live = truehbuf:(R.scanFinal v).buf = []hk:k.succ (R.scanFinal v).deptht:R.Termv₁:List Boolht:R.spell t ++ v₁ = vhlive₁:(R.scanFinal v₁).live = truehbuf₁:(R.scanFinal v₁).buf = []hd₁:(R.scanFinal v₁).depth + 1 = (R.scanFinal v).depthhv₁:v₁.length nch:Fin k R.Termrest:List Boolhch:(List.ofFn fun d R.spell (ch d)).flatten ++ rest = v₁hlive₂:(R.scanFinal rest).live = truehbuf₂:(R.scanFinal rest).buf = []hd₂:(R.scanFinal rest).depth + k = (R.scanFinal v₁).depth(R.spell (Fin.cons t ch 0) :: List.ofFn fun i R.spell (Fin.cons t ch i.succ)).flatten ++ rest = v R:RankedAlphabetn:ih: (w : List Bool), w.length n (R.scanFinal w).live = true (R.scanFinal w).buf = [] 1 (R.scanFinal w).depth t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depthk:ihk: (v : List Bool), v.length n (R.scanFinal v).live = true (R.scanFinal v).buf = [] k (R.scanFinal v).depth ch rest, (List.ofFn fun d R.spell (ch d)).flatten ++ rest = v (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + k = (R.scanFinal v).depthv:List Boolhv:v.length nhlive:(R.scanFinal v).live = truehbuf:(R.scanFinal v).buf = []hk:k.succ (R.scanFinal v).deptht:R.Termv₁:List Boolht:R.spell t ++ v₁ = vhlive₁:(R.scanFinal v₁).live = truehbuf₁:(R.scanFinal v₁).buf = []hd₁:(R.scanFinal v₁).depth + 1 = (R.scanFinal v).depthhv₁:v₁.length nch:Fin k R.Termrest:List Boolhch:(List.ofFn fun d R.spell (ch d)).flatten ++ rest = v₁hlive₂:(R.scanFinal rest).live = truehbuf₂:(R.scanFinal rest).buf = []hd₂:(R.scanFinal rest).depth + k = (R.scanFinal v₁).depth(R.spell t :: List.ofFn fun i R.spell (ch i)).flatten ++ rest = v All goals completed! 🐙)

A word whose scan is live, carries no incomplete block and leaves at least one subterm pending has a complete spelling as a prefix.

theorem exists_spell_append_of_live_of_buf_nil_of_one_le_depth (R : RankedAlphabet) : (n : ) (w : List Bool), w.length n (R.scanFinal w).live = true (R.scanFinal w).buf = [] 1 (R.scanFinal w).depth t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depth := Nat.rec (fun w hw _ _ hd R:RankedAlphabetw:List Boolhw:w.length Nat.zerox✝¹:(R.scanFinal w).live = truex✝:(R.scanFinal w).buf = []hd:1 (R.scanFinal w).depth t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depth R:RankedAlphabetw:List Boolhw:w.length Nat.zerox✝¹:(R.scanFinal w).live = truex✝:(R.scanFinal w).buf = []hd:1 (R.scanFinal w).depthhzero:w.length 0 t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depth R:RankedAlphabetw:List Boolhw:w.length Nat.zerox✝¹:(R.scanFinal w).live = truex✝:(R.scanFinal w).buf = []hd:1 (R.scanFinal w).depthhzero:w.length 0hnil:w = [] t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depth R:RankedAlphabethw:[].length Nat.zerox✝¹:(R.scanFinal []).live = truex✝:(R.scanFinal []).buf = []hd:1 (R.scanFinal []).depthhzero:[].length 0 t rest, R.spell t ++ rest = [] (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal []).depth exact absurd hd (R:RankedAlphabethw:[].length Nat.zerox✝¹:(R.scanFinal []).live = truex✝:(R.scanFinal []).buf = []hd:1 (R.scanFinal []).depthhzero:[].length 0¬1 (R.scanFinal []).depth All goals completed! 🐙)) (fun n ihn w hw hlive hbuf hd R:RankedAlphabetn:ihn: (w : List Bool), w.length n (R.scanFinal w).live = true (R.scanFinal w).buf = [] 1 (R.scanFinal w).depth t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depthw:List Boolhw:w.length n.succhlive:(R.scanFinal w).live = truehbuf:(R.scanFinal w).buf = []hd:1 (R.scanFinal w).depth t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depth R:RankedAlphabetn:ihn: (w : List Bool), w.length n (R.scanFinal w).live = true (R.scanFinal w).buf = [] 1 (R.scanFinal w).depth t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depthw:List Boolhw:w.length n.succhlive:(R.scanFinal w).live = truehbuf:(R.scanFinal w).buf = []hd:1 (R.scanFinal w).depthhmod:w.length % R.width = 0 t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depth R:RankedAlphabetn:ihn: (w : List Bool), w.length n (R.scanFinal w).live = true (R.scanFinal w).buf = [] 1 (R.scanFinal w).depth t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depthw:List Boolhw:w.length n.succhlive:(R.scanFinal w).live = truehbuf:(R.scanFinal w).buf = []hd:1 (R.scanFinal w).depthhmod:w.length % R.width = 0hne:w [] t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depth R:RankedAlphabetn:ihn: (w : List Bool), w.length n (R.scanFinal w).live = true (R.scanFinal w).buf = [] 1 (R.scanFinal w).depth t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depthw:List Boolhw:w.length n.succhlive:(R.scanFinal w).live = truehbuf:(R.scanFinal w).buf = []hd:1 (R.scanFinal w).depthhmod:w.length % R.width = 0hne:w []hwidth:R.width w.length t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depth R:RankedAlphabetn:ihn: (w : List Bool), w.length n (R.scanFinal w).live = true (R.scanFinal w).buf = [] 1 (R.scanFinal w).depth t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depthw:List Boolhw:w.length n.succhlive:(R.scanFinal w).live = truehbuf:(R.scanFinal w).buf = []hd:1 (R.scanFinal w).depthhmod:w.length % R.width = 0hne:w []hwidth:R.width w.lengthblk:List Boolrest:List Boolhsplit:blk ++ rest = whlenblk:blk.length = R.width t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depth R:RankedAlphabetn:ihn: (w : List Bool), w.length n (R.scanFinal w).live = true (R.scanFinal w).buf = [] 1 (R.scanFinal w).depth t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depthw:List Boolhw:w.length n.succhlive:(R.scanFinal w).live = truehbuf:(R.scanFinal w).buf = []hd:1 (R.scanFinal w).depthhmod:w.length % R.width = 0hne:w []hwidth:R.width w.lengthblk:List Boolrest:List Boolhsplit:blk ++ rest = whlenblk:blk.length = R.widthhlensum:R.width + rest.length = w.length t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depth R:RankedAlphabetn:ihn: (w : List Bool), w.length n (R.scanFinal w).live = true (R.scanFinal w).buf = [] 1 (R.scanFinal w).depth t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depthw:List Boolhw:w.length n.succhlive:(R.scanFinal w).live = truehbuf:(R.scanFinal w).buf = []hd:1 (R.scanFinal w).depthhmod:w.length % R.width = 0hne:w []hwidth:R.width w.lengthblk:List Boolrest:List Boolhsplit:blk ++ rest = whlenblk:blk.length = R.widthhlensum:R.width + rest.length = w.lengthhscan:R.scanFinal w = R.scanFrom blk (R.scanFinal rest) t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depth R:RankedAlphabetn:ihn: (w : List Bool), w.length n (R.scanFinal w).live = true (R.scanFinal w).buf = [] 1 (R.scanFinal w).depth t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depthw:List Boolhw:w.length n.succhlive:(R.scanFinal w).live = truehbuf:(R.scanFinal w).buf = []hd:1 (R.scanFinal w).depthhmod:w.length % R.width = 0hne:w []hwidth:R.width w.lengthblk:List Boolrest:List Boolhsplit:blk ++ rest = whlenblk:blk.length = R.widthhlensum:R.width + rest.length = w.lengthhscan:R.scanFinal w = R.scanFrom blk (R.scanFinal rest)hlive':(R.scanFinal rest).live = true t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depth R:RankedAlphabetn:ihn: (w : List Bool), w.length n (R.scanFinal w).live = true (R.scanFinal w).buf = [] 1 (R.scanFinal w).depth t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depthw:List Boolhw:w.length n.succhlive:(R.scanFinal w).live = truehbuf:(R.scanFinal w).buf = []hd:1 (R.scanFinal w).depthhmod:w.length % R.width = 0hne:w []hwidth:R.width w.lengthblk:List Boolrest:List Boolhsplit:blk ++ rest = whlenblk:blk.length = R.widthhlensum:R.width + rest.length = w.lengthhscan:R.scanFinal w = R.scanFrom blk (R.scanFinal rest)hlive':(R.scanFinal rest).live = truehbuf':(R.scanFinal rest).buf = [] t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depth R:RankedAlphabetn:ihn: (w : List Bool), w.length n (R.scanFinal w).live = true (R.scanFinal w).buf = [] 1 (R.scanFinal w).depth t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depthw:List Boolhw:w.length n.succhlive:(R.scanFinal w).live = truehbuf:(R.scanFinal w).buf = []hd:1 (R.scanFinal w).depthhmod:w.length % R.width = 0hne:w []hwidth:R.width w.lengthblk:List Boolrest:List Boolhsplit:blk ++ rest = whlenblk:blk.length = R.widthhlensum:R.width + rest.length = w.lengthhscan:R.scanFinal w = R.scanFrom blk (R.scanFinal rest)hlive':(R.scanFinal rest).live = truehbuf':(R.scanFinal rest).buf = []i:Fin R.cardhcode:R.code i = blkhari:R.arity i (R.scanFinal rest).depthhstep:R.scanFrom blk (R.scanFinal rest) = { buf := [], depth := (R.scanFinal rest).depth - R.arity i + 1, live := true } t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depth R:RankedAlphabetn:ihn: (w : List Bool), w.length n (R.scanFinal w).live = true (R.scanFinal w).buf = [] 1 (R.scanFinal w).depth t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depthw:List Boolhw:w.length n.succhlive:(R.scanFinal w).live = truehbuf:(R.scanFinal w).buf = []hd:1 (R.scanFinal w).depthhmod:w.length % R.width = 0hne:w []hwidth:R.width w.lengthblk:List Boolrest:List Boolhsplit:blk ++ rest = whlenblk:blk.length = R.widthhlensum:R.width + rest.length = w.lengthhscan:R.scanFinal w = R.scanFrom blk (R.scanFinal rest)hlive':(R.scanFinal rest).live = truehbuf':(R.scanFinal rest).buf = []i:Fin R.cardhcode:R.code i = blkhari:R.arity i (R.scanFinal rest).depthhstep:R.scanFrom blk (R.scanFinal rest) = { buf := [], depth := (R.scanFinal rest).depth - R.arity i + 1, live := true }ch:Fin (R.arity i) R.Termrest':List Boolhch:(List.ofFn fun d R.spell (ch d)).flatten ++ rest' = resthlive'':(R.scanFinal rest').live = truehbuf'':(R.scanFinal rest').buf = []hd'':(R.scanFinal rest').depth + R.arity i = (R.scanFinal rest).depth t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depth R:RankedAlphabetn:ihn: (w : List Bool), w.length n (R.scanFinal w).live = true (R.scanFinal w).buf = [] 1 (R.scanFinal w).depth t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depthw:List Boolhw:w.length n.succhlive:(R.scanFinal w).live = truehbuf:(R.scanFinal w).buf = []hd:1 (R.scanFinal w).depthhmod:w.length % R.width = 0hne:w []hwidth:R.width w.lengthblk:List Boolrest:List Boolhsplit:blk ++ rest = whlenblk:blk.length = R.widthhlensum:R.width + rest.length = w.lengthhscan:R.scanFinal w = R.scanFrom blk (R.scanFinal rest)hlive':(R.scanFinal rest).live = truehbuf':(R.scanFinal rest).buf = []i:Fin R.cardhcode:R.code i = blkhari:R.arity i (R.scanFinal rest).depthhstep:R.scanFrom blk (R.scanFinal rest) = { buf := [], depth := (R.scanFinal rest).depth - R.arity i + 1, live := true }ch:Fin (R.arity i) R.Termrest':List Boolhch:(List.ofFn fun d R.spell (ch d)).flatten ++ rest' = resthlive'':(R.scanFinal rest').live = truehbuf'':(R.scanFinal rest').buf = []hd'':(R.scanFinal rest').depth + R.arity i = (R.scanFinal rest).depthR.spell (Term.mk R i ch) ++ rest' = wR:RankedAlphabetn:ihn: (w : List Bool), w.length n (R.scanFinal w).live = true (R.scanFinal w).buf = [] 1 (R.scanFinal w).depth t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depthw:List Boolhw:w.length n.succhlive:(R.scanFinal w).live = truehbuf:(R.scanFinal w).buf = []hd:1 (R.scanFinal w).depthhmod:w.length % R.width = 0hne:w []hwidth:R.width w.lengthblk:List Boolrest:List Boolhsplit:blk ++ rest = whlenblk:blk.length = R.widthhlensum:R.width + rest.length = w.lengthhscan:R.scanFinal w = R.scanFrom blk (R.scanFinal rest)hlive':(R.scanFinal rest).live = truehbuf':(R.scanFinal rest).buf = []i:Fin R.cardhcode:R.code i = blkhari:R.arity i (R.scanFinal rest).depthhstep:R.scanFrom blk (R.scanFinal rest) = { buf := [], depth := (R.scanFinal rest).depth - R.arity i + 1, live := true }ch:Fin (R.arity i) R.Termrest':List Boolhch:(List.ofFn fun d R.spell (ch d)).flatten ++ rest' = resthlive'':(R.scanFinal rest').live = truehbuf'':(R.scanFinal rest').buf = []hd'':(R.scanFinal rest').depth + R.arity i = (R.scanFinal rest).depth(R.scanFinal rest').depth + 1 = (R.scanFinal w).depth R:RankedAlphabetn:ihn: (w : List Bool), w.length n (R.scanFinal w).live = true (R.scanFinal w).buf = [] 1 (R.scanFinal w).depth t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depthw:List Boolhw:w.length n.succhlive:(R.scanFinal w).live = truehbuf:(R.scanFinal w).buf = []hd:1 (R.scanFinal w).depthhmod:w.length % R.width = 0hne:w []hwidth:R.width w.lengthblk:List Boolrest:List Boolhsplit:blk ++ rest = whlenblk:blk.length = R.widthhlensum:R.width + rest.length = w.lengthhscan:R.scanFinal w = R.scanFrom blk (R.scanFinal rest)hlive':(R.scanFinal rest).live = truehbuf':(R.scanFinal rest).buf = []i:Fin R.cardhcode:R.code i = blkhari:R.arity i (R.scanFinal rest).depthhstep:R.scanFrom blk (R.scanFinal rest) = { buf := [], depth := (R.scanFinal rest).depth - R.arity i + 1, live := true }ch:Fin (R.arity i) R.Termrest':List Boolhch:(List.ofFn fun d R.spell (ch d)).flatten ++ rest' = resthlive'':(R.scanFinal rest').live = truehbuf'':(R.scanFinal rest').buf = []hd'':(R.scanFinal rest').depth + R.arity i = (R.scanFinal rest).depthR.spell (Term.mk R i ch) ++ rest' = w All goals completed! 🐙 R:RankedAlphabetn:ihn: (w : List Bool), w.length n (R.scanFinal w).live = true (R.scanFinal w).buf = [] 1 (R.scanFinal w).depth t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depthw:List Boolhw:w.length n.succhlive:(R.scanFinal w).live = truehbuf:(R.scanFinal w).buf = []hd:1 (R.scanFinal w).depthhmod:w.length % R.width = 0hne:w []hwidth:R.width w.lengthblk:List Boolrest:List Boolhsplit:blk ++ rest = whlenblk:blk.length = R.widthhlensum:R.width + rest.length = w.lengthhscan:R.scanFinal w = R.scanFrom blk (R.scanFinal rest)hlive':(R.scanFinal rest).live = truehbuf':(R.scanFinal rest).buf = []i:Fin R.cardhcode:R.code i = blkhari:R.arity i (R.scanFinal rest).depthhstep:R.scanFrom blk (R.scanFinal rest) = { buf := [], depth := (R.scanFinal rest).depth - R.arity i + 1, live := true }ch:Fin (R.arity i) R.Termrest':List Boolhch:(List.ofFn fun d R.spell (ch d)).flatten ++ rest' = resthlive'':(R.scanFinal rest').live = truehbuf'':(R.scanFinal rest').buf = []hd'':(R.scanFinal rest').depth + R.arity i = (R.scanFinal rest).depth(R.scanFinal rest').depth + 1 = (R.scanFinal w).depth R:RankedAlphabetn:ihn: (w : List Bool), w.length n (R.scanFinal w).live = true (R.scanFinal w).buf = [] 1 (R.scanFinal w).depth t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depthw:List Boolhw:w.length n.succhlive:(R.scanFinal w).live = truehbuf:(R.scanFinal w).buf = []hd:1 (R.scanFinal w).depthhmod:w.length % R.width = 0hne:w []hwidth:R.width w.lengthblk:List Boolrest:List Boolhsplit:blk ++ rest = whlenblk:blk.length = R.widthhlensum:R.width + rest.length = w.lengthhscan:R.scanFinal w = R.scanFrom blk (R.scanFinal rest)hlive':(R.scanFinal rest).live = truehbuf':(R.scanFinal rest).buf = []i:Fin R.cardhcode:R.code i = blkhari:R.arity i (R.scanFinal rest).depthhstep:R.scanFrom blk (R.scanFinal rest) = { buf := [], depth := (R.scanFinal rest).depth - R.arity i + 1, live := true }ch:Fin (R.arity i) R.Termrest':List Boolhch:(List.ofFn fun d R.spell (ch d)).flatten ++ rest' = resthlive'':(R.scanFinal rest').live = truehbuf'':(R.scanFinal rest').buf = []hd'':(R.scanFinal rest').depth + R.arity i = (R.scanFinal rest).depth(R.scanFinal rest').depth + 1 = { buf := [], depth := (R.scanFinal rest).depth - R.arity i + 1, live := true }.depth R:RankedAlphabetn:ihn: (w : List Bool), w.length n (R.scanFinal w).live = true (R.scanFinal w).buf = [] 1 (R.scanFinal w).depth t rest, R.spell t ++ rest = w (R.scanFinal rest).live = true (R.scanFinal rest).buf = [] (R.scanFinal rest).depth + 1 = (R.scanFinal w).depthw:List Boolhw:w.length n.succhlive:(R.scanFinal w).live = truehbuf:(R.scanFinal w).buf = []hd:1 (R.scanFinal w).depthhmod:w.length % R.width = 0hne:w []hwidth:R.width w.lengthblk:List Boolrest:List Boolhsplit:blk ++ rest = whlenblk:blk.length = R.widthhlensum:R.width + rest.length = w.lengthhscan:R.scanFinal w = R.scanFrom blk (R.scanFinal rest)hlive':(R.scanFinal rest).live = truehbuf':(R.scanFinal rest).buf = []i:Fin R.cardhcode:R.code i = blkhari:R.arity i (R.scanFinal rest).depthhstep:R.scanFrom blk (R.scanFinal rest) = { buf := [], depth := (R.scanFinal rest).depth - R.arity i + 1, live := true }ch:Fin (R.arity i) R.Termrest':List Boolhch:(List.ofFn fun d R.spell (ch d)).flatten ++ rest' = resthlive'':(R.scanFinal rest').live = truehbuf'':(R.scanFinal rest').buf = []hd'':(R.scanFinal rest').depth + R.arity i = (R.scanFinal rest).depth(R.scanFinal rest').depth + 1 = (R.scanFinal rest).depth - R.arity i + 1 All goals completed! 🐙)

Every valid word is a spelling: the converse of valid_spell.

theorem exists_spell_of_valid (R : RankedAlphabet) {w : List Bool} (h : R.Valid w) : t, R.spell t = w := R:RankedAlphabetw:List Boolh:R.Valid w t, R.spell t = w R:RankedAlphabetw:List Boolh:((R.scanFinal w).live && (R.scanFinal w).buf.isEmpty && (R.scanFinal w).depth == 1) = true t, R.spell t = w R:RankedAlphabetw:List Boolh:((R.scanFinal w).live = true (R.scanFinal w).buf = []) (R.scanFinal w).depth = 1 t, R.spell t = w R:RankedAlphabetw:List Boolhd:(R.scanFinal w).depth = 1hlive:(R.scanFinal w).live = truehbuf:(R.scanFinal w).buf = [] t, R.spell t = w R:RankedAlphabetw:List Boolhd:(R.scanFinal w).depth = 1hlive:(R.scanFinal w).live = truehbuf:(R.scanFinal w).buf = []t:R.Termrest:List Boolhe:R.spell t ++ rest = whlive':(R.scanFinal rest).live = truehbuf':(R.scanFinal rest).buf = []hd':(R.scanFinal rest).depth + 1 = (R.scanFinal w).depth t, R.spell t = w R:RankedAlphabetw:List Boolhd:(R.scanFinal w).depth = 1hlive:(R.scanFinal w).live = truehbuf:(R.scanFinal w).buf = []t:R.Termrest:List Boolhe:R.spell t ++ rest = whlive':(R.scanFinal rest).live = truehbuf':(R.scanFinal rest).buf = []hd':(R.scanFinal rest).depth + 1 = (R.scanFinal w).depthhz:(R.scanFinal rest).depth = 0 t, R.spell t = w R:RankedAlphabetw:List Boolhd:(R.scanFinal w).depth = 1hlive:(R.scanFinal w).live = truehbuf:(R.scanFinal w).buf = []t:R.Termrest:List Boolhe:R.spell t ++ rest = whlive':(R.scanFinal rest).live = truehbuf':(R.scanFinal rest).buf = []hd':(R.scanFinal rest).depth + 1 = (R.scanFinal w).depthhz:(R.scanFinal rest).depth = 0hnil:rest = [] t, R.spell t = w R:RankedAlphabetw:List Boolhd:(R.scanFinal w).depth = 1hlive:(R.scanFinal w).live = truehbuf:(R.scanFinal w).buf = []t:R.Termhe:R.spell t ++ [] = whlive':(R.scanFinal []).live = truehbuf':(R.scanFinal []).buf = []hd':(R.scanFinal []).depth + 1 = (R.scanFinal w).depthhz:(R.scanFinal []).depth = 0 t, R.spell t = w exact t, R:RankedAlphabetw:List Boolhd:(R.scanFinal w).depth = 1hlive:(R.scanFinal w).live = truehbuf:(R.scanFinal w).buf = []t:R.Termhe:R.spell t ++ [] = whlive':(R.scanFinal []).live = truehbuf':(R.scanFinal []).buf = []hd':(R.scanFinal []).depth + 1 = (R.scanFinal w).depthhz:(R.scanFinal []).depth = 0R.spell t = w All goals completed! 🐙

The encoding's image is exactly the valid words: the characterization the recognizer's correctness is stated against.

theorem valid_iff_exists_spell (R : RankedAlphabet) (w : List Bool) : R.Valid w t, R.spell t = w := exists_spell_of_valid R, fun t, ht ht valid_spell R t

The descent decides validity: a word is valid exactly when parse accepts it.

theorem valid_iff_isSome_parse (R : RankedAlphabet) (w : List Bool) : R.Valid w (R.parse w).isSome := R:RankedAlphabetw:List BoolR.Valid w (R.parse w).isSome = true R:RankedAlphabetw:List Bool(∃ t, R.spell t = w) (R.parse w).isSome = true R:RankedAlphabetw:List Boolx✝: t, R.spell t = wt:R.Termht:R.spell t = w(R.parse w).isSome = trueR:RankedAlphabetw:List Boolh:(R.parse w).isSome = true t, R.spell t = w R:RankedAlphabetw:List Boolx✝: t, R.spell t = wt:R.Termht:R.spell t = w(R.parse w).isSome = true R:RankedAlphabetw:List Boolx✝: t, R.spell t = wt:R.Termht:R.spell t = w(some t).isSome = true All goals completed! 🐙 R:RankedAlphabetw:List Boolh:(R.parse w).isSome = true t, R.spell t = w R:RankedAlphabetw:List Boolh:(R.parse w).isSome = truet:R.Termht:R.parse w = some t t, R.spell t = w All goals completed! 🐙
endend RankedAlphabet