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

tactic: cases' v with xs h
state_before: n : ℕ
v : Bitvec n
⊢ Bitvec.ofNat n (Bitvec.toNat v) = v

tactic: apply Subtype.ext
state_before: case mk
n : ℕ
xs : List Bool
h : List.length xs = n
⊢ Bitvec.ofNat n (Bitvec.toNat { val := xs, property := h }) = { val := xs, property := h }

tactic: change Vector.toList _ = xs
state_before: case mk.a
n : ℕ
xs : List Bool
h : List.length xs = n
⊢ ↑(Bitvec.ofNat n (Bitvec.toNat { val := xs, property := h })) = ↑{ val := xs, property := h }

tactic: dsimp [Bitvec.toNat, bitsToNat]
state_before: case mk.a
n : ℕ
xs : List Bool
h : List.length xs = n
⊢ Vector.toList (Bitvec.ofNat n (Bitvec.toNat { val := xs, property := h })) = xs

tactic: rw [← List.length_reverse] at h
state_before: case mk.a
n : ℕ
xs : List Bool
h : List.length xs = n
⊢ Vector.toList (Bitvec.ofNat n (List.foldl addLsb 0 xs)) = xs

tactic: rw [← List.reverse_reverse xs, List.foldl_reverse]
state_before: case mk.a
n : ℕ
xs : List Bool
h : List.length (List.reverse xs) = n
⊢ Vector.toList (Bitvec.ofNat n (List.foldl addLsb 0 xs)) = xs

tactic: generalize xs.reverse = ys at h⊢
state_before: case mk.a
n : ℕ
xs : List Bool
h : List.length (List.reverse xs) = n
⊢ Vector.toList (Bitvec.ofNat n (List.foldr (fun x y => addLsb y x) 0 (List.reverse xs))) =
    List.reverse (List.reverse xs)

tactic: clear xs
state_before: case mk.a
n : ℕ
xs ys : List Bool
h : List.length ys = n
⊢ Vector.toList (Bitvec.ofNat n (List.foldr (fun x y => addLsb y x) 0 ys)) = List.reverse ys

tactic: induction' ys with ys_head ys_tail ys_ih generalizing n
state_before: case mk.a
n : ℕ
ys : List Bool
h : List.length ys = n
⊢ Vector.toList (Bitvec.ofNat n (List.foldr (fun x y => addLsb y x) 0 ys)) = List.reverse ys

tactic: cases h
state_before: case mk.a.nil
n✝ : ℕ
ys : List Bool
h✝ : List.length ys = n✝
n : ℕ
h : List.length [] = n
⊢ Vector.toList (Bitvec.ofNat n (List.foldr (fun x y => addLsb y x) 0 [])) = List.reverse []

tactic: simp [Bitvec.ofNat]
state_before: case mk.a.nil.refl
n : ℕ
ys : List Bool
h : List.length ys = n
⊢ Vector.toList (Bitvec.ofNat (List.length []) (List.foldr (fun x y => addLsb y x) 0 [])) = List.reverse []

tactic: simp only [← Nat.succ_eq_add_one, List.length] at h
state_before: case mk.a.cons
n✝ : ℕ
ys : List Bool
h✝ : List.length ys = n✝
ys_head : Bool
ys_tail : List Bool
ys_ih :
  ∀ {n : ℕ},
    List.length ys_tail = n →
      Vector.toList (Bitvec.ofNat n (List.foldr (fun x y => addLsb y x) 0 ys_tail)) = List.reverse ys_tail
n : ℕ
h : List.length (ys_head :: ys_tail) = n
⊢ Vector.toList (Bitvec.ofNat n (List.foldr (fun x y => addLsb y x) 0 (ys_head :: ys_tail))) =
    List.reverse (ys_head :: ys_tail)

tactic: subst n
state_before: case mk.a.cons
n✝ : ℕ
ys : List Bool
h✝ : List.length ys = n✝
ys_head : Bool
ys_tail : List Bool
ys_ih :
  ∀ {n : ℕ},
    List.length ys_tail = n →
      Vector.toList (Bitvec.ofNat n (List.foldr (fun x y => addLsb y x) 0 ys_tail)) = List.reverse ys_tail
n : ℕ
h : succ (List.length ys_tail) = n
⊢ Vector.toList (Bitvec.ofNat n (List.foldr (fun x y => addLsb y x) 0 (ys_head :: ys_tail))) =
    List.reverse (ys_head :: ys_tail)

tactic: simp only [Bitvec.ofNat, Vector.toList_cons, Vector.toList_nil, List.reverse_cons,
  Vector.toList_append, List.foldr]
state_before: case mk.a.cons
n : ℕ
ys : List Bool
h : List.length ys = n
ys_head : Bool
ys_tail : List Bool
ys_ih :
  ∀ {n : ℕ},
    List.length ys_tail = n →
      Vector.toList (Bitvec.ofNat n (List.foldr (fun x y => addLsb y x) 0 ys_tail)) = List.reverse ys_tail
⊢ Vector.toList
      (Bitvec.ofNat (succ (List.length ys_tail)) (List.foldr (fun x y => addLsb y x) 0 (ys_head :: ys_tail))) =
    List.reverse (ys_head :: ys_tail)

tactic: erw [addLsb_div_two, decide_addLsb_mod_two]
state_before: case mk.a.cons
n : ℕ
ys : List Bool
h : List.length ys = n
ys_head : Bool
ys_tail : List Bool
ys_ih :
  ∀ {n : ℕ},
    List.length ys_tail = n →
      Vector.toList (Bitvec.ofNat n (List.foldr (fun x y => addLsb y x) 0 ys_tail)) = List.reverse ys_tail
⊢ Vector.toList
        (Bitvec.ofNat (List.length ys_tail) (addLsb (List.foldr (fun x y => addLsb y x) 0 ys_tail) ys_head / 2)) ++
      [decide (addLsb (List.foldr (fun x y => addLsb y x) 0 ys_tail) ys_head % 2 = 1)] =
    List.reverse ys_tail ++ [ys_head]

tactic: congr
state_before: case mk.a.cons
n : ℕ
ys : List Bool
h : List.length ys = n
ys_head : Bool
ys_tail : List Bool
ys_ih :
  ∀ {n : ℕ},
    List.length ys_tail = n →
      Vector.toList (Bitvec.ofNat n (List.foldr (fun x y => addLsb y x) 0 ys_tail)) = List.reverse ys_tail
⊢ Vector.toList (Bitvec.ofNat (List.length ys_tail) (List.foldr (fun x y => addLsb y x) 0 ys_tail)) ++ [ys_head] =
    List.reverse ys_tail ++ [ys_head]

tactic: apply ys_ih
state_before: case mk.a.cons.e_a
n : ℕ
ys : List Bool
h : List.length ys = n
ys_head : Bool
ys_tail : List Bool
ys_ih :
  ∀ {n : ℕ},
    List.length ys_tail = n →
      Vector.toList (Bitvec.ofNat n (List.foldr (fun x y => addLsb y x) 0 ys_tail)) = List.reverse ys_tail
⊢ Vector.toList (Bitvec.ofNat (List.length ys_tail) (List.foldr (fun x y => addLsb y x) 0 ys_tail)) =
    List.reverse ys_tail

tactic: rfl
state_before: case mk.a.cons.e_a.h
n : ℕ
ys : List Bool
h : List.length ys = n
ys_head : Bool
ys_tail : List Bool
ys_ih :
  ∀ {n : ℕ},
    List.length ys_tail = n →
      Vector.toList (Bitvec.ofNat n (List.foldr (fun x y => addLsb y x) 0 ys_tail)) = List.reverse ys_tail
⊢ List.length ys_tail = List.length ys_tail