Theorem: Bitvec.toNat_lt
File: Mathlib/Data/Bitvec/Lemmas.lean

tactic: suffices : v.toNat + 1 ≤ 2 ^ n
state_before: n : ℕ
v : Bitvec n
⊢ Bitvec.toNat v < 2 ^ n

tactic: simpa
state_before: n : ℕ
v : Bitvec n
this : Bitvec.toNat v + 1 ≤ 2 ^ n
⊢ Bitvec.toNat v < 2 ^ n

case this
n : ℕ
v : Bitvec n
⊢ Bitvec.toNat v + 1 ≤ 2 ^ n

tactic: rw [toNat_eq_foldr_reverse]
state_before: case this
n : ℕ
v : Bitvec n
⊢ Bitvec.toNat v + 1 ≤ 2 ^ n

tactic: cases' v with xs h
state_before: case this
n : ℕ
v : Bitvec n
⊢ List.foldr (flip addLsb) 0 (List.reverse (Vector.toList v)) + 1 ≤ 2 ^ n

tactic: dsimp [Bitvec.toNat, bitsToNat]
state_before: case this.mk
n : ℕ
xs : List Bool
h : List.length xs = n
⊢ List.foldr (flip addLsb) 0 (List.reverse (Vector.toList { val := xs, property := h })) + 1 ≤ 2 ^ n

tactic: rw [← List.length_reverse] at h
state_before: case this.mk
n : ℕ
xs : List Bool
h : List.length xs = n
⊢ List.foldr (flip addLsb) 0 (List.reverse xs) + 1 ≤ 2 ^ n

tactic: generalize xs.reverse = ys at h
state_before: case this.mk
n : ℕ
xs : List Bool
h : List.length (List.reverse xs) = n
⊢ List.foldr (flip addLsb) 0 (List.reverse xs) + 1 ≤ 2 ^ n

tactic: induction' ys with head tail ih generalizing n
state_before: case this.mk
n : ℕ
xs ys : List Bool
h : List.length ys = n
⊢ List.foldr (flip addLsb) 0 ys + 1 ≤ 2 ^ n

tactic: simp [← h]
state_before: case this.mk.nil
n✝ : ℕ
xs ys : List Bool
h✝ : List.length ys = n✝
n : ℕ
h : List.length [] = n
⊢ List.foldr (flip addLsb) 0 [] + 1 ≤ 2 ^ n

tactic: simp only [← h, pow_add, flip, List.length, List.foldr, pow_one]
state_before: case this.mk.cons
n✝ : ℕ
xs ys : List Bool
h✝ : List.length ys = n✝
head : Bool
tail : List Bool
ih : ∀ {n : ℕ}, List.length tail = n → List.foldr (flip addLsb) 0 tail + 1 ≤ 2 ^ n
n : ℕ
h : List.length (head :: tail) = n
⊢ List.foldr (flip addLsb) 0 (head :: tail) + 1 ≤ 2 ^ n

tactic: rw [addLsb_eq_twice_add_one]
state_before: case this.mk.cons
n✝ : ℕ
xs ys : List Bool
h✝ : List.length ys = n✝
head : Bool
tail : List Bool
ih : ∀ {n : ℕ}, List.length tail = n → List.foldr (flip addLsb) 0 tail + 1 ≤ 2 ^ n
n : ℕ
h : List.length (head :: tail) = n
⊢ addLsb (List.foldr (fun b a => addLsb a b) 0 tail) head + 1 ≤ 2 ^ List.length tail * 2

tactic: trans 2 * List.foldr (fun (x : Bool) (y : ℕ) => addLsb y x) 0 tail + 2 * 1
state_before: case this.mk.cons
n✝ : ℕ
xs ys : List Bool
h✝ : List.length ys = n✝
head : Bool
tail : List Bool
ih : ∀ {n : ℕ}, List.length tail = n → List.foldr (flip addLsb) 0 tail + 1 ≤ 2 ^ n
n : ℕ
h : List.length (head :: tail) = n
⊢ (2 * List.foldr (fun b a => addLsb a b) 0 tail + bif head then 1 else 0) + 1 ≤ 2 ^ List.length tail * 2

tactic: rw [add_assoc]
state_before: n✝ : ℕ
xs ys : List Bool
h✝ : List.length ys = n✝
head : Bool
tail : List Bool
ih : ∀ {n : ℕ}, List.length tail = n → List.foldr (flip addLsb) 0 tail + 1 ≤ 2 ^ n
n : ℕ
h : List.length (head :: tail) = n
⊢ (2 * List.foldr (fun b a => addLsb a b) 0 tail + bif head then 1 else 0) + 1 ≤
    2 * List.foldr (fun x y => addLsb y x) 0 tail + 2 * 1

tactic: apply Nat.add_le_add_left
state_before: n✝ : ℕ
xs ys : List Bool
h✝ : List.length ys = n✝
head : Bool
tail : List Bool
ih : ∀ {n : ℕ}, List.length tail = n → List.foldr (flip addLsb) 0 tail + 1 ≤ 2 ^ n
n : ℕ
h : List.length (head :: tail) = n
⊢ 2 * List.foldr (fun b a => addLsb a b) 0 tail + ((bif head then 1 else 0) + 1) ≤
    2 * List.foldr (fun x y => addLsb y x) 0 tail + 2 * 1

tactic: cases head <;> simp only
state_before: case h
n✝ : ℕ
xs ys : List Bool
h✝ : List.length ys = n✝
head : Bool
tail : List Bool
ih : ∀ {n : ℕ}, List.length tail = n → List.foldr (flip addLsb) 0 tail + 1 ≤ 2 ^ n
n : ℕ
h : List.length (head :: tail) = n
⊢ (bif head then 1 else 0) + 1 ≤ 2 * 1

tactic: rw [← left_distrib]
state_before: n✝ : ℕ
xs ys : List Bool
h✝ : List.length ys = n✝
head : Bool
tail : List Bool
ih : ∀ {n : ℕ}, List.length tail = n → List.foldr (flip addLsb) 0 tail + 1 ≤ 2 ^ n
n : ℕ
h : List.length (head :: tail) = n
⊢ 2 * List.foldr (fun x y => addLsb y x) 0 tail + 2 * 1 ≤ 2 ^ List.length tail * 2

tactic: rw [mul_comm _ 2]
state_before: n✝ : ℕ
xs ys : List Bool
h✝ : List.length ys = n✝
head : Bool
tail : List Bool
ih : ∀ {n : ℕ}, List.length tail = n → List.foldr (flip addLsb) 0 tail + 1 ≤ 2 ^ n
n : ℕ
h : List.length (head :: tail) = n
⊢ 2 * (List.foldr (fun x y => addLsb y x) 0 tail + 1) ≤ 2 ^ List.length tail * 2

tactic: apply Nat.mul_le_mul_left
state_before: n✝ : ℕ
xs ys : List Bool
h✝ : List.length ys = n✝
head : Bool
tail : List Bool
ih : ∀ {n : ℕ}, List.length tail = n → List.foldr (flip addLsb) 0 tail + 1 ≤ 2 ^ n
n : ℕ
h : List.length (head :: tail) = n
⊢ 2 * (List.foldr (fun x y => addLsb y x) 0 tail + 1) ≤ 2 * 2 ^ List.length tail

tactic: exact ih rfl
state_before: case h
n✝ : ℕ
xs ys : List Bool
h✝ : List.length ys = n✝
head : Bool
tail : List Bool
ih : ∀ {n : ℕ}, List.length tail = n → List.foldr (flip addLsb) 0 tail + 1 ≤ 2 ^ n
n : ℕ
h : List.length (head :: tail) = n
⊢ List.foldr (fun x y => addLsb y x) 0 tail + 1 ≤ 2 ^ List.length tail