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.Prototypes.Computability.BitTree.Elias.CodeBits import Geb.Prototypes.Computability.BitTree.Counter meta import GebMeta -- shake: keep
set_option doc.verso true

Elias delta codes for natural numbers

The positive integer n + 1 is encoded by the Elias delta code: the gamma code of its binary size, followed by the remaining bits after its leading one. The gamma code prefixes the binary representation by one zero for each bit after its leading one. This is the delta code of Section V of

[Elias1975]Peter Elias (1975). “Universal codeword sets and representations of the integers”. IEEE Transactions on Information Theory 21(2), pp. 194–203. https://doi.org/10.1109/TIT.1975.1055349.
, shifted to include zero.

Main definitions

  • encodeNat encodes a natural number.

  • readNat decodes one number and retains its unconsumed suffix.

Main statements

  • readNat_encodeNat_append is the roundtrip law with an arbitrary suffix.

  • readNat_eq_some proves that successful decoding identifies a canonical prefix.

  • length_encodeNat gives the exact length.

  • length_encodeNat_le bounds the length by three times the binary size.

References

  • [Elias1975]Peter Elias (1975). “Universal codeword sets and representations of the integers”. IEEE Transactions on Information Theory 21(2), pp. 194–203. https://doi.org/10.1109/TIT.1975.1055349.

Tags

Elias delta code, Elias gamma code, prefix code, binary encoding

@[expose] public sectionnamespace Geb.BitTree.Elias

Read the number of zeros preceding the next one, failing if there is no one.

def readZeros : List Bool Option ( × List Bool) := List.rec none fun b bs next if b then some (0, bs) else next.map fun p (p.1 + 1, p.2)

One recursive clause of the zero-prefix reader.

theorem readZeros_cons (b : Bool) (bs : List Bool) : readZeros (b :: bs) = if b then some (0, bs) else (readZeros bs).map fun p (p.1 + 1, p.2) := rfl

A unary length prefix reads back with its suffix intact.

theorem readZeros_append (k : ) (rest : List Bool) : readZeros (List.replicate k false ++ true :: rest) = some (k, rest) := k:rest:List BoolreadZeros (List.replicate k false ++ true :: rest) = some (k, rest) k:rest:List BoolreadZeros (List.replicate Nat.zero false ++ true :: rest) = some (Nat.zero, rest)k:rest:List Bool (n : ), readZeros (List.replicate n false ++ true :: rest) = some (n, rest) readZeros (List.replicate n.succ false ++ true :: rest) = some (n.succ, rest) k:rest:List BoolreadZeros (List.replicate Nat.zero false ++ true :: rest) = some (Nat.zero, rest) All goals completed! 🐙 k:rest:List Bool (n : ), readZeros (List.replicate n false ++ true :: rest) = some (n, rest) readZeros (List.replicate n.succ false ++ true :: rest) = some (n.succ, rest) k✝:rest:List Boolk:ih:readZeros (List.replicate k false ++ true :: rest) = some (k, rest)readZeros (List.replicate k.succ false ++ true :: rest) = some (k.succ, rest) k✝:rest:List Boolk:ih:readZeros (List.replicate k false ++ true :: rest) = some (k, rest)(if false = true then some (0, List.replicate k false ++ true :: rest) else Option.map (fun p (p.fst + 1, p.snd)) (readZeros (List.replicate k false ++ true :: rest))) = some (k.succ, rest) All goals completed! 🐙

Successful zero-prefix parsing identifies the exact consumed prefix.

theorem readZeros_eq_some (w : List Bool) : k rest, readZeros w = some (k, rest) w = List.replicate k false ++ true :: rest := List.rec (fun k rest h w:List Boolk:rest:List Boolh:readZeros [] = some (k, rest)[] = List.replicate k false ++ true :: rest All goals completed! 🐙) (fun b bs ih k rest h w:List Boolb:Boolbs:List Boolih: (k : ) (rest : List Bool), readZeros bs = some (k, rest) bs = List.replicate k false ++ true :: restk:rest:List Boolh:readZeros (b :: bs) = some (k, rest)b :: bs = List.replicate k false ++ true :: rest cases b with w:List Boolbs:List Boolih: (k : ) (rest : List Bool), readZeros bs = some (k, rest) bs = List.replicate k false ++ true :: restk:rest:List Boolh:readZeros (true :: bs) = some (k, rest)true :: bs = List.replicate k false ++ true :: rest w:List Boolbs:List Boolih: (k : ) (rest : List Bool), readZeros bs = some (k, rest) bs = List.replicate k false ++ true :: restk:rest:List Boolh:some (0, bs) = some (k, rest)true :: bs = List.replicate k false ++ true :: rest w:List Boolbs:List Boolih: (k : ) (rest : List Bool), readZeros bs = some (k, rest) bs = List.replicate k false ++ true :: resth:some (0, bs) = some (0, bs)true :: bs = List.replicate 0 false ++ true :: bs All goals completed! 🐙 w:List Boolbs:List Boolih: (k : ) (rest : List Bool), readZeros bs = some (k, rest) bs = List.replicate k false ++ true :: restk:rest:List Boolh:readZeros (false :: bs) = some (k, rest)false :: bs = List.replicate k false ++ true :: rest w:List Boolbs:List Boolih: (k : ) (rest : List Bool), readZeros bs = some (k, rest) bs = List.replicate k false ++ true :: restk:rest:List Boolh:(if false = true then some (0, bs) else Option.map (fun p (p.fst + 1, p.snd)) (readZeros bs)) = some (k, rest)false :: bs = List.replicate k false ++ true :: rest w:List Boolbs:List Boolih: (k : ) (rest : List Bool), readZeros bs = some (k, rest) bs = List.replicate k false ++ true :: restk:rest:List Boolh:Option.map (fun p (p.fst + 1, p.snd)) (readZeros bs) = some (k, rest)false :: bs = List.replicate k false ++ true :: rest cases hx : readZeros bs with w:List Boolbs:List Boolih: (k : ) (rest : List Bool), readZeros bs = some (k, rest) bs = List.replicate k false ++ true :: restk:rest:List Boolh:Option.map (fun p (p.fst + 1, p.snd)) (readZeros bs) = some (k, rest)hx:readZeros bs = nonefalse :: bs = List.replicate k false ++ true :: rest All goals completed! 🐙 w:List Boolbs:List Boolih: (k : ) (rest : List Bool), readZeros bs = some (k, rest) bs = List.replicate k false ++ true :: restk:rest:List Boolh:Option.map (fun p (p.fst + 1, p.snd)) (readZeros bs) = some (k, rest)p: × List Boolhx:readZeros bs = some pfalse :: bs = List.replicate k false ++ true :: rest w:List Boolbs:List Boolih: (k : ) (rest : List Bool), readZeros bs = some (k, rest) bs = List.replicate k false ++ true :: restk:rest:List Boolh:Option.map (fun p (p.fst + 1, p.snd)) (readZeros bs) = some (k, rest)j:suffix:List Boolhx:readZeros bs = some (j, suffix)false :: bs = List.replicate k false ++ true :: rest w:List Boolbs:List Boolih: (k : ) (rest : List Bool), readZeros bs = some (k, rest) bs = List.replicate k false ++ true :: restk:rest:List Boolj:suffix:List Boolh:Option.map (fun p (p.fst + 1, p.snd)) (some (j, suffix)) = some (k, rest)hx:readZeros bs = some (j, suffix)false :: bs = List.replicate k false ++ true :: rest w:List Boolbs:List Boolih: (k : ) (rest : List Bool), readZeros bs = some (k, rest) bs = List.replicate k false ++ true :: restk:rest:List Boolj:suffix:List Boolh:Option.map (fun p (p.fst + 1, p.snd)) (some (j, suffix)) = some (k, rest)hx:readZeros bs = some (j, suffix)he:(fun p (p.fst + 1, p.snd)) (j, suffix) = (k, rest)false :: bs = List.replicate k false ++ true :: rest w:List Boolbs:List Boolih: (k : ) (rest : List Bool), readZeros bs = some (k, rest) bs = List.replicate k false ++ true :: restk:rest:List Boolj:suffix:List Boolh:Option.map (fun p (p.fst + 1, p.snd)) (some (j, suffix)) = some (k, rest)hx:readZeros bs = some (j, suffix)he:(fun p (p.fst + 1, p.snd)) (j, suffix) = (k, rest)hk:((fun p (p.fst + 1, p.snd)) (j, suffix)).fst = (k, rest).fstfalse :: bs = List.replicate k false ++ true :: rest w:List Boolbs:List Boolih: (k : ) (rest : List Bool), readZeros bs = some (k, rest) bs = List.replicate k false ++ true :: restk:rest:List Boolj:suffix:List Boolh:Option.map (fun p (p.fst + 1, p.snd)) (some (j, suffix)) = some (k, rest)hx:readZeros bs = some (j, suffix)he:(fun p (p.fst + 1, p.snd)) (j, suffix) = (k, rest)hk:((fun p (p.fst + 1, p.snd)) (j, suffix)).fst = (k, rest).fsthr:((fun p (p.fst + 1, p.snd)) (j, suffix)).snd = (k, rest).sndfalse :: bs = List.replicate k false ++ true :: rest w:List Boolbs:List Boolih: (k : ) (rest : List Bool), readZeros bs = some (k, rest) bs = List.replicate k false ++ true :: restk:rest:List Boolj:suffix:List Boolh:Option.map (fun p (p.fst + 1, p.snd)) (some (j, suffix)) = some (k, rest)hx:readZeros bs = some (j, suffix)he:(fun p (p.fst + 1, p.snd)) (j, suffix) = (k, rest)hr:((fun p (p.fst + 1, p.snd)) (j, suffix)).snd = (k, rest).sndhk:j + 1 = kfalse :: bs = List.replicate k false ++ true :: rest w:List Boolbs:List Boolih: (k : ) (rest : List Bool), readZeros bs = some (k, rest) bs = List.replicate k false ++ true :: restk:rest:List Boolj:suffix:List Boolh:Option.map (fun p (p.fst + 1, p.snd)) (some (j, suffix)) = some (k, rest)hx:readZeros bs = some (j, suffix)he:(fun p (p.fst + 1, p.snd)) (j, suffix) = (k, rest)hk:j + 1 = khr:suffix = restfalse :: bs = List.replicate k false ++ true :: rest All goals completed! 🐙) w

Gamma code of a positive integer; zero is assigned the same word as one.

def encodeGamma (n : ) : List Bool := List.replicate (n.size - 1) false ++ true :: payload n

Read one gamma-coded positive integer.

def readGamma (w : List Bool) : Option ( × List Bool) := (readZeros w).bind fun p readFixed p.1 p.2

A gamma-coded positive integer reads back with its suffix intact.

theorem readGamma_encodeGamma_append (n : ) (hn : n 0) (rest : List Bool) : readGamma (encodeGamma n ++ rest) = some (n, rest) := n:hn:n 0rest:List BoolreadGamma (encodeGamma n ++ rest) = some (n, rest) n:hn:n 0rest:List BoolreadFixed (n.size - 1) (payload n ++ rest) = some (n, rest) All goals completed! 🐙

Successful gamma decoding identifies a positive number and its exact canonical prefix.

theorem readGamma_eq_some (w : List Bool) (n : ) (rest : List Bool) (h : readGamma w = some (n, rest)) : n 0 w = encodeGamma n ++ rest := w:List Booln:rest:List Boolh:readGamma w = some (n, rest)n 0 w = encodeGamma n ++ rest cases hx : readZeros w with w:List Booln:rest:List Boolh:readGamma w = some (n, rest)hx:readZeros w = nonen 0 w = encodeGamma n ++ rest All goals completed! 🐙 w:List Booln:rest:List Boolh:readGamma w = some (n, rest)p: × List Boolhx:readZeros w = some pn 0 w = encodeGamma n ++ rest w:List Booln:rest:List Boolh:readGamma w = some (n, rest)k:suffix:List Boolhx:readZeros w = some (k, suffix)n 0 w = encodeGamma n ++ rest w:List Booln:rest:List Boolh:readGamma w = some (n, rest)k:suffix:List Boolhx:readZeros w = some (k, suffix)hf:readFixed k suffix = some (n, rest)n 0 w = encodeGamma n ++ rest w:List Booln:rest:List Boolh:readGamma w = some (n, rest)k:suffix:List Boolhx:readZeros w = some (k, suffix)hf:readFixed k suffix = some (n, rest)hn:n 0hs:n.size = k + 1hw:suffix = payload n ++ restn 0 w = encodeGamma n ++ rest w:List Booln:rest:List Boolh:readGamma w = some (n, rest)k:suffix:List Boolhx:readZeros w = some (k, suffix)hf:readFixed k suffix = some (n, rest)hn:n 0hs:n.size = k + 1hw:suffix = payload n ++ restw = encodeGamma n ++ rest w:List Booln:rest:List Boolh:readGamma w = some (n, rest)k:suffix:List Boolhx:readZeros w = some (k, suffix)hf:readFixed k suffix = some (n, rest)hn:n 0hs:n.size = k + 1hw:suffix = payload n ++ resthl:n.size - 1 = kw = encodeGamma n ++ rest w:List Booln:rest:List Boolh:readGamma w = some (n, rest)k:suffix:List Boolhx:readZeros w = some (k, suffix)hf:readFixed k suffix = some (n, rest)hn:n 0hs:n.size = k + 1hw:suffix = payload n ++ resthl:n.size - 1 = kList.replicate k false ++ true :: (payload n ++ rest) = List.replicate k false ++ true :: payload n ++ rest All goals completed! 🐙

Elias delta code of the positive integer one greater than the argument.

def encodeNat (n : ) : List Bool := encodeGamma (n + 1).size ++ payload (n + 1)

Decode one shifted Elias delta code and retain the remaining input.

def readNat (w : List Bool) : Option ( × List Bool) := (readGamma w).bind fun p (readFixed (p.1 - 1) p.2).bind fun q some (q.1 - 1, q.2)

Encoding followed by decoding recovers both the number and any appended suffix.

theorem readNat_encodeNat_append (n : ) (rest : List Bool) : readNat (encodeNat n ++ rest) = some (n, rest) := n:rest:List BoolreadNat (encodeNat n ++ rest) = some (n, rest) n:rest:List Boolhp:0 < (n + 1).sizereadNat (encodeNat n ++ rest) = some (n, rest) n:rest:List Boolhp:0 < (n + 1).size((readGamma (encodeGamma (n + 1).size ++ (payload (n + 1) ++ rest))).bind fun p (readFixed (p.fst - 1) p.snd).bind fun q some (q.fst - 1, q.snd)) = some (n, rest) n:rest:List Boolhp:0 < (n + 1).size((some ((n + 1).size, payload (n + 1) ++ rest)).bind fun p (readFixed (p.fst - 1) p.snd).bind fun q some (q.fst - 1, q.snd)) = some (n, rest) n:rest:List Boolhp:0 < (n + 1).size((readFixed ((n + 1).size - 1) (payload (n + 1) ++ rest)).bind fun q some (q.fst - 1, q.snd)) = some (n, rest) n:rest:List Boolhp:0 < (n + 1).size((some (n + 1, rest)).bind fun q some (q.fst - 1, q.snd)) = some (n, rest) All goals completed! 🐙

A successfully decoded word has exactly the canonical code as its consumed prefix.

theorem readNat_eq_some (w : List Bool) (n : ) (rest : List Bool) (h : readNat w = some (n, rest)) : w = encodeNat n ++ rest := w:List Booln:rest:List Boolh:readNat w = some (n, rest)w = encodeNat n ++ rest cases hg : readGamma w with w:List Booln:rest:List Boolh:readNat w = some (n, rest)hg:readGamma w = nonew = encodeNat n ++ rest All goals completed! 🐙 w:List Booln:rest:List Boolh:readNat w = some (n, rest)p: × List Boolhg:readGamma w = some pw = encodeNat n ++ rest w:List Booln:rest:List Boolh:readNat w = some (n, rest)k:suffix:List Boolhg:readGamma w = some (k, suffix)w = encodeNat n ++ rest w:List Booln:rest:List Boolh:readNat w = some (n, rest)k:suffix:List Boolhg:readGamma w = some (k, suffix)hk:k 0hw:w = encodeGamma k ++ suffixw = encodeNat n ++ rest cases hf : readFixed (k - 1) suffix with w:List Booln:rest:List Boolh:readNat w = some (n, rest)k:suffix:List Boolhg:readGamma w = some (k, suffix)hk:k 0hw:w = encodeGamma k ++ suffixhf:readFixed (k - 1) suffix = nonew = encodeNat n ++ rest All goals completed! 🐙 w:List Booln:rest:List Boolh:readNat w = some (n, rest)k:suffix:List Boolhg:readGamma w = some (k, suffix)hk:k 0hw:w = encodeGamma k ++ suffixp: × List Boolhf:readFixed (k - 1) suffix = some pw = encodeNat n ++ rest w:List Booln:rest:List Boolh:readNat w = some (n, rest)k:suffix:List Boolhg:readGamma w = some (k, suffix)hk:k 0hw:w = encodeGamma k ++ suffixm:tail:List Boolhf:readFixed (k - 1) suffix = some (m, tail)w = encodeNat n ++ rest w:List Booln:rest:List Boolh:readNat w = some (n, rest)k:suffix:List Boolhg:readGamma w = some (k, suffix)hk:k 0hw:w = encodeGamma k ++ suffixm:tail:List Boolhf:readFixed (k - 1) suffix = some (m, tail)hm:m 0hs:m.size = k - 1 + 1ht:suffix = payload m ++ tailw = encodeNat n ++ rest w:List Booln:rest:List Boolh:readNat w = some (n, rest)k:suffix:List Boolhg:readGamma w = some (k, suffix)hk:k 0hw:w = encodeGamma k ++ suffixm:tail:List Boolhf:readFixed (k - 1) suffix = some (m, tail)hm:m 0hs:m.size = k - 1 + 1ht:suffix = payload m ++ tailhe:(m - 1, tail) = (n, rest)w = encodeNat n ++ rest w:List Booln:rest:List Boolh:readNat w = some (n, rest)k:suffix:List Boolhg:readGamma w = some (k, suffix)hk:k 0hw:w = encodeGamma k ++ suffixm:tail:List Boolhf:readFixed (k - 1) suffix = some (m, tail)hm:m 0hs:m.size = k - 1 + 1ht:suffix = payload m ++ tailhe:(m - 1, tail) = (n, rest)hn:(m - 1, tail).fst = (n, rest).fstw = encodeNat n ++ rest w:List Booln:rest:List Boolh:readNat w = some (n, rest)k:suffix:List Boolhg:readGamma w = some (k, suffix)hk:k 0hw:w = encodeGamma k ++ suffixm:tail:List Boolhf:readFixed (k - 1) suffix = some (m, tail)hm:m 0hs:m.size = k - 1 + 1ht:suffix = payload m ++ tailhe:(m - 1, tail) = (n, rest)hn:(m - 1, tail).fst = (n, rest).fsthr:(m - 1, tail).snd = (n, rest).sndw = encodeNat n ++ rest w:List Booln:rest:List Boolh:readNat w = some (n, rest)k:suffix:List Boolhg:readGamma w = some (k, suffix)hk:k 0hw:w = encodeGamma k ++ suffixm:tail:List Boolhf:readFixed (k - 1) suffix = some (m, tail)hm:m 0hs:m.size = k - 1 + 1ht:suffix = payload m ++ tailhe:(m - 1, tail) = (n, rest)hr:(m - 1, tail).snd = (n, rest).sndhn:m - 1 = nw = encodeNat n ++ rest w:List Booln:rest:List Boolh:readNat w = some (n, rest)k:suffix:List Boolhg:readGamma w = some (k, suffix)hk:k 0hw:w = encodeGamma k ++ suffixm:tail:List Boolhf:readFixed (k - 1) suffix = some (m, tail)hm:m 0hs:m.size = k - 1 + 1ht:suffix = payload m ++ tailhe:(m - 1, tail) = (n, rest)hn:m - 1 = nhr:tail = restw = encodeNat n ++ rest w:List Booln:rest:List Boolh:readNat w = some (n, rest)k:suffix:List Boolhg:readGamma w = some (k, suffix)hk:k 0hw:w = encodeGamma k ++ suffixm:tail:List Boolhf:readFixed (k - 1) suffix = some (m, tail)hm:m 0hs:m.size = k - 1 + 1ht:suffix = payload m ++ tailhe:(m - 1, tail) = (n, rest)hn:m - 1 = nhr:tail = resthm':m = n + 1w = encodeNat n ++ rest w:List Booln:rest:List Boolh:readNat w = some (n, rest)k:suffix:List Boolhg:readGamma w = some (k, suffix)hk:k 0hw:w = encodeGamma k ++ suffixm:tail:List Boolhf:readFixed (k - 1) suffix = some (m, tail)hm:m 0hs:(n + 1).size = k - 1 + 1ht:suffix = payload m ++ tailhe:(m - 1, tail) = (n, rest)hn:m - 1 = nhr:tail = resthm':m = n + 1w = encodeNat n ++ rest w:List Booln:rest:List Boolh:readNat w = some (n, rest)k:suffix:List Boolhg:readGamma w = some (k, suffix)hk:k 0hw:w = encodeGamma k ++ suffixm:tail:List Boolhf:readFixed (k - 1) suffix = some (m, tail)hm:m 0hs:(n + 1).size = k - 1 + 1ht:suffix = payload m ++ tailhe:(m - 1, tail) = (n, rest)hn:m - 1 = nhr:tail = resthm':m = n + 1hk':k = (n + 1).sizew = encodeNat n ++ rest All goals completed! 🐙

Success is equivalent to having the canonical encoding as a prefix.

theorem readNat_eq_some_iff (w : List Bool) (n : ) (rest : List Bool) : readNat w = some (n, rest) w = encodeNat n ++ rest := readNat_eq_some w n rest, fun h h readNat_encodeNat_append n rest

Both the encoded value and the end of its code are uniquely determined.

theorem encodeNat_append_injective (n m : ) (s t : List Bool) (h : encodeNat n ++ s = encodeNat m ++ t) : n = m s = t := n:m:s:List Boolt:List Boolh:encodeNat n ++ s = encodeNat m ++ tn = m s = t n:m:s:List Boolt:List Boolh:encodeNat n ++ s = encodeNat m ++ the:readNat (encodeNat n ++ s) = readNat (encodeNat m ++ t)n = m s = t n:m:s:List Boolt:List Boolh:encodeNat n ++ s = encodeNat m ++ the:some (n, s) = some (m, t)n = m s = t All goals completed! 🐙

Distinct natural numbers have distinct delta codes.

theorem encodeNat_injective : Function.Injective encodeNat := Function.Injective encodeNat n:m:h:encodeNat n = encodeNat mn = m exact (encodeNat_append_injective n m [] [] (n:m:h:encodeNat n = encodeNat mencodeNat n ++ [] = encodeNat m ++ [] All goals completed! 🐙)).1

Gamma coding adds one zero for each bit after the leading one.

theorem length_encodeGamma (n : ) : (encodeGamma n).length = 2 * (n.size - 1) + 1 := n:(encodeGamma n).length = 2 * (n.size - 1) + 1 n:n.size - 1 + (n.size - 1 + 1) = 2 * (n.size - 1) + 1 All goals completed! 🐙

The exact length of the shifted Elias delta code.

theorem length_encodeNat (n : ) : (encodeNat n).length = (n + 1).size + 2 * ((n + 1).size.size - 1) := n:(encodeNat n).length = (n + 1).size + 2 * ((n + 1).size.size - 1) n:hp:0 < (n + 1).size(encodeNat n).length = (n + 1).size + 2 * ((n + 1).size.size - 1) n:hp:0 < (n + 1).size2 * ((n + 1).size.size - 1) + 1 + ((n + 1).size - 1) = (n + 1).size + 2 * ((n + 1).size.size - 1) All goals completed! 🐙

Delta coding uses at most three times the binary size of the shifted argument.

theorem length_encodeNat_le (n : ) : (encodeNat n).length 3 * (n + 1).size := n:(encodeNat n).length 3 * (n + 1).size n:hs:(n + 1).size.size (n + 1).size(encodeNat n).length 3 * (n + 1).size n:hs:(n + 1).size.size (n + 1).size(n + 1).size + 2 * ((n + 1).size.size - 1) 3 * (n + 1).size All goals completed! 🐙

Every encoded natural number consumes at least one bit.

theorem length_encodeNat_pos (n : ) : 0 < (encodeNat n).length := n:0 < (encodeNat n).length n:hp:0 < (n + 1).size0 < (encodeNat n).length n:hp:0 < (n + 1).size0 < (n + 1).size + 2 * ((n + 1).size.size - 1) All goals completed! 🐙

Successful parsing strictly shortens the input.

theorem readNat_rest_length_lt (w : List Bool) (n : ) (rest : List Bool) (h : readNat w = some (n, rest)) : rest.length < w.length := w:List Booln:rest:List Boolh:readNat w = some (n, rest)rest.length < w.length w:List Booln:rest:List Boolh:readNat w = some (n, rest)hp:0 < (encodeNat n).lengthrest.length < w.length w:List Booln:rest:List Boolh:readNat w = some (n, rest)hp:0 < (encodeNat n).lengthrest.length < (encodeNat n).length + rest.length All goals completed! 🐙
end Geb.BitTree.Elias