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
set_option doc.verso true

Fixed-width binary countdown

Digits are stored least significant first, with leading zeroes retained. Decrement propagates a borrow through the initial zeroes and clears the first one. At zero it wraps within the existing width; numeric correctness is therefore stated for positive inputs.

Main definitions

  • value interprets a list of binary digits.

  • decrement preserves the width while subtracting one.

  • borrowFlips counts the digits changed by a borrow.

Main statements

  • length_decrement states width preservation.

  • value_decrement gives the numeric meaning for positive counter values.

Tags

binary counter, decrement, borrow, fixed width

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

Interpret binary digits, allowing leading zeroes.

def value (bs : List Bool) : := bs.foldr Nat.bit 0

Adding a least significant digit doubles the value and adds that digit.

theorem value_cons (b : Bool) (bs : List Bool) : value (b :: bs) = 2 * value bs + b.toNat := Nat.bit_val b (value bs)

Canonical binary digits represent the number from which they were obtained.

theorem value_bits (n : ) : value n.bits = n := foldr_bits n

A binary word represents zero exactly when all its digits are zero.

theorem value_eq_zero_iff (bs : List Bool) : value bs = 0 b bs, b = false := bs:List Boolvalue bs = 0 (b : Bool), b bs b = false bs:List Boolvalue [] = 0 (b : Bool), b [] b = falsebs:List Bool (head : Bool) (tail : List Bool), (value tail = 0 (b : Bool), b tail b = false) (value (head :: tail) = 0 (b : Bool), b head :: tail b = false) bs:List Boolvalue [] = 0 (b : Bool), b [] b = false All goals completed! 🐙 bs:List Bool (head : Bool) (tail : List Bool), (value tail = 0 (b : Bool), b tail b = false) (value (head :: tail) = 0 (b : Bool), b head :: tail b = false) bs✝:List Boolb:Boolbs:List Boolih:value bs = 0 (b : Bool), b bs b = falsevalue (b :: bs) = 0 (b_1 : Bool), b_1 b :: bs b_1 = false bs✝:List Boolb:Boolbs:List Boolih:value bs = 0 (b : Bool), b bs b = false2 * value bs + b.toNat = 0 b = false (x : Bool), x bs x = false bs✝:List Boolbs:List Boolih:value bs = 0 (b : Bool), b bs b = false2 * value bs + false.toNat = 0 false = false (x : Bool), x bs x = falsebs✝:List Boolbs:List Boolih:value bs = 0 (b : Bool), b bs b = false2 * value bs + true.toNat = 0 true = false (x : Bool), x bs x = false bs✝:List Boolbs:List Boolih:value bs = 0 (b : Bool), b bs b = false2 * value bs + false.toNat = 0 false = false (x : Bool), x bs x = false bs✝:List Boolbs:List Boolih:value bs = 0 (b : Bool), b bs b = false2 * value bs + 0 = 0 True (x : Bool), x bs x = false bs✝:List Boolbs:List Boolih:value bs = 0 (b : Bool), b bs b = false2 * value bs + 0 = 0 True (x : Bool), x bs x = falsebs✝:List Boolbs:List Boolih:value bs = 0 (b : Bool), b bs b = false(True (x : Bool), x bs x = false) 2 * value bs + 0 = 0 bs✝:List Boolbs:List Boolih:value bs = 0 (b : Bool), b bs b = false2 * value bs + 0 = 0 True (x : Bool), x bs x = false bs✝:List Boolbs:List Boolih:value bs = 0 (b : Bool), b bs b = falseh:2 * value bs + 0 = 0True (x : Bool), x bs x = false exact trivial, ih.mp (bs✝:List Boolbs:List Boolih:value bs = 0 (b : Bool), b bs b = falseh:2 * value bs + 0 = 0value bs = 0 All goals completed! 🐙) bs✝:List Boolbs:List Boolih:value bs = 0 (b : Bool), b bs b = false(True (x : Bool), x bs x = false) 2 * value bs + 0 = 0 bs✝:List Boolbs:List Boolih:value bs = 0 (b : Bool), b bs b = falseleft✝:Trueh: (x : Bool), x bs x = false2 * value bs + 0 = 0 bs✝:List Boolbs:List Boolih:value bs = 0 (b : Bool), b bs b = falseleft✝:Trueh: (x : Bool), x bs x = falseht:value bs = 02 * value bs + 0 = 0 All goals completed! 🐙 bs✝:List Boolbs:List Boolih:value bs = 0 (b : Bool), b bs b = false2 * value bs + true.toNat = 0 true = false (x : Bool), x bs x = false bs✝:List Boolbs:List Boolih:value bs = 0 (b : Bool), b bs b = false2 * value bs + 1 = 0 true = false (x : Bool), x bs x = false bs✝:List Boolbs:List Boolih:value bs = 0 (b : Bool), b bs b = false2 * value bs + 1 = 0 true = false (x : Bool), x bs x = falsebs✝:List Boolbs:List Boolih:value bs = 0 (b : Bool), b bs b = false(true = false (x : Bool), x bs x = false) 2 * value bs + 1 = 0 bs✝:List Boolbs:List Boolih:value bs = 0 (b : Bool), b bs b = false2 * value bs + 1 = 0 true = false (x : Bool), x bs x = false bs✝:List Boolbs:List Boolih:value bs = 0 (b : Bool), b bs b = falseh:2 * value bs + 1 = 0true = false (x : Bool), x bs x = false All goals completed! 🐙 bs✝:List Boolbs:List Boolih:value bs = 0 (b : Bool), b bs b = false(true = false (x : Bool), x bs x = false) 2 * value bs + 1 = 0 bs✝:List Boolbs:List Boolih:value bs = 0 (b : Bool), b bs b = falseh:true = falseright✝: (x : Bool), x bs x = false2 * value bs + 1 = 0 All goals completed! 🐙

The usual boolean test for an all-zero word agrees with its numeric value.

theorem all_not_eq_true_iff (bs : List Bool) : bs.all (fun b !b) = true value bs = 0 := bs:List Bool(bs.all fun b !b) = true value bs = 0 bs:List Bool(∀ (x : Bool), x bs (!x) = true) (b : Bool), b bs b = false bs:List Bool(∀ (x : Bool), x bs (!x) = true) (b : Bool), b bs b = falsebs:List Bool(∀ (b : Bool), b bs b = false) (x : Bool), x bs (!x) = true bs:List Bool(∀ (x : Bool), x bs (!x) = true) (b : Bool), b bs b = false bs:List Boolh: (x : Bool), x bs (!x) = trueb:Boolhb:b bsb = false bs:List Boolh: (x : Bool), x bs (!x) = trueb:Boolhb:b bshe:(!b) = trueb = false bs:List Boolh: (x : Bool), x bs (!x) = truehb:false bshe:(!false) = truefalse = falsebs:List Boolh: (x : Bool), x bs (!x) = truehb:true bshe:(!true) = truetrue = false bs:List Boolh: (x : Bool), x bs (!x) = truehb:false bshe:(!false) = truefalse = false All goals completed! 🐙 bs:List Boolh: (x : Bool), x bs (!x) = truehb:true bshe:(!true) = truetrue = false All goals completed! 🐙 bs:List Bool(∀ (b : Bool), b bs b = false) (x : Bool), x bs (!x) = true bs:List Boolh: (b : Bool), b bs b = falseb:Boolhb:b bs(!b) = true bs:List Boolh: (b : Bool), b bs b = falseb:Boolhb:b bs(!false) = true All goals completed! 🐙

Recording whether any digit is one detects a zero counter.

theorem any_eq_false_iff (bs : List Bool) : bs.any id = false value bs = 0 := bs:List Boolbs.any id = false value bs = 0 bs:List Bool(∀ (x : Bool), x bs ¬id x = true) (b : Bool), b bs b = false bs:List Bool(∀ (x : Bool), x bs ¬id x = true) (b : Bool), b bs b = falsebs:List Bool(∀ (b : Bool), b bs b = false) (x : Bool), x bs ¬id x = true bs:List Bool(∀ (x : Bool), x bs ¬id x = true) (b : Bool), b bs b = false bs:List Boolh: (x : Bool), x bs ¬id x = trueb:Boolhb:b bsb = false bs:List Boolh: (x : Bool), x bs ¬id x = trueb:Boolhb:b bshn:¬id b = trueb = false bs:List Boolh: (x : Bool), x bs ¬id x = truehb:false bshn:¬id false = truefalse = falsebs:List Boolh: (x : Bool), x bs ¬id x = truehb:true bshn:¬id true = truetrue = false bs:List Boolh: (x : Bool), x bs ¬id x = truehb:false bshn:¬id false = truefalse = false All goals completed! 🐙 bs:List Boolh: (x : Bool), x bs ¬id x = truehb:true bshn:¬id true = truetrue = false All goals completed! 🐙 bs:List Bool(∀ (b : Bool), b bs b = false) (x : Bool), x bs ¬id x = true bs:List Boolh: (b : Bool), b bs b = falseb:Boolhb:b bs¬id b = true bs:List Boolh: (b : Bool), b bs b = falseb:Boolhb:b bs¬id false = true bs:List Boolh: (b : Bool), b bs b = falseb:Boolhb:b bshe:id false = trueFalse All goals completed! 🐙

Subtract one within the existing width, wrapping an all-zero word.

def decrement : List Bool List Bool := List.rec [] fun b bs next if b then false :: bs else true :: next

Count the initial zeroes and the first one, or the whole width at zero.

def borrowFlips : List Bool := List.foldr (fun b n if b then 1 else n + 1) 0

Decrement never changes the allocated width.

theorem length_decrement (bs : List Bool) : (decrement bs).length = bs.length := bs:List Bool(decrement bs).length = bs.length bs:List Bool(decrement []).length = [].lengthbs:List Bool (head : Bool) (tail : List Bool), (decrement tail).length = tail.length (decrement (head :: tail)).length = (head :: tail).length bs:List Bool(decrement []).length = [].length All goals completed! 🐙 bs:List Bool (head : Bool) (tail : List Bool), (decrement tail).length = tail.length (decrement (head :: tail)).length = (head :: tail).length bs✝:List Boolb:Boolbs:List Boolih:(decrement bs).length = bs.length(decrement (b :: bs)).length = (b :: bs).length bs✝:List Boolbs:List Boolih:(decrement bs).length = bs.length(decrement (false :: bs)).length = (false :: bs).lengthbs✝:List Boolbs:List Boolih:(decrement bs).length = bs.length(decrement (true :: bs)).length = (true :: bs).length bs✝:List Boolbs:List Boolih:(decrement bs).length = bs.length(decrement (false :: bs)).length = (false :: bs).lengthbs✝:List Boolbs:List Boolih:(decrement bs).length = bs.length(decrement (true :: bs)).length = (true :: bs).length All goals completed! 🐙

A borrow changes at most the allocated width.

theorem borrowFlips_le_length (bs : List Bool) : borrowFlips bs bs.length := bs:List BoolborrowFlips bs bs.length bs:List BoolborrowFlips [] [].lengthbs:List Bool (head : Bool) (tail : List Bool), borrowFlips tail tail.length borrowFlips (head :: tail) (head :: tail).length bs:List BoolborrowFlips [] [].length All goals completed! 🐙 bs:List Bool (head : Bool) (tail : List Bool), borrowFlips tail tail.length borrowFlips (head :: tail) (head :: tail).length bs✝:List Boolb:Boolbs:List Boolih:borrowFlips bs bs.lengthborrowFlips (b :: bs) (b :: bs).length bs✝:List Boolbs:List Boolih:borrowFlips bs bs.lengthborrowFlips (false :: bs) (false :: bs).lengthbs✝:List Boolbs:List Boolih:borrowFlips bs bs.lengthborrowFlips (true :: bs) (true :: bs).length bs✝:List Boolbs:List Boolih:borrowFlips bs bs.lengthborrowFlips (false :: bs) (false :: bs).lengthbs✝:List Boolbs:List Boolih:borrowFlips bs bs.lengthborrowFlips (true :: bs) (true :: bs).length All goals completed! 🐙

Decrement subtracts one from every positive represented value.

theorem value_decrement (bs : List Bool) (h : 0 < value bs) : value (decrement bs) = value bs - 1 := bs:List Boolh:0 < value bsvalue (decrement bs) = value bs - 1 bs:List Bool0 < value bs value (decrement bs) = value bs - 1 bs:List Bool0 < value [] value (decrement []) = value [] - 1bs:List Bool (head : Bool) (tail : List Bool), (0 < value tail value (decrement tail) = value tail - 1) 0 < value (head :: tail) value (decrement (head :: tail)) = value (head :: tail) - 1 bs:List Bool0 < value [] value (decrement []) = value [] - 1 bs:List Boolh:0 < value []value (decrement []) = value [] - 1 All goals completed! 🐙 bs:List Bool (head : Bool) (tail : List Bool), (0 < value tail value (decrement tail) = value tail - 1) 0 < value (head :: tail) value (decrement (head :: tail)) = value (head :: tail) - 1 bs✝:List Boolb:Boolbs:List Boolih:0 < value bs value (decrement bs) = value bs - 1h:0 < value (b :: bs)value (decrement (b :: bs)) = value (b :: bs) - 1 bs✝:List Boolbs:List Boolih:0 < value bs value (decrement bs) = value bs - 1h:0 < value (false :: bs)value (decrement (false :: bs)) = value (false :: bs) - 1bs✝:List Boolbs:List Boolih:0 < value bs value (decrement bs) = value bs - 1h:0 < value (true :: bs)value (decrement (true :: bs)) = value (true :: bs) - 1 bs✝:List Boolbs:List Boolih:0 < value bs value (decrement bs) = value bs - 1h:0 < value (false :: bs)value (decrement (false :: bs)) = value (false :: bs) - 1 bs✝:List Boolbs:List Boolih:0 < value bs value (decrement bs) = value bs - 1h:0 < value (false :: bs)hp:0 < value bsvalue (decrement (false :: bs)) = value (false :: bs) - 1 bs✝:List Boolbs:List Boolih:0 < value bs value (decrement bs) = value bs - 1h:0 < value (false :: bs)hp:0 < value bsvalue (true :: decrement bs) = value (false :: bs) - 1 bs✝:List Boolbs:List Boolih:0 < value bs value (decrement bs) = value bs - 1h:0 < value (false :: bs)hp:0 < value bs2 * (value bs - 1) + true.toNat = 2 * value bs + false.toNat - 1 bs✝:List Boolbs:List Boolih:0 < value bs value (decrement bs) = value bs - 1h:0 < value (false :: bs)hp:0 < value bs2 * (value bs - 1) + 1 = 2 * value bs + 0 - 1 All goals completed! 🐙 bs✝:List Boolbs:List Boolih:0 < value bs value (decrement bs) = value bs - 1h:0 < value (true :: bs)value (decrement (true :: bs)) = value (true :: bs) - 1 bs✝:List Boolbs:List Boolih:0 < value bs value (decrement bs) = value bs - 1h:0 < value (true :: bs)value (false :: bs) = value (true :: bs) - 1 bs✝:List Boolbs:List Boolih:0 < value bs value (decrement bs) = value bs - 1h:0 < value (true :: bs)2 * value bs + false.toNat = 2 * value bs + true.toNat - 1 bs✝:List Boolbs:List Boolih:0 < value bs value (decrement bs) = value bs - 1h:0 < value (true :: bs)2 * value bs + 0 = 2 * value bs + 1 - 1 All goals completed! 🐙

A positive counter requires at least one changed digit.

theorem borrowFlips_pos (bs : List Bool) (h : 0 < value bs) : 0 < borrowFlips bs := bs:List Boolh:0 < value bs0 < borrowFlips bs cases bs with h:0 < value []0 < borrowFlips [] All goals completed! 🐙 b:Boolbs:List Boolh:0 < value (b :: bs)0 < borrowFlips (b :: bs) bs:List Boolh:0 < value (false :: bs)0 < borrowFlips (false :: bs)bs:List Boolh:0 < value (true :: bs)0 < borrowFlips (true :: bs) bs:List Boolh:0 < value (false :: bs)0 < borrowFlips (false :: bs)bs:List Boolh:0 < value (true :: bs)0 < borrowFlips (true :: bs) All goals completed! 🐙

Every digit before the final changed position is zero.

theorem getD_eq_false_of_lt_borrowFlips (bs : List Bool) (i : ) (h : i + 1 < borrowFlips bs) : bs[i]?.getD false = false := bs:List Booli:h:i + 1 < borrowFlips bsbs[i]?.getD false = false bs:List Bool (i : ), i + 1 < borrowFlips bs bs[i]?.getD false = false bs:List Bool (i : ), i + 1 < borrowFlips [] [][i]?.getD false = falsebs:List Bool (head : Bool) (tail : List Bool), (∀ (i : ), i + 1 < borrowFlips tail tail[i]?.getD false = false) (i : ), i + 1 < borrowFlips (head :: tail) (head :: tail)[i]?.getD false = false bs:List Bool (i : ), i + 1 < borrowFlips [] [][i]?.getD false = false bs:List Booli:a✝:i + 1 < borrowFlips [][][i]?.getD false = false All goals completed! 🐙 bs:List Bool (head : Bool) (tail : List Bool), (∀ (i : ), i + 1 < borrowFlips tail tail[i]?.getD false = false) (i : ), i + 1 < borrowFlips (head :: tail) (head :: tail)[i]?.getD false = false bs✝:List Boolb:Boolbs:List Boolih: (i : ), i + 1 < borrowFlips bs bs[i]?.getD false = falsei:hi:i + 1 < borrowFlips (b :: bs)(b :: bs)[i]?.getD false = false bs✝:List Boolbs:List Boolih: (i : ), i + 1 < borrowFlips bs bs[i]?.getD false = falsei:hi:i + 1 < borrowFlips (false :: bs)(false :: bs)[i]?.getD false = falsebs✝:List Boolbs:List Boolih: (i : ), i + 1 < borrowFlips bs bs[i]?.getD false = falsei:hi:i + 1 < borrowFlips (true :: bs)(true :: bs)[i]?.getD false = false bs✝:List Boolbs:List Boolih: (i : ), i + 1 < borrowFlips bs bs[i]?.getD false = falsei:hi:i + 1 < borrowFlips (false :: bs)(false :: bs)[i]?.getD false = false cases i with bs✝:List Boolbs:List Boolih: (i : ), i + 1 < borrowFlips bs bs[i]?.getD false = falsehi:0 + 1 < borrowFlips (false :: bs)(false :: bs)[0]?.getD false = false All goals completed! 🐙 bs✝:List Boolbs:List Boolih: (i : ), i + 1 < borrowFlips bs bs[i]?.getD false = falsei:hi:i + 1 + 1 < borrowFlips (false :: bs)(false :: bs)[i + 1]?.getD false = false bs✝:List Boolbs:List Boolih: (i : ), i + 1 < borrowFlips bs bs[i]?.getD false = falsei:hi:i + 1 + 1 < borrowFlips (false :: bs)bs[i]?.getD false = false bs✝:List Boolbs:List Boolih: (i : ), i + 1 < borrowFlips bs bs[i]?.getD false = falsei:hi:i + 1 + 1 < borrowFlips (false :: bs)i + 1 < borrowFlips bs bs✝:List Boolbs:List Boolih: (i : ), i + 1 < borrowFlips bs bs[i]?.getD false = falsei:hi:i + 1 + 1 < borrowFlips bs + 1i + 1 < borrowFlips bs All goals completed! 🐙 bs✝:List Boolbs:List Boolih: (i : ), i + 1 < borrowFlips bs bs[i]?.getD false = falsei:hi:i + 1 < borrowFlips (true :: bs)(true :: bs)[i]?.getD false = false bs✝:List Boolbs:List Boolih: (i : ), i + 1 < borrowFlips bs bs[i]?.getD false = falsei:hi:i + 1 < 1(true :: bs)[i]?.getD false = false All goals completed! 🐙

The final changed position of a positive counter contains one.

theorem getD_last_borrowFlips (bs : List Bool) (h : 0 < value bs) : bs[borrowFlips bs - 1]?.getD false = true := bs:List Boolh:0 < value bsbs[borrowFlips bs - 1]?.getD false = true bs:List Bool0 < value bs bs[borrowFlips bs - 1]?.getD false = true bs:List Bool0 < value [] [][borrowFlips [] - 1]?.getD false = truebs:List Bool (head : Bool) (tail : List Bool), (0 < value tail tail[borrowFlips tail - 1]?.getD false = true) 0 < value (head :: tail) (head :: tail)[borrowFlips (head :: tail) - 1]?.getD false = true bs:List Bool0 < value [] [][borrowFlips [] - 1]?.getD false = true bs:List Boolh:0 < value [][][borrowFlips [] - 1]?.getD false = true All goals completed! 🐙 bs:List Bool (head : Bool) (tail : List Bool), (0 < value tail tail[borrowFlips tail - 1]?.getD false = true) 0 < value (head :: tail) (head :: tail)[borrowFlips (head :: tail) - 1]?.getD false = true bs✝:List Boolb:Boolbs:List Boolih:0 < value bs bs[borrowFlips bs - 1]?.getD false = trueh:0 < value (b :: bs)(b :: bs)[borrowFlips (b :: bs) - 1]?.getD false = true bs✝:List Boolbs:List Boolih:0 < value bs bs[borrowFlips bs - 1]?.getD false = trueh:0 < value (false :: bs)(false :: bs)[borrowFlips (false :: bs) - 1]?.getD false = truebs✝:List Boolbs:List Boolih:0 < value bs bs[borrowFlips bs - 1]?.getD false = trueh:0 < value (true :: bs)(true :: bs)[borrowFlips (true :: bs) - 1]?.getD false = true bs✝:List Boolbs:List Boolih:0 < value bs bs[borrowFlips bs - 1]?.getD false = trueh:0 < value (false :: bs)(false :: bs)[borrowFlips (false :: bs) - 1]?.getD false = true bs✝:List Boolbs:List Boolih:0 < value bs bs[borrowFlips bs - 1]?.getD false = trueh:0 < value (false :: bs)hp:0 < value bs(false :: bs)[borrowFlips (false :: bs) - 1]?.getD false = true bs✝:List Boolbs:List Boolih:0 < value bs bs[borrowFlips bs - 1]?.getD false = trueh:0 < value (false :: bs)hp:0 < value bshf:0 < borrowFlips bs(false :: bs)[borrowFlips (false :: bs) - 1]?.getD false = true bs✝:List Boolbs:List Boolih:0 < value bs bs[borrowFlips bs - 1]?.getD false = trueh:0 < value (false :: bs)hp:0 < value bshf:0 < borrowFlips bshe:borrowFlips (false :: bs) - 1 = borrowFlips bs - 1 + 1(false :: bs)[borrowFlips (false :: bs) - 1]?.getD false = true All goals completed! 🐙 bs✝:List Boolbs:List Boolih:0 < value bs bs[borrowFlips bs - 1]?.getD false = trueh:0 < value (true :: bs)(true :: bs)[borrowFlips (true :: bs) - 1]?.getD false = true All goals completed! 🐙

Decrement flips exactly the initial borrow positions, preserving all later digits.

theorem getD_decrement (bs : List Bool) (i : ) : (decrement bs)[i]?.getD false = if i < borrowFlips bs then !bs[i]?.getD false else bs[i]?.getD false := bs:List Booli:(decrement bs)[i]?.getD false = if i < borrowFlips bs then !bs[i]?.getD false else bs[i]?.getD false bs:List Bool (i : ), (decrement bs)[i]?.getD false = if i < borrowFlips bs then !bs[i]?.getD false else bs[i]?.getD false bs:List Bool (i : ), (decrement [])[i]?.getD false = if i < borrowFlips [] then ![][i]?.getD false else [][i]?.getD falsebs:List Bool (head : Bool) (tail : List Bool), (∀ (i : ), (decrement tail)[i]?.getD false = if i < borrowFlips tail then !tail[i]?.getD false else tail[i]?.getD false) (i : ), (decrement (head :: tail))[i]?.getD false = if i < borrowFlips (head :: tail) then !(head :: tail)[i]?.getD false else (head :: tail)[i]?.getD false bs:List Bool (i : ), (decrement [])[i]?.getD false = if i < borrowFlips [] then ![][i]?.getD false else [][i]?.getD false bs:List Booli:(decrement [])[i]?.getD false = if i < borrowFlips [] then ![][i]?.getD false else [][i]?.getD false bs:List Booli:false = if i < 0 then true else false All goals completed! 🐙 bs:List Bool (head : Bool) (tail : List Bool), (∀ (i : ), (decrement tail)[i]?.getD false = if i < borrowFlips tail then !tail[i]?.getD false else tail[i]?.getD false) (i : ), (decrement (head :: tail))[i]?.getD false = if i < borrowFlips (head :: tail) then !(head :: tail)[i]?.getD false else (head :: tail)[i]?.getD false bs✝:List Boolb:Boolbs:List Boolih: (i : ), (decrement bs)[i]?.getD false = if i < borrowFlips bs then !bs[i]?.getD false else bs[i]?.getD falsei:(decrement (b :: bs))[i]?.getD false = if i < borrowFlips (b :: bs) then !(b :: bs)[i]?.getD false else (b :: bs)[i]?.getD false bs✝:List Boolbs:List Boolih: (i : ), (decrement bs)[i]?.getD false = if i < borrowFlips bs then !bs[i]?.getD false else bs[i]?.getD falsei:(decrement (false :: bs))[i]?.getD false = if i < borrowFlips (false :: bs) then !(false :: bs)[i]?.getD false else (false :: bs)[i]?.getD falsebs✝:List Boolbs:List Boolih: (i : ), (decrement bs)[i]?.getD false = if i < borrowFlips bs then !bs[i]?.getD false else bs[i]?.getD falsei:(decrement (true :: bs))[i]?.getD false = if i < borrowFlips (true :: bs) then !(true :: bs)[i]?.getD false else (true :: bs)[i]?.getD false bs✝:List Boolbs:List Boolih: (i : ), (decrement bs)[i]?.getD false = if i < borrowFlips bs then !bs[i]?.getD false else bs[i]?.getD falsei:(decrement (false :: bs))[i]?.getD false = if i < borrowFlips (false :: bs) then !(false :: bs)[i]?.getD false else (false :: bs)[i]?.getD false cases i with bs✝:List Boolbs:List Boolih: (i : ), (decrement bs)[i]?.getD false = if i < borrowFlips bs then !bs[i]?.getD false else bs[i]?.getD false(decrement (false :: bs))[0]?.getD false = if 0 < borrowFlips (false :: bs) then !(false :: bs)[0]?.getD false else (false :: bs)[0]?.getD false bs✝:List Boolbs:List Boolih: (i : ), (decrement bs)[i]?.getD false = if i < borrowFlips bs then !bs[i]?.getD false else bs[i]?.getD falsetrue = if 0 < borrowFlips bs + 1 then true else false All goals completed! 🐙 bs✝:List Boolbs:List Boolih: (i : ), (decrement bs)[i]?.getD false = if i < borrowFlips bs then !bs[i]?.getD false else bs[i]?.getD falsei:(decrement (false :: bs))[i + 1]?.getD false = if i + 1 < borrowFlips (false :: bs) then !(false :: bs)[i + 1]?.getD false else (false :: bs)[i + 1]?.getD false bs✝:List Boolbs:List Boolih: (i : ), (decrement bs)[i]?.getD false = if i < borrowFlips bs then !bs[i]?.getD false else bs[i]?.getD falsei:(decrement bs)[i]?.getD false = if i + 1 < borrowFlips bs + 1 then !bs[i]?.getD false else bs[i]?.getD false bs✝:List Boolbs:List Boolih: (i : ), (decrement bs)[i]?.getD false = if i < borrowFlips bs then !bs[i]?.getD false else bs[i]?.getD falsei:he:i + 1 < borrowFlips bs + 1 i < borrowFlips bs(decrement bs)[i]?.getD false = if i + 1 < borrowFlips bs + 1 then !bs[i]?.getD false else bs[i]?.getD false All goals completed! 🐙 bs✝:List Boolbs:List Boolih: (i : ), (decrement bs)[i]?.getD false = if i < borrowFlips bs then !bs[i]?.getD false else bs[i]?.getD falsei:(decrement (true :: bs))[i]?.getD false = if i < borrowFlips (true :: bs) then !(true :: bs)[i]?.getD false else (true :: bs)[i]?.getD false cases i with bs✝:List Boolbs:List Boolih: (i : ), (decrement bs)[i]?.getD false = if i < borrowFlips bs then !bs[i]?.getD false else bs[i]?.getD false(decrement (true :: bs))[0]?.getD false = if 0 < borrowFlips (true :: bs) then !(true :: bs)[0]?.getD false else (true :: bs)[0]?.getD false All goals completed! 🐙 bs✝:List Boolbs:List Boolih: (i : ), (decrement bs)[i]?.getD false = if i < borrowFlips bs then !bs[i]?.getD false else bs[i]?.getD falsei:(decrement (true :: bs))[i + 1]?.getD false = if i + 1 < borrowFlips (true :: bs) then !(true :: bs)[i + 1]?.getD false else (true :: bs)[i + 1]?.getD false bs✝:List Boolbs:List Boolih: (i : ), (decrement bs)[i]?.getD false = if i < borrowFlips bs then !bs[i]?.getD false else bs[i]?.getD falsei:bs[i]?.getD false = if i + 1 < 1 then !bs[i]?.getD false else bs[i]?.getD false All goals completed! 🐙

The zero-digit potential pays for a borrow even when zero wraps to all ones.

theorem borrowFlips_add_count_decrement_le (bs : List Bool) : borrowFlips bs + (decrement bs).count false bs.count false + 2 := bs:List BoolborrowFlips bs + List.count false (decrement bs) List.count false bs + 2 bs:List BoolborrowFlips [] + List.count false (decrement []) List.count false [] + 2bs:List Bool (head : Bool) (tail : List Bool), borrowFlips tail + List.count false (decrement tail) List.count false tail + 2 borrowFlips (head :: tail) + List.count false (decrement (head :: tail)) List.count false (head :: tail) + 2 bs:List BoolborrowFlips [] + List.count false (decrement []) List.count false [] + 2 All goals completed! 🐙 bs:List Bool (head : Bool) (tail : List Bool), borrowFlips tail + List.count false (decrement tail) List.count false tail + 2 borrowFlips (head :: tail) + List.count false (decrement (head :: tail)) List.count false (head :: tail) + 2 bs✝:List Boolb:Boolbs:List Boolih:borrowFlips bs + List.count false (decrement bs) List.count false bs + 2borrowFlips (b :: bs) + List.count false (decrement (b :: bs)) List.count false (b :: bs) + 2 bs✝:List Boolbs:List Boolih:borrowFlips bs + List.count false (decrement bs) List.count false bs + 2borrowFlips (false :: bs) + List.count false (decrement (false :: bs)) List.count false (false :: bs) + 2bs✝:List Boolbs:List Boolih:borrowFlips bs + List.count false (decrement bs) List.count false bs + 2borrowFlips (true :: bs) + List.count false (decrement (true :: bs)) List.count false (true :: bs) + 2 bs✝:List Boolbs:List Boolih:borrowFlips bs + List.count false (decrement bs) List.count false bs + 2borrowFlips (false :: bs) + List.count false (decrement (false :: bs)) List.count false (false :: bs) + 2bs✝:List Boolbs:List Boolih:borrowFlips bs + List.count false (decrement bs) List.count false bs + 2borrowFlips (true :: bs) + List.count false (decrement (true :: bs)) List.count false (true :: bs) + 2 bs✝:List Boolbs:List Boolih:List.foldr (fun b n if b = true then 1 else n + 1) 0 bs + List.count false (List.rec [] (fun b bs next if b = true then false :: bs else true :: next) bs) List.count false bs + 21 + (List.count false bs + 1) List.count false bs + 2 bs✝:List Boolbs:List Boolih:List.foldr (fun b n if b = true then 1 else n + 1) 0 bs + List.count false (List.rec [] (fun b bs next if b = true then false :: bs else true :: next) bs) List.count false bs + 2List.foldr (fun b n if b = true then 1 else n + 1) 0 bs + 1 + List.count false (List.rec [] (fun b bs next if b = true then false :: bs else true :: next) bs) List.count false bs + 1 + 2bs✝:List Boolbs:List Boolih:List.foldr (fun b n if b = true then 1 else n + 1) 0 bs + List.count false (List.rec [] (fun b bs next if b = true then false :: bs else true :: next) bs) List.count false bs + 21 + (List.count false bs + 1) List.count false bs + 2 All goals completed! 🐙
end Geb.BitTree.Elias.Counter