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 Mathlib.Data.Nat.BinaryRec public import Mathlib.Data.Nat.Notation public import Mathlib.Tactic.ToDual
set_option doc.verso true

A bitwise scanner for delta-prefixed leaf payloads

The finite control distinguishes tree tags, the unary part of a delta header, the two binary header fields, and raw payload bits. The pending-subtree counter is changed only by fork tags and completed leaf payloads.

Main definitions

  • Mode records the current phase and its numeric counters.

  • step consumes exactly one input bit.

  • scan folds the transition over the input.

Tags

Elias delta code, binary tree, streaming recognizer

@[expose] public sectionnamespace Geb.BitTree.Elias.Scanner

Header and payload phases, with remaining lengths and partial binary values.

inductive Mode where | tree | zeros (count : ) | size (remaining value : ) | length (remaining value : ) | payload (remaining : ) | done | dead deriving DecidableEq, Repr, Inhabited

A phase and the number of pending subtrees.

abbrev State := Mode ×

Complete one leaf, recognizing the final pending subtree.

def finish (n : ) : State := if n = 1 then (.done, 0) else (.tree, n - 1)

Read one bit, including all phase changes that consume no additional input.

def step : State Bool State | (.tree, n), true => (.tree, n + 1) | (.tree, n), false => (.zeros 0, n) | (.zeros z, n), false => (.zeros (z + 1), n) | (.zeros z, n), true => if z = 0 then finish n else (.size z 1, n) | (.size r v, n), b => if r = 1 then (.length (Nat.bit b v - 1) 1, n) else (.size (r - 1) (Nat.bit b v), n) | (.length r v, n), b => if r = 1 then (.payload (Nat.bit b v - 1), n) else (.length (r - 1) (Nat.bit b v), n) | (.payload r, n), _ => if r = 1 then finish n else (.payload (r - 1), n) | (.done, n), _ => (.dead, n) | (.dead, n), _ => (.dead, n)

Scan from one pending root.

def scan (w : List Bool) : State := w.foldl step (.tree, 1)

Accept exactly when the complete root ends at the end of input.

def validBool (w : List Bool) : Bool := decide ((scan w).1 = .done)

Positive pending counts and positive remaining lengths in the active phases.

def Active : State Prop | (.done, n) | (.dead, n) => n = 0 | (.tree, n) | (.zeros _, n) => 0 < n | (.size r v, n) | (.length r v, n) => 0 < n 0 < r 0 < v | (.payload r, n) => 0 < n 0 < r

Completing an active leaf preserves the scanner invariant.

theorem active_finish (n : ) (hn : 0 < n) : Active (finish n) := n:hn:0 < nActive (finish n) n:hn:0 < nActive (if n = 1 then (Mode.done, 0) else (Mode.tree, n - 1)) n:hn:0 < nh✝:n = 1Active (Mode.done, 0)n:hn:0 < nh✝:¬n = 1Active (Mode.tree, n - 1) n:hn:0 < nh✝:n = 1Active (Mode.done, 0)n:hn:0 < nh✝:¬n = 1Active (Mode.tree, n - 1) n:hn:0 < nh✝:¬n = 10 < n - 1 n:hn:0 < nh✝:¬n = 10 < n - 1 All goals completed! 🐙

Consuming one bit preserves the invariant.

theorem active_step (s : State) (b : Bool) (h : Active s) : Active (step s b) := s:Stateb:Boolh:Active sActive (step s b) b:Boolm:Moden:h:Active (m, n)Active (step (m, n) b) cases m with b:Booln:h:Active (Mode.tree, n)Active (step (Mode.tree, n) b) b:Booln:h:0 < nActive (step (Mode.tree, n) b) n:h:0 < nActive (step (Mode.tree, n) false)n:h:0 < nActive (step (Mode.tree, n) true) n:h:0 < nActive (step (Mode.tree, n) false)n:h:0 < nActive (step (Mode.tree, n) true) n:h:0 < n0 < n + 1 n:h:0 < n0 < nn:h:0 < n0 < n + 1 All goals completed! 🐙 b:Booln:z:h:Active (Mode.zeros z, n)Active (step (Mode.zeros z, n) b) cases b with n:z:h:Active (Mode.zeros z, n)Active (step (Mode.zeros z, n) false) All goals completed! 🐙 n:z:h:Active (Mode.zeros z, n)Active (step (Mode.zeros z, n) true) n:z:h:Active (Mode.zeros z, n)Active (if z = 0 then finish n else (Mode.size z 1, n)) n:z:h:Active (Mode.zeros z, n)h✝:z = 0Active (finish n)n:z:h:Active (Mode.zeros z, n)h✝:¬z = 0Active (Mode.size z 1, n) n:z:h:Active (Mode.zeros z, n)h✝:z = 0Active (finish n) All goals completed! 🐙 n:z:h:Active (Mode.zeros z, n)h✝:¬z = 0Active (Mode.size z 1, n) exact h, n:z:h:Active (Mode.zeros z, n)h✝:¬z = 00 < z All goals completed! 🐙, n:z:h:Active (Mode.zeros z, n)h✝:¬z = 00 < 1 All goals completed! 🐙 b:Booln:r:v:h:Active (Mode.size r v, n)Active (step (Mode.size r v, n) b) b:Booln:r:v:hn:0 < nhr:0 < rhv:0 < vActive (step (Mode.size r v, n) b) b:Booln:r:v:hn:0 < nhr:0 < rhv:0 < vhb:2 Nat.bit b vActive (step (Mode.size r v, n) b) b:Booln:r:v:hn:0 < nhr:0 < rhv:0 < vhb:2 Nat.bit b vActive (if r = 1 then (Mode.length (Nat.bit b v - 1) 1, n) else (Mode.size (r - 1) (Nat.bit b v), n)) b:Booln:r:v:hn:0 < nhr:0 < rhv:0 < vhb:2 Nat.bit b vh✝:r = 1Active (Mode.length (Nat.bit b v - 1) 1, n)b:Booln:r:v:hn:0 < nhr:0 < rhv:0 < vhb:2 Nat.bit b vh✝:¬r = 1Active (Mode.size (r - 1) (Nat.bit b v), n) b:Booln:r:v:hn:0 < nhr:0 < rhv:0 < vhb:2 Nat.bit b vh✝:r = 1Active (Mode.length (Nat.bit b v - 1) 1, n) exact hn, b:Booln:r:v:hn:0 < nhr:0 < rhv:0 < vhb:2 Nat.bit b vh✝:r = 10 < Nat.bit b v - 1 All goals completed! 🐙, b:Booln:r:v:hn:0 < nhr:0 < rhv:0 < vhb:2 Nat.bit b vh✝:r = 10 < 1 All goals completed! 🐙 b:Booln:r:v:hn:0 < nhr:0 < rhv:0 < vhb:2 Nat.bit b vh✝:¬r = 1Active (Mode.size (r - 1) (Nat.bit b v), n) exact hn, b:Booln:r:v:hn:0 < nhr:0 < rhv:0 < vhb:2 Nat.bit b vh✝:¬r = 10 < r - 1 All goals completed! 🐙, b:Booln:r:v:hn:0 < nhr:0 < rhv:0 < vhb:2 Nat.bit b vh✝:¬r = 10 < Nat.bit b v All goals completed! 🐙 b:Booln:r:v:h:Active (Mode.length r v, n)Active (step (Mode.length r v, n) b) b:Booln:r:v:hn:0 < nhr:0 < rhv:0 < vActive (step (Mode.length r v, n) b) b:Booln:r:v:hn:0 < nhr:0 < rhv:0 < vhb:2 Nat.bit b vActive (step (Mode.length r v, n) b) b:Booln:r:v:hn:0 < nhr:0 < rhv:0 < vhb:2 Nat.bit b vActive (if r = 1 then (Mode.payload (Nat.bit b v - 1), n) else (Mode.length (r - 1) (Nat.bit b v), n)) b:Booln:r:v:hn:0 < nhr:0 < rhv:0 < vhb:2 Nat.bit b vh✝:r = 1Active (Mode.payload (Nat.bit b v - 1), n)b:Booln:r:v:hn:0 < nhr:0 < rhv:0 < vhb:2 Nat.bit b vh✝:¬r = 1Active (Mode.length (r - 1) (Nat.bit b v), n) b:Booln:r:v:hn:0 < nhr:0 < rhv:0 < vhb:2 Nat.bit b vh✝:r = 1Active (Mode.payload (Nat.bit b v - 1), n) exact hn, b:Booln:r:v:hn:0 < nhr:0 < rhv:0 < vhb:2 Nat.bit b vh✝:r = 10 < Nat.bit b v - 1 All goals completed! 🐙 b:Booln:r:v:hn:0 < nhr:0 < rhv:0 < vhb:2 Nat.bit b vh✝:¬r = 1Active (Mode.length (r - 1) (Nat.bit b v), n) exact hn, b:Booln:r:v:hn:0 < nhr:0 < rhv:0 < vhb:2 Nat.bit b vh✝:¬r = 10 < r - 1 All goals completed! 🐙, b:Booln:r:v:hn:0 < nhr:0 < rhv:0 < vhb:2 Nat.bit b vh✝:¬r = 10 < Nat.bit b v All goals completed! 🐙 b:Booln:r:h:Active (Mode.payload r, n)Active (step (Mode.payload r, n) b) b:Booln:r:hn:0 < nhr:0 < rActive (step (Mode.payload r, n) b) b:Booln:r:hn:0 < nhr:0 < rActive (if r = 1 then finish n else (Mode.payload (r - 1), n)) b:Booln:r:hn:0 < nhr:0 < rh✝:r = 1Active (finish n)b:Booln:r:hn:0 < nhr:0 < rh✝:¬r = 1Active (Mode.payload (r - 1), n) b:Booln:r:hn:0 < nhr:0 < rh✝:r = 1Active (finish n) All goals completed! 🐙 b:Booln:r:hn:0 < nhr:0 < rh✝:¬r = 1Active (Mode.payload (r - 1), n) exact hn, b:Booln:r:hn:0 < nhr:0 < rh✝:¬r = 10 < r - 1 All goals completed! 🐙 b:Booln:h:Active (Mode.done, n)Active (step (Mode.done, n) b) All goals completed! 🐙 b:Booln:h:Active (Mode.dead, n)Active (step (Mode.dead, n) b) All goals completed! 🐙

Every prefix of a scan satisfies the invariant.

theorem active_foldl (w : List Bool) : s, Active s Active (w.foldl step s) := List.rec (fun _ h h) (fun b _ ih s h ih (step s b) (active_step s b h)) w

The scanner starts and remains in an active or terminal state.

theorem scan_active (w : List Bool) : Active (scan w) := active_foldl w (.tree, 1) (show 0 < 1 All goals completed! 🐙 All goals completed! 🐙)

An incomplete raw payload stays in the payload phase.

theorem foldl_payload_short (w : List Bool) : r n, w.length < r w.foldl step (.payload r, n) = (.payload (r - w.length), n) := w:List Bool (r n : ), w.length < r List.foldl step (Mode.payload r, n) w = (Mode.payload (r - w.length), n) w:List Bool (r n : ), [].length < r List.foldl step (Mode.payload r, n) [] = (Mode.payload (r - [].length), n)w:List Bool (head : Bool) (tail : List Bool), (∀ (r n : ), tail.length < r List.foldl step (Mode.payload r, n) tail = (Mode.payload (r - tail.length), n)) (r n : ), (head :: tail).length < r List.foldl step (Mode.payload r, n) (head :: tail) = (Mode.payload (r - (head :: tail).length), n) w:List Bool (r n : ), [].length < r List.foldl step (Mode.payload r, n) [] = (Mode.payload (r - [].length), n) w:List Boolr:n:a✝:[].length < rList.foldl step (Mode.payload r, n) [] = (Mode.payload (r - [].length), n) All goals completed! 🐙 w:List Bool (head : Bool) (tail : List Bool), (∀ (r n : ), tail.length < r List.foldl step (Mode.payload r, n) tail = (Mode.payload (r - tail.length), n)) (r n : ), (head :: tail).length < r List.foldl step (Mode.payload r, n) (head :: tail) = (Mode.payload (r - (head :: tail).length), n) w:List Boolb:Boolbs:List Boolih: (r n : ), bs.length < r List.foldl step (Mode.payload r, n) bs = (Mode.payload (r - bs.length), n)r:n:h:(b :: bs).length < rList.foldl step (Mode.payload r, n) (b :: bs) = (Mode.payload (r - (b :: bs).length), n) w:List Boolb:Boolbs:List Boolih: (r n : ), bs.length < r List.foldl step (Mode.payload r, n) bs = (Mode.payload (r - bs.length), n)r:n:h:(b :: bs).length < rhr:r 1List.foldl step (Mode.payload r, n) (b :: bs) = (Mode.payload (r - (b :: bs).length), n) w:List Boolb:Boolbs:List Boolih: (r n : ), bs.length < r List.foldl step (Mode.payload r, n) bs = (Mode.payload (r - bs.length), n)r:n:h:(b :: bs).length < rhr:r 1List.foldl step (Mode.payload (r - 1), n) bs = (Mode.payload (r - (b :: bs).length), n) w:List Boolb:Boolbs:List Boolih: (r n : ), bs.length < r List.foldl step (Mode.payload r, n) bs = (Mode.payload (r - bs.length), n)r:n:h:(b :: bs).length < rhr:r 1(Mode.payload (r - 1 - bs.length), n) = (Mode.payload (r - (b :: bs).length), n) w:List Boolb:Boolbs:List Boolih: (r n : ), bs.length < r List.foldl step (Mode.payload r, n) bs = (Mode.payload (r - bs.length), n)r:n:h:(b :: bs).length < rhr:r 1r - 1 - bs.length = r - (b :: bs).length w:List Boolb:Boolbs:List Boolih: (r n : ), bs.length < r List.foldl step (Mode.payload r, n) bs = (Mode.payload (r - bs.length), n)r:n:h:(b :: bs).length < rhr:r 1r - 1 - bs.length = r - (bs.length + 1) All goals completed! 🐙

Consuming a complete nonempty raw payload completes one leaf.

theorem foldl_payload (w : List Bool) : n, w [] w.foldl step (.payload w.length, n) = finish n := w:List Bool (n : ), w [] List.foldl step (Mode.payload w.length, n) w = finish n w:List Bool (n : ), [] [] List.foldl step (Mode.payload [].length, n) [] = finish nw:List Bool (head : Bool) (tail : List Bool), (∀ (n : ), tail [] List.foldl step (Mode.payload tail.length, n) tail = finish n) (n : ), head :: tail [] List.foldl step (Mode.payload (head :: tail).length, n) (head :: tail) = finish n w:List Bool (n : ), [] [] List.foldl step (Mode.payload [].length, n) [] = finish n w:List Booln:h:[] []List.foldl step (Mode.payload [].length, n) [] = finish n All goals completed! 🐙 w:List Bool (head : Bool) (tail : List Bool), (∀ (n : ), tail [] List.foldl step (Mode.payload tail.length, n) tail = finish n) (n : ), head :: tail [] List.foldl step (Mode.payload (head :: tail).length, n) (head :: tail) = finish n w:List Boolb:Boolbs:List Boolih: (n : ), bs [] List.foldl step (Mode.payload bs.length, n) bs = finish nn:a✝:b :: bs []List.foldl step (Mode.payload (b :: bs).length, n) (b :: bs) = finish n cases bs with w:List Boolb:Booln:ih: (n : ), [] [] List.foldl step (Mode.payload [].length, n) [] = finish na✝:[b] []List.foldl step (Mode.payload [b].length, n) [b] = finish n All goals completed! 🐙 w:List Boolb:Booln:c:Boolcs:List Boolih: (n : ), c :: cs [] List.foldl step (Mode.payload (c :: cs).length, n) (c :: cs) = finish na✝:b :: c :: cs []List.foldl step (Mode.payload (b :: c :: cs).length, n) (b :: c :: cs) = finish n w:List Boolb:Booln:c:Boolcs:List Boolih: (n : ), c :: cs [] List.foldl step (Mode.payload (c :: cs).length, n) (c :: cs) = finish na✝:b :: c :: cs []List.foldl step (if cs.length + 1 + 1 - 1 = 1 then finish n else (Mode.payload (cs.length + 1 + 1 - 1 - 1), n)) cs = finish n exact ih n (w:List Boolb:Booln:c:Boolcs:List Boolih: (n : ), c :: cs [] List.foldl step (Mode.payload (c :: cs).length, n) (c :: cs) = finish na✝:b :: c :: cs []c :: cs [] w:List Boolb:Booln:c:Boolcs:List Boolih: (n : ), c :: cs [] List.foldl step (Mode.payload (c :: cs).length, n) (c :: cs) = finish na✝:b :: c :: cs []h:c :: cs = []False; All goals completed! 🐙)

A completed scanner with no further input remains completed.

theorem foldl_done (w : List Bool) (n : ) : (w.foldl step (.done, n)).1 = .done w = [] := w:List Booln:(List.foldl step (Mode.done, n) w).fst = Mode.done w = [] w:List Booln:hd: (bs : List Bool), List.foldl step (Mode.dead, n) bs = (Mode.dead, n)(List.foldl step (Mode.done, n) w).fst = Mode.done w = [] cases w with n:hd: (bs : List Bool), List.foldl step (Mode.dead, n) bs = (Mode.dead, n)(List.foldl step (Mode.done, n) []).fst = Mode.done [] = [] All goals completed! 🐙 n:hd: (bs : List Bool), List.foldl step (Mode.dead, n) bs = (Mode.dead, n)b:Boolbs:List Bool(List.foldl step (Mode.done, n) (b :: bs)).fst = Mode.done b :: bs = [] n:hd: (bs : List Bool), List.foldl step (Mode.dead, n) bs = (Mode.dead, n)b:Boolbs:List Bool(List.foldl step (Mode.dead, n) bs).fst = Mode.done b :: bs = [] n:hd: (bs : List Bool), List.foldl step (Mode.dead, n) bs = (Mode.dead, n)b:Boolbs:List Bool(Mode.dead, n).fst = Mode.done b :: bs = [] n:hd: (bs : List Bool), List.foldl step (Mode.dead, n) bs = (Mode.dead, n)b:Boolbs:List Bool(Mode.dead, n).fst = Mode.done b :: bs = []n:hd: (bs : List Bool), List.foldl step (Mode.dead, n) bs = (Mode.dead, n)b:Boolbs:List Boolb :: bs = [] (Mode.dead, n).fst = Mode.done n:hd: (bs : List Bool), List.foldl step (Mode.dead, n) bs = (Mode.dead, n)b:Boolbs:List Bool(Mode.dead, n).fst = Mode.done b :: bs = []n:hd: (bs : List Bool), List.foldl step (Mode.dead, n) bs = (Mode.dead, n)b:Boolbs:List Boolb :: bs = [] (Mode.dead, n).fst = Mode.done n:hd: (bs : List Bool), List.foldl step (Mode.dead, n) bs = (Mode.dead, n)b:Boolbs:List Boolh:b :: bs = [](Mode.dead, n).fst = Mode.done n:hd: (bs : List Bool), List.foldl step (Mode.dead, n) bs = (Mode.dead, n)b:Boolbs:List Boolh:(Mode.dead, n).fst = Mode.doneb :: bs = []n:hd: (bs : List Bool), List.foldl step (Mode.dead, n) bs = (Mode.dead, n)b:Boolbs:List Boolh:b :: bs = [](Mode.dead, n).fst = Mode.done All goals completed! 🐙

Acceptance after a declared payload supplies exactly that many raw bits and a suffix.

theorem payload_of_accept (w : List Bool) (m n : ) (h : (w.foldl step (if m = 0 then finish n else (.payload m, n))).1 = .done) : s rest, s.length = m w = s ++ rest (rest.foldl step (finish n)).1 = .done := w:List Boolm:n:h:(List.foldl step (if m = 0 then finish n else (Mode.payload m, n)) w).fst = Mode.done s rest, s.length = m w = s ++ rest (List.foldl step (finish n) rest).fst = Mode.done w:List Boolm:n:h:(List.foldl step (if m = 0 then finish n else (Mode.payload m, n)) w).fst = Mode.donehm:m = 0 s rest, s.length = m w = s ++ rest (List.foldl step (finish n) rest).fst = Mode.donew:List Boolm:n:h:(List.foldl step (if m = 0 then finish n else (Mode.payload m, n)) w).fst = Mode.donehm:¬m = 0 s rest, s.length = m w = s ++ rest (List.foldl step (finish n) rest).fst = Mode.done w:List Boolm:n:h:(List.foldl step (if m = 0 then finish n else (Mode.payload m, n)) w).fst = Mode.donehm:m = 0 s rest, s.length = m w = s ++ rest (List.foldl step (finish n) rest).fst = Mode.done w:List Booln:h:(List.foldl step (if 0 = 0 then finish n else (Mode.payload 0, n)) w).fst = Mode.done s rest, s.length = 0 w = s ++ rest (List.foldl step (finish n) rest).fst = Mode.done All goals completed! 🐙 w:List Boolm:n:h:(List.foldl step (if m = 0 then finish n else (Mode.payload m, n)) w).fst = Mode.donehm:¬m = 0 s rest, s.length = m w = s ++ rest (List.foldl step (finish n) rest).fst = Mode.done w:List Boolm:n:h:(List.foldl step (Mode.payload m, n) w).fst = Mode.donehm:¬m = 0 s rest, s.length = m w = s ++ rest (List.foldl step (finish n) rest).fst = Mode.done w:List Boolm:n:h:(List.foldl step (Mode.payload m, n) w).fst = Mode.donehm:¬m = 0hl:m w.length s rest, s.length = m w = s ++ rest (List.foldl step (finish n) rest).fst = Mode.donew:List Boolm:n:h:(List.foldl step (Mode.payload m, n) w).fst = Mode.donehm:¬m = 0hl:¬m w.length s rest, s.length = m w = s ++ rest (List.foldl step (finish n) rest).fst = Mode.done w:List Boolm:n:h:(List.foldl step (Mode.payload m, n) w).fst = Mode.donehm:¬m = 0hl:m w.length s rest, s.length = m w = s ++ rest (List.foldl step (finish n) rest).fst = Mode.done w:List Boolm:n:h:(List.foldl step (Mode.payload m, n) w).fst = Mode.donehm:¬m = 0hl:m w.lengthhs:(List.take m w).length = m s rest, s.length = m w = s ++ rest (List.foldl step (finish n) rest).fst = Mode.done w:List Boolm:n:h:(List.foldl step (Mode.payload m, n) w).fst = Mode.donehm:¬m = 0hl:m w.lengthhs:(List.take m w).length = mhne:List.take m w [] s rest, s.length = m w = s ++ rest (List.foldl step (finish n) rest).fst = Mode.done w:List Boolm:n:h:(List.foldl step (Mode.payload m, n) w).fst = Mode.donehm:¬m = 0hl:m w.lengthhs:(List.take m w).length = mhne:List.take m w [](List.foldl step (finish n) (List.drop m w)).fst = Mode.done w:List Boolm:n:h:(List.foldl step (Mode.payload m, n) w).fst = Mode.donehm:¬m = 0hl:m w.lengthhs:(List.take m w).length = mhne:List.take m w []hf:List.foldl step (Mode.payload (List.take m w).length, n) (List.take m w) = finish n(List.foldl step (finish n) (List.drop m w)).fst = Mode.done w:List Boolm:n:h:(List.foldl step (Mode.payload m, n) w).fst = Mode.donehm:¬m = 0hl:m w.lengthhs:(List.take m w).length = mhne:List.take m w []hf:List.foldl step (Mode.payload m, n) (List.take m w) = finish n(List.foldl step (finish n) (List.drop m w)).fst = Mode.done w:List Boolm:n:h:(List.foldl step (finish n) (List.drop m w)).fst = Mode.donehm:¬m = 0hl:m w.lengthhs:(List.take m w).length = mhne:List.take m w []hf:List.foldl step (Mode.payload m, n) (List.take m w) = finish n(List.foldl step (finish n) (List.drop m w)).fst = Mode.done All goals completed! 🐙 w:List Boolm:n:h:(List.foldl step (Mode.payload m, n) w).fst = Mode.donehm:¬m = 0hl:¬m w.length s rest, s.length = m w = s ++ rest (List.foldl step (finish n) rest).fst = Mode.done w:List Boolm:n:h:(Mode.payload (m - w.length), n).fst = Mode.donehm:¬m = 0hl:¬m w.length s rest, s.length = m w = s ++ rest (List.foldl step (finish n) rest).fst = Mode.done All goals completed! 🐙

One input bit introduces at most one additional pending subtree.

theorem step_pending_le (s : State) (b : Bool) : (step s b).2 s.2 + 1 := s:Stateb:Bool(step s b).snd s.snd + 1 s:Stateb:Boolhf: (n : ), (finish n).snd n + 1(step s b).snd s.snd + 1 b:Boolhf: (n : ), (finish n).snd n + 1m:Moden:(step (m, n) b).snd (m, n).snd + 1 b:Boolhf: (n : ), (finish n).snd n + 1n:(step (Mode.tree, n) b).snd (Mode.tree, n).snd + 1b:Boolhf: (n : ), (finish n).snd n + 1n:count✝:(step (Mode.zeros count✝, n) b).snd (Mode.zeros count✝, n).snd + 1b:Boolhf: (n : ), (finish n).snd n + 1n:remaining✝:value✝:(step (Mode.size remaining✝ value✝, n) b).snd (Mode.size remaining✝ value✝, n).snd + 1b:Boolhf: (n : ), (finish n).snd n + 1n:remaining✝:value✝:(step (Mode.length remaining✝ value✝, n) b).snd (Mode.length remaining✝ value✝, n).snd + 1b:Boolhf: (n : ), (finish n).snd n + 1n:remaining✝:(step (Mode.payload remaining✝, n) b).snd (Mode.payload remaining✝, n).snd + 1b:Boolhf: (n : ), (finish n).snd n + 1n:(step (Mode.done, n) b).snd (Mode.done, n).snd + 1b:Boolhf: (n : ), (finish n).snd n + 1n:(step (Mode.dead, n) b).snd (Mode.dead, n).snd + 1 b:Boolhf: (n : ), (finish n).snd n + 1n:(step (Mode.tree, n) b).snd (Mode.tree, n).snd + 1b:Boolhf: (n : ), (finish n).snd n + 1n:count✝:(step (Mode.zeros count✝, n) b).snd (Mode.zeros count✝, n).snd + 1b:Boolhf: (n : ), (finish n).snd n + 1n:remaining✝:value✝:(step (Mode.size remaining✝ value✝, n) b).snd (Mode.size remaining✝ value✝, n).snd + 1b:Boolhf: (n : ), (finish n).snd n + 1n:remaining✝:value✝:(step (Mode.length remaining✝ value✝, n) b).snd (Mode.length remaining✝ value✝, n).snd + 1b:Boolhf: (n : ), (finish n).snd n + 1n:remaining✝:(step (Mode.payload remaining✝, n) b).snd (Mode.payload remaining✝, n).snd + 1b:Boolhf: (n : ), (finish n).snd n + 1n:(step (Mode.done, n) b).snd (Mode.done, n).snd + 1b:Boolhf: (n : ), (finish n).snd n + 1n:(step (Mode.dead, n) b).snd (Mode.dead, n).snd + 1 hf: (n : ), (finish n).snd n + 1n:(step (Mode.dead, n) false).snd (Mode.dead, n).snd + 1hf: (n : ), (finish n).snd n + 1n:(step (Mode.dead, n) true).snd (Mode.dead, n).snd + 1 hf: (n : ), (finish n).snd n + 1n:(step (Mode.tree, n) false).snd (Mode.tree, n).snd + 1hf: (n : ), (finish n).snd n + 1n:(step (Mode.tree, n) true).snd (Mode.tree, n).snd + 1hf: (n : ), (finish n).snd n + 1n:count✝:(step (Mode.zeros count✝, n) false).snd (Mode.zeros count✝, n).snd + 1hf: (n : ), (finish n).snd n + 1n:count✝:(step (Mode.zeros count✝, n) true).snd (Mode.zeros count✝, n).snd + 1hf: (n : ), (finish n).snd n + 1n:remaining✝:value✝:(step (Mode.size remaining✝ value✝, n) false).snd (Mode.size remaining✝ value✝, n).snd + 1hf: (n : ), (finish n).snd n + 1n:remaining✝:value✝:(step (Mode.size remaining✝ value✝, n) true).snd (Mode.size remaining✝ value✝, n).snd + 1hf: (n : ), (finish n).snd n + 1n:remaining✝:value✝:(step (Mode.length remaining✝ value✝, n) false).snd (Mode.length remaining✝ value✝, n).snd + 1hf: (n : ), (finish n).snd n + 1n:remaining✝:value✝:(step (Mode.length remaining✝ value✝, n) true).snd (Mode.length remaining✝ value✝, n).snd + 1hf: (n : ), (finish n).snd n + 1n:remaining✝:(step (Mode.payload remaining✝, n) false).snd (Mode.payload remaining✝, n).snd + 1hf: (n : ), (finish n).snd n + 1n:remaining✝:(step (Mode.payload remaining✝, n) true).snd (Mode.payload remaining✝, n).snd + 1hf: (n : ), (finish n).snd n + 1n:(step (Mode.done, n) false).snd (Mode.done, n).snd + 1hf: (n : ), (finish n).snd n + 1n:(step (Mode.done, n) true).snd (Mode.done, n).snd + 1hf: (n : ), (finish n).snd n + 1n:(step (Mode.dead, n) false).snd (Mode.dead, n).snd + 1hf: (n : ), (finish n).snd n + 1n:(step (Mode.dead, n) true).snd (Mode.dead, n).snd + 1 hf: (n : ), (finish n).snd n + 1n:n n + 1 hf: (n : ), (finish n).snd n + 1n:n n + 1hf: (n : ), (finish n).snd n + 1n:n + 1 n + 1hf: (n : ), (finish n).snd n + 1n:count✝:n n + 1hf: (n : ), (finish n).snd n + 1n:count✝:(if count✝ = 0 then finish n else (Mode.size count✝ 1, n)).snd n + 1hf: (n : ), (finish n).snd n + 1n:remaining✝:value✝:(if remaining✝ = 1 then (Mode.length (Nat.bit false value✝ - 1) 1, n) else (Mode.size (remaining✝ - 1) (Nat.bit false value✝), n)).snd n + 1hf: (n : ), (finish n).snd n + 1n:remaining✝:value✝:(if remaining✝ = 1 then (Mode.length (Nat.bit true value✝ - 1) 1, n) else (Mode.size (remaining✝ - 1) (Nat.bit true value✝), n)).snd n + 1hf: (n : ), (finish n).snd n + 1n:remaining✝:value✝:(if remaining✝ = 1 then (Mode.payload (Nat.bit false value✝ - 1), n) else (Mode.length (remaining✝ - 1) (Nat.bit false value✝), n)).snd n + 1hf: (n : ), (finish n).snd n + 1n:remaining✝:value✝:(if remaining✝ = 1 then (Mode.payload (Nat.bit true value✝ - 1), n) else (Mode.length (remaining✝ - 1) (Nat.bit true value✝), n)).snd n + 1hf: (n : ), (finish n).snd n + 1n:remaining✝:(if remaining✝ = 1 then finish n else (Mode.payload (remaining✝ - 1), n)).snd n + 1hf: (n : ), (finish n).snd n + 1n:remaining✝:(if remaining✝ = 1 then finish n else (Mode.payload (remaining✝ - 1), n)).snd n + 1hf: (n : ), (finish n).snd n + 1n:n n + 1hf: (n : ), (finish n).snd n + 1n:n n + 1hf: (n : ), (finish n).snd n + 1n:n n + 1hf: (n : ), (finish n).snd n + 1n:n n + 1 first | hf: (n : ), (finish n).snd n + 1n:n n + 1 | All goals completed! 🐙 | (hf: (n : ), (finish n).snd n + 1n:remaining✝:h✝:remaining✝ = 1(finish n).snd n + 1hf: (n : ), (finish n).snd n + 1n:remaining✝:h✝:¬remaining✝ = 1(Mode.payload (remaining✝ - 1), n).snd n + 1 hf: (n : ), (finish n).snd n + 1n:remaining✝:h✝:remaining✝ = 1(finish n).snd n + 1hf: (n : ), (finish n).snd n + 1n:remaining✝:h✝:¬remaining✝ = 1(Mode.payload (remaining✝ - 1), n).snd n + 1 first | hf: (n : ), (finish n).snd n + 1n:remaining✝:h✝:¬remaining✝ = 1(Mode.payload (remaining✝ - 1), n).snd n + 1 | All goals completed! 🐙)

Pending subtrees are bounded by the initial count and the number of bits read.

theorem foldl_pending_le (w : List Bool) : s, (w.foldl step s).2 s.2 + w.length := w:List Bool (s : State), (List.foldl step s w).snd s.snd + w.length w:List Bool (s : State), (List.foldl step s []).snd s.snd + [].lengthw:List Bool (head : Bool) (tail : List Bool), (∀ (s : State), (List.foldl step s tail).snd s.snd + tail.length) (s : State), (List.foldl step s (head :: tail)).snd s.snd + (head :: tail).length w:List Bool (s : State), (List.foldl step s []).snd s.snd + [].length w:List Bools:State(List.foldl step s []).snd s.snd + [].length All goals completed! 🐙 w:List Bool (head : Bool) (tail : List Bool), (∀ (s : State), (List.foldl step s tail).snd s.snd + tail.length) (s : State), (List.foldl step s (head :: tail)).snd s.snd + (head :: tail).length w:List Boolb:Boolbs:List Boolih: (s : State), (List.foldl step s bs).snd s.snd + bs.lengths:State(List.foldl step s (b :: bs)).snd s.snd + (b :: bs).length w:List Boolb:Boolbs:List Boolih: (s : State), (List.foldl step s bs).snd s.snd + bs.lengths:Stateh:(List.foldl step (step s b) bs).snd (step s b).snd + bs.length(List.foldl step s (b :: bs)).snd s.snd + (b :: bs).length w:List Boolb:Boolbs:List Boolih: (s : State), (List.foldl step s bs).snd s.snd + bs.lengths:Stateh:(List.foldl step (step s b) bs).snd (step s b).snd + bs.lengthhb:(step s b).snd s.snd + 1(List.foldl step s (b :: bs)).snd s.snd + (b :: bs).length w:List Boolb:Boolbs:List Boolih: (s : State), (List.foldl step s bs).snd s.snd + bs.lengths:Stateh:(List.foldl step (step s b) bs).snd (step s b).snd + bs.lengthhb:(step s b).snd s.snd + 1(List.foldl step (step s b) bs).snd s.snd + (bs.length + 1) All goals completed! 🐙

The unary structural counter uses at most one plus the input length.

theorem scan_pending_le (w : List Bool) : (scan w).2 w.length + 1 := w:List Bool(scan w).snd w.length + 1 w:List Boolh:(List.foldl step (Mode.tree, 1) w).snd (Mode.tree, 1).snd + w.length(scan w).snd w.length + 1 w:List Boolh:(scan w).snd 1 + w.length(scan w).snd w.length + 1 All goals completed! 🐙
end Geb.BitTree.Elias.Scanner