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.CodeBitsset_option doc.verso trueFixed-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
-
valueinterprets a list of binary digits. -
decrementpreserves the width while subtracting one. -
borrowFlipscounts the digits changed by a borrow.
Main statements
-
length_decrementstates width preservation. -
value_decrementgives the numeric meaning for positive counter values.
Tags
binary counter, decrement, borrow, fixed width
@[expose] public sectionnamespace Geb.BitTree.Elias.CounterInterpret binary digits, allowing leading zeroes.
def value (bs : List Bool) : ℕ := bs.foldr Nat.bit 0Adding 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 nA 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 Bool⊢ value bs = 0 ↔ ∀ (b : Bool), b ∈ bs → b = false
bs:List Bool⊢ value [] = 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 Bool⊢ value [] = 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 = false⊢ value (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 = false⊢ 2 * value bs + b.toNat = 0 ↔ b = false ∧ ∀ (x : Bool), x ∈ bs → x = false
cases b false bs✝:List Boolbs:List Boolih:value bs = 0 ↔ ∀ (b : Bool), b ∈ bs → b = false⊢ 2 * value bs + false.toNat = 0 ↔ false = false ∧ ∀ (x : Bool), x ∈ bs → x = falsetrue bs✝:List Boolbs:List Boolih:value bs = 0 ↔ ∀ (b : Bool), b ∈ bs → b = false⊢ 2 * value bs + true.toNat = 0 ↔ true = false ∧ ∀ (x : Bool), x ∈ bs → x = false
· false bs✝:List Boolbs:List Boolih:value bs = 0 ↔ ∀ (b : Bool), b ∈ bs → b = false⊢ 2 * value bs + false.toNat = 0 ↔ false = false ∧ ∀ (x : Bool), x ∈ bs → x = false simp only [Bool.toNat_false] false bs✝:List Boolbs:List Boolih:value bs = 0 ↔ ∀ (b : Bool), b ∈ bs → b = false⊢ 2 * value bs + 0 = 0 ↔ True ∧ ∀ (x : Bool), x ∈ bs → x = false
constructor false.mp bs✝:List Boolbs:List Boolih:value bs = 0 ↔ ∀ (b : Bool), b ∈ bs → b = false⊢ 2 * value bs + 0 = 0 → True ∧ ∀ (x : Bool), x ∈ bs → x = falsefalse.mpr 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
· false.mp bs✝:List Boolbs:List Boolih:value bs = 0 ↔ ∀ (b : Bool), b ∈ bs → b = false⊢ 2 * value bs + 0 = 0 → True ∧ ∀ (x : Bool), x ∈ bs → x = false intro h false.mp bs✝:List Boolbs:List Boolih:value bs = 0 ↔ ∀ (b : Bool), b ∈ bs → b = falseh:2 * value bs + 0 = 0⊢ True ∧ ∀ (x : Bool), x ∈ bs → x = false
exact ⟨trivial, ih.mp (by bs✝:List Boolbs:List Boolih:value bs = 0 ↔ ∀ (b : Bool), b ∈ bs → b = falseh:2 * value bs + 0 = 0⊢ value bs = 0 omega All goals completed! 🐙)⟩
· false.mpr 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 rintro ⟨_, h⟩ false.mpr bs✝:List Boolbs:List Boolih:value bs = 0 ↔ ∀ (b : Bool), b ∈ bs → b = falseleft✝:Trueh:∀ (x : Bool), x ∈ bs → x = false⊢ 2 * value bs + 0 = 0
have ht := ih.mpr h false.mpr bs✝:List Boolbs:List Boolih:value bs = 0 ↔ ∀ (b : Bool), b ∈ bs → b = falseleft✝:Trueh:∀ (x : Bool), x ∈ bs → x = falseht:value bs = 0⊢ 2 * value bs + 0 = 0
omega All goals completed! 🐙
· true bs✝:List Boolbs:List Boolih:value bs = 0 ↔ ∀ (b : Bool), b ∈ bs → b = false⊢ 2 * value bs + true.toNat = 0 ↔ true = false ∧ ∀ (x : Bool), x ∈ bs → x = false simp only [Bool.toNat_true] true bs✝:List Boolbs:List Boolih:value bs = 0 ↔ ∀ (b : Bool), b ∈ bs → b = false⊢ 2 * value bs + 1 = 0 ↔ true = false ∧ ∀ (x : Bool), x ∈ bs → x = false
constructor true.mp bs✝:List Boolbs:List Boolih:value bs = 0 ↔ ∀ (b : Bool), b ∈ bs → b = false⊢ 2 * value bs + 1 = 0 → true = false ∧ ∀ (x : Bool), x ∈ bs → x = falsetrue.mpr 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
· true.mp bs✝:List Boolbs:List Boolih:value bs = 0 ↔ ∀ (b : Bool), b ∈ bs → b = false⊢ 2 * value bs + 1 = 0 → true = false ∧ ∀ (x : Bool), x ∈ bs → x = false intro h true.mp bs✝:List Boolbs:List Boolih:value bs = 0 ↔ ∀ (b : Bool), b ∈ bs → b = falseh:2 * value bs + 1 = 0⊢ true = false ∧ ∀ (x : Bool), x ∈ bs → x = false
omega All goals completed! 🐙
· true.mpr 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 rintro ⟨h, _⟩ true.mpr bs✝:List Boolbs:List Boolih:value bs = 0 ↔ ∀ (b : Bool), b ∈ bs → b = falseh:true = falseright✝:∀ (x : Bool), x ∈ bs → x = false⊢ 2 * value bs + 1 = 0
cases h 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 := by bs:List Bool⊢ (bs.all fun b ↦ !b) = true ↔ value bs = 0
rw [value_eq_zero_iff, bs:List Bool⊢ (bs.all fun b ↦ !b) = true ↔ ∀ (b : Bool), b ∈ bs → b = false List.all_eq_true 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 = false
constructor mp bs:List Bool⊢ (∀ (x : Bool), x ∈ bs → (!x) = true) → ∀ (b : Bool), b ∈ bs → b = falsempr bs:List Bool⊢ (∀ (b : Bool), b ∈ bs → b = false) → ∀ (x : Bool), x ∈ bs → (!x) = true
· mp bs:List Bool⊢ (∀ (x : Bool), x ∈ bs → (!x) = true) → ∀ (b : Bool), b ∈ bs → b = false intro h b hb mp bs:List Boolh:∀ (x : Bool), x ∈ bs → (!x) = trueb:Boolhb:b ∈ bs⊢ b = false
have he := h b hb mp bs:List Boolh:∀ (x : Bool), x ∈ bs → (!x) = trueb:Boolhb:b ∈ bshe:(!b) = true⊢ b = false
cases b mp.false bs:List Boolh:∀ (x : Bool), x ∈ bs → (!x) = truehb:false ∈ bshe:(!false) = true⊢ false = falsemp.true bs:List Boolh:∀ (x : Bool), x ∈ bs → (!x) = truehb:true ∈ bshe:(!true) = true⊢ true = false
· mp.false bs:List Boolh:∀ (x : Bool), x ∈ bs → (!x) = truehb:false ∈ bshe:(!false) = true⊢ false = false rfl All goals completed! 🐙
· mp.true bs:List Boolh:∀ (x : Bool), x ∈ bs → (!x) = truehb:true ∈ bshe:(!true) = true⊢ true = false cases he All goals completed! 🐙
· mpr bs:List Bool⊢ (∀ (b : Bool), b ∈ bs → b = false) → ∀ (x : Bool), x ∈ bs → (!x) = true intro h b hb mpr bs:List Boolh:∀ (b : Bool), b ∈ bs → b = falseb:Boolhb:b ∈ bs⊢ (!b) = true
rw [h b hb mpr bs:List Boolh:∀ (b : Bool), b ∈ bs → b = falseb:Boolhb:b ∈ bs⊢ (!false) = true] mpr bs:List Boolh:∀ (b : Bool), b ∈ bs → b = falseb:Boolhb:b ∈ bs⊢ (!false) = true
rfl 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 := by bs:List Bool⊢ bs.any id = false ↔ value bs = 0
rw [List.any_eq_false, bs:List Bool⊢ (∀ (x : Bool), x ∈ bs → ¬id x = true) ↔ value bs = 0 value_eq_zero_iff 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 = false
constructor mp bs:List Bool⊢ (∀ (x : Bool), x ∈ bs → ¬id x = true) → ∀ (b : Bool), b ∈ bs → b = falsempr bs:List Bool⊢ (∀ (b : Bool), b ∈ bs → b = false) → ∀ (x : Bool), x ∈ bs → ¬id x = true
· mp bs:List Bool⊢ (∀ (x : Bool), x ∈ bs → ¬id x = true) → ∀ (b : Bool), b ∈ bs → b = false intro h b hb mp bs:List Boolh:∀ (x : Bool), x ∈ bs → ¬id x = trueb:Boolhb:b ∈ bs⊢ b = false
have hn := h b hb mp bs:List Boolh:∀ (x : Bool), x ∈ bs → ¬id x = trueb:Boolhb:b ∈ bshn:¬id b = true⊢ b = false
cases b mp.false bs:List Boolh:∀ (x : Bool), x ∈ bs → ¬id x = truehb:false ∈ bshn:¬id false = true⊢ false = falsemp.true bs:List Boolh:∀ (x : Bool), x ∈ bs → ¬id x = truehb:true ∈ bshn:¬id true = true⊢ true = false
· mp.false bs:List Boolh:∀ (x : Bool), x ∈ bs → ¬id x = truehb:false ∈ bshn:¬id false = true⊢ false = false rfl All goals completed! 🐙
· mp.true bs:List Boolh:∀ (x : Bool), x ∈ bs → ¬id x = truehb:true ∈ bshn:¬id true = true⊢ true = false exact False.elim (hn rfl) All goals completed! 🐙
· mpr bs:List Bool⊢ (∀ (b : Bool), b ∈ bs → b = false) → ∀ (x : Bool), x ∈ bs → ¬id x = true intro h b hb mpr bs:List Boolh:∀ (b : Bool), b ∈ bs → b = falseb:Boolhb:b ∈ bs⊢ ¬id b = true
rw [h b hb mpr bs:List Boolh:∀ (b : Bool), b ∈ bs → b = falseb:Boolhb:b ∈ bs⊢ ¬id false = true] mpr bs:List Boolh:∀ (b : Bool), b ∈ bs → b = falseb:Boolhb:b ∈ bs⊢ ¬id false = true
intro he mpr bs:List Boolh:∀ (b : Bool), b ∈ bs → b = falseb:Boolhb:b ∈ bshe:id false = true⊢ False
cases he 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 :: nextCount 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) 0Decrement never changes the allocated width.
theorem length_decrement (bs : List Bool) : (decrement bs).length = bs.length := by bs:List Bool⊢ (decrement bs).length = bs.length
apply List.rec (motive := fun bs ↦ (decrement bs).length = bs.length) ?_ ?_ bs 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 rfl All goals completed! 🐙
· bs:List Bool⊢ ∀ (head : Bool) (tail : List Bool),
(decrement tail).length = tail.length → (decrement (head :: tail)).length = (head :: tail).length intro b bs ih bs✝:List Boolb:Boolbs:List Boolih:(decrement bs).length = bs.length⊢ (decrement (b :: bs)).length = (b :: bs).length
cases b false bs✝:List Boolbs:List Boolih:(decrement bs).length = bs.length⊢ (decrement (false :: bs)).length = (false :: bs).lengthtrue bs✝:List Boolbs:List Boolih:(decrement bs).length = bs.length⊢ (decrement (true :: bs)).length = (true :: bs).length <;> false bs✝:List Boolbs:List Boolih:(decrement bs).length = bs.length⊢ (decrement (false :: bs)).length = (false :: bs).lengthtrue bs✝:List Boolbs:List Boolih:(decrement bs).length = bs.length⊢ (decrement (true :: bs)).length = (true :: bs).length simp_all [decrement] All goals completed! 🐙A borrow changes at most the allocated width.
theorem borrowFlips_le_length (bs : List Bool) : borrowFlips bs ≤ bs.length := by bs:List Bool⊢ borrowFlips bs ≤ bs.length
apply List.rec (motive := fun bs ↦ borrowFlips bs ≤ bs.length) ?_ ?_ bs bs:List Bool⊢ borrowFlips [] ≤ [].lengthbs:List Bool⊢ ∀ (head : Bool) (tail : List Bool), borrowFlips tail ≤ tail.length → borrowFlips (head :: tail) ≤ (head :: tail).length
· bs:List Bool⊢ borrowFlips [] ≤ [].length exact Nat.le_refl _ All goals completed! 🐙
· bs:List Bool⊢ ∀ (head : Bool) (tail : List Bool), borrowFlips tail ≤ tail.length → borrowFlips (head :: tail) ≤ (head :: tail).length intro b bs ih bs✝:List Boolb:Boolbs:List Boolih:borrowFlips bs ≤ bs.length⊢ borrowFlips (b :: bs) ≤ (b :: bs).length
cases b false bs✝:List Boolbs:List Boolih:borrowFlips bs ≤ bs.length⊢ borrowFlips (false :: bs) ≤ (false :: bs).lengthtrue bs✝:List Boolbs:List Boolih:borrowFlips bs ≤ bs.length⊢ borrowFlips (true :: bs) ≤ (true :: bs).length <;> false bs✝:List Boolbs:List Boolih:borrowFlips bs ≤ bs.length⊢ borrowFlips (false :: bs) ≤ (false :: bs).lengthtrue bs✝:List Boolbs:List Boolih:borrowFlips bs ≤ bs.length⊢ borrowFlips (true :: bs) ≤ (true :: bs).length simp_all [borrowFlips] 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 := by bs:List Boolh:0 < value bs⊢ value (decrement bs) = value bs - 1
revert h bs:List Bool⊢ 0 < value bs → value (decrement bs) = value bs - 1
apply List.rec (motive := fun bs ↦ 0 < value bs →
value (decrement bs) = value bs - 1) ?_ ?_ bs bs:List Bool⊢ 0 < 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 Bool⊢ 0 < value [] → value (decrement []) = value [] - 1 intro h bs:List Boolh:0 < value []⊢ value (decrement []) = value [] - 1
exact (Nat.not_lt_zero 0 h).elim 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 intro b bs ih h 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
cases b false 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) - 1true 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
· false 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 have hp : 0 < value bs := by bs:List Boolh:0 < value bs⊢ value (decrement bs) = value bs - 1
rw [value_cons bs✝:List Boolbs:List Boolih:0 < value bs → value (decrement bs) = value bs - 1h:0 < 2 * value bs + false.toNat⊢ 0 < value bs] at h bs✝:List Boolbs:List Boolih:0 < value bs → value (decrement bs) = value bs - 1h:0 < 2 * value bs + false.toNat⊢ 0 < value bs
simp only [Bool.toNat_false] at h bs✝:List Boolbs:List Boolih:0 < value bs → value (decrement bs) = value bs - 1h:0 < 2 * value bs + 0⊢ 0 < value bs
omega false bs✝:List Boolbs:List Boolih:0 < value bs → value (decrement bs) = value bs - 1h:0 < value (false :: bs)hp:0 < value bs⊢ value (decrement (false :: bs)) = value (false :: bs) - 1
change value (true :: decrement bs) = value (false :: bs) - 1 false bs✝:List Boolbs:List Boolih:0 < value bs → value (decrement bs) = value bs - 1h:0 < value (false :: bs)hp:0 < value bs⊢ value (true :: decrement bs) = value (false :: bs) - 1
rw [value_cons, false bs✝:List Boolbs:List Boolih:0 < value bs → value (decrement bs) = value bs - 1h:0 < value (false :: bs)hp:0 < value bs⊢ 2 * value (decrement bs) + true.toNat = value (false :: bs) - 1 value_cons, false bs✝:List Boolbs:List Boolih:0 < value bs → value (decrement bs) = value bs - 1h:0 < value (false :: bs)hp:0 < value bs⊢ 2 * value (decrement bs) + true.toNat = 2 * value bs + false.toNat - 1 ih hp false bs✝:List Boolbs:List Boolih:0 < value bs → value (decrement bs) = value bs - 1h:0 < value (false :: bs)hp:0 < value bs⊢ 2 * (value bs - 1) + true.toNat = 2 * value bs + false.toNat - 1] false bs✝:List Boolbs:List Boolih:0 < value bs → value (decrement bs) = value bs - 1h:0 < value (false :: bs)hp:0 < value bs⊢ 2 * (value bs - 1) + true.toNat = 2 * value bs + false.toNat - 1
simp only [Bool.toNat_true, Bool.toNat_false] false bs✝:List Boolbs:List Boolih:0 < value bs → value (decrement bs) = value bs - 1h:0 < value (false :: bs)hp:0 < value bs⊢ 2 * (value bs - 1) + 1 = 2 * value bs + 0 - 1
omega All goals completed! 🐙
· true 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 change value (false :: bs) = value (true :: bs) - 1 true 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
rw [value_cons, true bs✝:List Boolbs:List Boolih:0 < value bs → value (decrement bs) = value bs - 1h:0 < value (true :: bs)⊢ 2 * value bs + false.toNat = value (true :: bs) - 1 value_cons true 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] true 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
simp only [Bool.toNat_true, Bool.toNat_false] true 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
omega 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 := by bs:List Boolh:0 < value bs⊢ 0 < borrowFlips bs
cases bs with
| nil => nil h:0 < value []⊢ 0 < borrowFlips [] exact (Nat.not_lt_zero 0 h).elim All goals completed! 🐙
| cons b bs => cons b:Boolbs:List Boolh:0 < value (b :: bs)⊢ 0 < borrowFlips (b :: bs) cases b cons.false bs:List Boolh:0 < value (false :: bs)⊢ 0 < borrowFlips (false :: bs)cons.true bs:List Boolh:0 < value (true :: bs)⊢ 0 < borrowFlips (true :: bs) <;> cons.false bs:List Boolh:0 < value (false :: bs)⊢ 0 < borrowFlips (false :: bs)cons.true bs:List Boolh:0 < value (true :: bs)⊢ 0 < borrowFlips (true :: bs) simp [borrowFlips] 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 := by bs:List Booli:ℕh:i + 1 < borrowFlips bs⊢ bs[i]?.getD false = false
revert i bs:List Bool⊢ ∀ (i : ℕ), i + 1 < borrowFlips bs → bs[i]?.getD false = false
apply List.rec (motive := fun bs ↦ ∀ i, i + 1 < borrowFlips bs →
bs[i]?.getD false = false) ?_ ?_ bs 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 intro i _ bs:List Booli:ℕa✝:i + 1 < borrowFlips []⊢ [][i]?.getD false = false
rfl 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 intro b bs ih i hi 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
cases b 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 = falsetrue 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
· 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
| zero => false.zero 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 rfl All goals completed! 🐙
| succ i => false.succ 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
change bs[i]?.getD false = false false.succ 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
apply ih false.succ 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
change i + 1 + 1 < borrowFlips bs + 1 at hi false.succ bs✝:List Boolbs:List Boolih:∀ (i : ℕ), i + 1 < borrowFlips bs → bs[i]?.getD false = falsei:ℕhi:i + 1 + 1 < borrowFlips bs + 1⊢ i + 1 < borrowFlips bs
omega All goals completed! 🐙
· true 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 change i + 1 < 1 at hi true 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
omega 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 := by bs:List Boolh:0 < value bs⊢ bs[borrowFlips bs - 1]?.getD false = true
revert h bs:List Bool⊢ 0 < value bs → bs[borrowFlips bs - 1]?.getD false = true
apply List.rec (motive := fun bs ↦ 0 < value bs →
bs[borrowFlips bs - 1]?.getD false = true) ?_ ?_ bs bs:List Bool⊢ 0 < 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 Bool⊢ 0 < value [] → [][borrowFlips [] - 1]?.getD false = true intro h bs:List Boolh:0 < value []⊢ [][borrowFlips [] - 1]?.getD false = true
exact (Nat.not_lt_zero 0 h).elim 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 intro b bs ih h 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
cases b false 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 = truetrue 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
· false 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 have hp : 0 < value bs := by bs:List Boolh:0 < value bs⊢ bs[borrowFlips bs - 1]?.getD false = true
rw [value_cons bs✝:List Boolbs:List Boolih:0 < value bs → bs[borrowFlips bs - 1]?.getD false = trueh:0 < 2 * value bs + false.toNat⊢ 0 < value bs] at h bs✝:List Boolbs:List Boolih:0 < value bs → bs[borrowFlips bs - 1]?.getD false = trueh:0 < 2 * value bs + false.toNat⊢ 0 < value bs
simp only [Bool.toNat_false] at h bs✝:List Boolbs:List Boolih:0 < value bs → bs[borrowFlips bs - 1]?.getD false = trueh:0 < 2 * value bs + 0⊢ 0 < value bs
omega false 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
have hf := borrowFlips_pos bs hp false 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
have he : borrowFlips (false :: bs) - 1 = (borrowFlips bs - 1) + 1 := by bs:List Boolh:0 < value bs⊢ bs[borrowFlips bs - 1]?.getD false = true
change borrowFlips bs + 1 - 1 = borrowFlips bs - 1 + 1 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⊢ borrowFlips bs + 1 - 1 = borrowFlips bs - 1 + 1
omega false 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
simpa only [he, List.getElem?_cons_succ] using ih hp All goals completed! 🐙
· true 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 rfl 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 := by bs:List Booli:ℕ⊢ (decrement bs)[i]?.getD false = if i < borrowFlips bs then !bs[i]?.getD false else bs[i]?.getD false
revert i bs:List Bool⊢ ∀ (i : ℕ), (decrement bs)[i]?.getD false = if i < borrowFlips bs then !bs[i]?.getD false else bs[i]?.getD false
apply List.rec (motive := fun bs ↦ ∀ i,
(decrement bs)[i]?.getD false =
if i < borrowFlips bs then !bs[i]?.getD false else bs[i]?.getD false) ?_ ?_ bs 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 intro i bs:List Booli:ℕ⊢ (decrement [])[i]?.getD false = if i < borrowFlips [] then ![][i]?.getD false else [][i]?.getD false
change false = if i < 0 then true else false bs:List Booli:ℕ⊢ false = if i < 0 then true else false
simp only [show ¬i < 0 from by omega, ↓reduceIte] 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 intro b bs ih i 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
cases b 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 falsetrue 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
· 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
| zero => false.zero 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
change true = if 0 < borrowFlips bs + 1 then true else false false.zero 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⊢ true = if 0 < borrowFlips bs + 1 then true else false
simp only [show 0 < borrowFlips bs + 1 from by omega, ↓reduceIte] All goals completed! 🐙
| succ i => false.succ 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
change (decrement bs)[i]?.getD false =
if i + 1 < borrowFlips bs + 1 then !bs[i]?.getD false else bs[i]?.getD false false.succ 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
have he : (i + 1 < borrowFlips bs + 1) ↔ (i < borrowFlips bs) := by bs:List Booli:ℕ⊢ (decrement bs)[i]?.getD false = if i < borrowFlips bs then !bs[i]?.getD false else bs[i]?.getD false
constructor mp 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:ℕ⊢ i + 1 < borrowFlips bs + 1 → i < borrowFlips bsmpr 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:ℕ⊢ i < borrowFlips bs → i + 1 < borrowFlips bs + 1 <;> mp 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:ℕ⊢ i + 1 < borrowFlips bs + 1 → i < borrowFlips bsmpr 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:ℕ⊢ i < borrowFlips bs → i + 1 < borrowFlips bs + 1 intro h mpr 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:ℕh:i < borrowFlips bs⊢ i + 1 < borrowFlips bs + 1 <;> mp 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:ℕh:i + 1 < borrowFlips bs + 1⊢ i < borrowFlips bsmpr 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:ℕh:i < borrowFlips bs⊢ i + 1 < borrowFlips bs + 1 omega false.succ 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
simpa only [he] using ih i All goals completed! 🐙
· true 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
| zero => true.zero 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 rfl All goals completed! 🐙
| succ i => true.succ 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
change bs[i]?.getD false =
if i + 1 < 1 then !bs[i]?.getD false else bs[i]?.getD false true.succ 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
simp only [show ¬i + 1 < 1 from by omega, ↓reduceIte] 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 := by bs:List Bool⊢ borrowFlips bs + List.count false (decrement bs) ≤ List.count false bs + 2
apply List.rec (motive := fun bs ↦
borrowFlips bs + (decrement bs).count false ≤ bs.count false + 2) ?_ ?_ bs bs:List Bool⊢ borrowFlips [] + 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 Bool⊢ borrowFlips [] + List.count false (decrement []) ≤ List.count false [] + 2 decide 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 intro b bs ih bs✝:List Boolb:Boolbs:List Boolih:borrowFlips bs + List.count false (decrement bs) ≤ List.count false bs + 2⊢ borrowFlips (b :: bs) + List.count false (decrement (b :: bs)) ≤ List.count false (b :: bs) + 2
cases b false bs✝:List Boolbs:List Boolih:borrowFlips bs + List.count false (decrement bs) ≤ List.count false bs + 2⊢ borrowFlips (false :: bs) + List.count false (decrement (false :: bs)) ≤ List.count false (false :: bs) + 2true bs✝:List Boolbs:List Boolih:borrowFlips bs + List.count false (decrement bs) ≤ List.count false bs + 2⊢ borrowFlips (true :: bs) + List.count false (decrement (true :: bs)) ≤ List.count false (true :: bs) + 2 <;> false bs✝:List Boolbs:List Boolih:borrowFlips bs + List.count false (decrement bs) ≤ List.count false bs + 2⊢ borrowFlips (false :: bs) + List.count false (decrement (false :: bs)) ≤ List.count false (false :: bs) + 2true bs✝:List Boolbs:List Boolih:borrowFlips bs + List.count false (decrement bs) ≤ List.count false bs + 2⊢ borrowFlips (true :: bs) + List.count false (decrement (true :: bs)) ≤ List.count false (true :: bs) + 2 simp_all [decrement, borrowFlips] true 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 + 2⊢ 1 + (List.count false bs + 1) ≤ List.count false bs + 2 <;> false 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 + 2⊢ List.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 + 2true 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 + 2⊢ 1 + (List.count false bs + 1) ≤ List.count false bs + 2 omega All goals completed! 🐙end Geb.BitTree.Elias.Counter