l3lab/ntp-mathlib huggingface dataset:
theorem sub_one_mul_sum_div_pow_eq_sub_sum_digits
    (L : List ℕ) {h_nonempty} (h_ne_zero : L.getLast h_nonempty ≠ 0) (h_lt : ∀ l ∈ L, l < p) :
    (p - 1) * ∑ i in range L.length, (ofDigits p L) / p ^ i.succ = (ofDigits p L) - L.sum := by
  obtain h | rfl | h : 1 < p ∨ 1 = p ∨ p < 1 := trichotomous 1 p
  · induction' L with hd tl ih
    · simp [ofDigits]
    · simp only [List.length_cons, List.sum_cons, self_div_pow_eq_ofDigits_drop _ _ h,
          digits_ofDigits p h (hd :: tl) h_lt (fun _ => h_ne_zero)]
      simp only [ofDigits]
      rw [sum_range_succ, Nat.cast_id]
      simp only [List.drop, List.drop_length]
      obtain rfl | h' := em <| tl = []
      · simp [ofDigits]
      · have w₁' := fun l hl ↦ h_lt l <| List.mem_cons_of_mem hd hl
        have w₂' := fun (h : tl ≠ []) ↦ (List.getLast_cons h) ▸ h_ne_zero
        have ih := ih (w₂' h') w₁'
        simp only [self_div_pow_eq_ofDigits_drop _ _ h, digits_ofDigits p h tl w₁' w₂',
          ← Nat.one_add] at ih
        have := sum_singleton (fun x ↦ ofDigits p <| tl.drop x) tl.length
        rw [← Ico_succ_singleton, List.drop_length, ofDigits] at this
        have h₁ : 1 ≤ tl.length :=  List.length_pos.mpr h'
        rw [← sum_range_add_sum_Ico _ <| h₁, ← add_zero (∑ x in Ico _ _, ofDigits p (tl.drop x)),
            ← this, sum_Ico_consecutive _  h₁ <| le_succ tl.length, ← sum_Ico_add _ 0 tl.length 1,
            Ico_zero_eq_range, mul_add, mul_add, ih, range_one, sum_singleton, List.drop, ofDigits,
            mul_zero, add_zero, ← Nat.add_sub_assoc <| sum_le_ofDigits _ <| Nat.le_of_lt h]
        nth_rw 2 [← one_mul <| ofDigits p tl]
        rw [← add_mul, one_eq_succ_zero, Nat.sub_add_cancel <| zero_lt_of_lt h,
           Nat.add_sub_add_left]
  · simp [ofDigits_one]
  · 

Proof state:
case inr.inr
n p : ℕ
L : List ℕ
h_nonempty : L ≠ []
h_ne_zero : List.getLast L h_nonempty ≠ 0
h_lt : ∀ l ∈ L, l < p
h : p < 1
⊢ (p - 1) * ∑ i in range (List.length L), ofDigits p L / p ^ succ i = ofDigits p L - List.sum L

Next tactic:
simp [lt_one_iff.mp h]
theorem sub_one_mul_sum_div_pow_eq_sub_sum_digits
    (L : List ℕ) {h_nonempty} (h_ne_zero : L.getLast h_nonempty ≠ 0) (h_lt : ∀ l ∈ L, l < p) :
    (p - 1) * ∑ i in range L.length, (ofDigits p L) / p ^ i.succ = (ofDigits p L) - L.sum := by
  obtain h | rfl | h : 1 < p ∨ 1 = p ∨ p < 1 := trichotomous 1 p
  · induction' L with hd tl ih
    · simp [ofDigits]
    · simp only [List.length_cons, List.sum_cons, self_div_pow_eq_ofDigits_drop _ _ h,
          digits_ofDigits p h (hd :: tl) h_lt (fun _ => h_ne_zero)]
      simp only [ofDigits]
      rw [sum_range_succ, Nat.cast_id]
      simp only [List.drop, List.drop_length]
      obtain rfl | h' := em <| tl = []
      · simp [ofDigits]
      · have w₁' := fun l hl ↦ h_lt l <| List.mem_cons_of_mem hd hl
        have w₂' := fun (h : tl ≠ []) ↦ (List.getLast_cons h) ▸ h_ne_zero
        have ih := ih (w₂' h') w₁'
        simp only [self_div_pow_eq_ofDigits_drop _ _ h, digits_ofDigits p h tl w₁' w₂',
          ← Nat.one_add] at ih
        have := sum_singleton (fun x ↦ ofDigits p <| tl.drop x) tl.length
        rw [← Ico_succ_singleton, List.drop_length, ofDigits] at this
        have h₁ : 1 ≤ tl.length :=  List.length_pos.mpr h'
        rw [← sum_range_add_sum_Ico _ <| h₁, ← add_zero (∑ x in Ico _ _, ofDigits p (tl.drop x)),
            ← this, sum_Ico_consecutive _  h₁ <| le_succ tl.length, ← sum_Ico_add _ 0 tl.length 1,
            Ico_zero_eq_range, mul_add, mul_add, ih, range_one, sum_singleton, List.drop, ofDigits,
            mul_zero, add_zero, ← Nat.add_sub_assoc <| sum_le_ofDigits _ <| Nat.le_of_lt h]
        nth_rw 2 [← one_mul <| ofDigits p tl]
        rw [← add_mul, one_eq_succ_zero, Nat.sub_add_cancel <| zero_lt_of_lt h,
           Nat.add_sub_add_left]
  · simp [ofDigits_one]
  · simp [lt_one_iff.mp h]
    

Proof state:
case inr.inr
n p : ℕ
L : List ℕ
h_nonempty : L ≠ []
h_ne_zero : List.getLast L h_nonempty ≠ 0
h_lt : ∀ l ∈ L, l < p
h : p < 1
⊢ 0 = ofDigits 0 L - List.sum L

Next tactic:
cases L
theorem sub_one_mul_sum_div_pow_eq_sub_sum_digits
    (L : List ℕ) {h_nonempty} (h_ne_zero : L.getLast h_nonempty ≠ 0) (h_lt : ∀ l ∈ L, l < p) :
    (p - 1) * ∑ i in range L.length, (ofDigits p L) / p ^ i.succ = (ofDigits p L) - L.sum := by
  obtain h | rfl | h : 1 < p ∨ 1 = p ∨ p < 1 := trichotomous 1 p
  · induction' L with hd tl ih
    · simp [ofDigits]
    · simp only [List.length_cons, List.sum_cons, self_div_pow_eq_ofDigits_drop _ _ h,
          digits_ofDigits p h (hd :: tl) h_lt (fun _ => h_ne_zero)]
      simp only [ofDigits]
      rw [sum_range_succ, Nat.cast_id]
      simp only [List.drop, List.drop_length]
      obtain rfl | h' := em <| tl = []
      · simp [ofDigits]
      · have w₁' := fun l hl ↦ h_lt l <| List.mem_cons_of_mem hd hl
        have w₂' := fun (h : tl ≠ []) ↦ (List.getLast_cons h) ▸ h_ne_zero
        have ih := ih (w₂' h') w₁'
        simp only [self_div_pow_eq_ofDigits_drop _ _ h, digits_ofDigits p h tl w₁' w₂',
          ← Nat.one_add] at ih
        have := sum_singleton (fun x ↦ ofDigits p <| tl.drop x) tl.length
        rw [← Ico_succ_singleton, List.drop_length, ofDigits] at this
        have h₁ : 1 ≤ tl.length :=  List.length_pos.mpr h'
        rw [← sum_range_add_sum_Ico _ <| h₁, ← add_zero (∑ x in Ico _ _, ofDigits p (tl.drop x)),
            ← this, sum_Ico_consecutive _  h₁ <| le_succ tl.length, ← sum_Ico_add _ 0 tl.length 1,
            Ico_zero_eq_range, mul_add, mul_add, ih, range_one, sum_singleton, List.drop, ofDigits,
            mul_zero, add_zero, ← Nat.add_sub_assoc <| sum_le_ofDigits _ <| Nat.le_of_lt h]
        nth_rw 2 [← one_mul <| ofDigits p tl]
        rw [← add_mul, one_eq_succ_zero, Nat.sub_add_cancel <| zero_lt_of_lt h,
           Nat.add_sub_add_left]
  · simp [ofDigits_one]
  · simp [lt_one_iff.mp h]
    cases L
    · 

Proof state:
case inr.inr.nil
n p : ℕ
h : p < 1
h_nonempty : [] ≠ []
h_ne_zero : List.getLast [] h_nonempty ≠ 0
h_lt : ∀ l ∈ [], l < p
⊢ 0 = ofDigits 0 [] - List.sum []

Next tactic:
rfl
theorem sub_one_mul_sum_div_pow_eq_sub_sum_digits
    (L : List ℕ) {h_nonempty} (h_ne_zero : L.getLast h_nonempty ≠ 0) (h_lt : ∀ l ∈ L, l < p) :
    (p - 1) * ∑ i in range L.length, (ofDigits p L) / p ^ i.succ = (ofDigits p L) - L.sum := by
  obtain h | rfl | h : 1 < p ∨ 1 = p ∨ p < 1 := trichotomous 1 p
  · induction' L with hd tl ih
    · simp [ofDigits]
    · simp only [List.length_cons, List.sum_cons, self_div_pow_eq_ofDigits_drop _ _ h,
          digits_ofDigits p h (hd :: tl) h_lt (fun _ => h_ne_zero)]
      simp only [ofDigits]
      rw [sum_range_succ, Nat.cast_id]
      simp only [List.drop, List.drop_length]
      obtain rfl | h' := em <| tl = []
      · simp [ofDigits]
      · have w₁' := fun l hl ↦ h_lt l <| List.mem_cons_of_mem hd hl
        have w₂' := fun (h : tl ≠ []) ↦ (List.getLast_cons h) ▸ h_ne_zero
        have ih := ih (w₂' h') w₁'
        simp only [self_div_pow_eq_ofDigits_drop _ _ h, digits_ofDigits p h tl w₁' w₂',
          ← Nat.one_add] at ih
        have := sum_singleton (fun x ↦ ofDigits p <| tl.drop x) tl.length
        rw [← Ico_succ_singleton, List.drop_length, ofDigits] at this
        have h₁ : 1 ≤ tl.length :=  List.length_pos.mpr h'
        rw [← sum_range_add_sum_Ico _ <| h₁, ← add_zero (∑ x in Ico _ _, ofDigits p (tl.drop x)),
            ← this, sum_Ico_consecutive _  h₁ <| le_succ tl.length, ← sum_Ico_add _ 0 tl.length 1,
            Ico_zero_eq_range, mul_add, mul_add, ih, range_one, sum_singleton, List.drop, ofDigits,
            mul_zero, add_zero, ← Nat.add_sub_assoc <| sum_le_ofDigits _ <| Nat.le_of_lt h]
        nth_rw 2 [← one_mul <| ofDigits p tl]
        rw [← add_mul, one_eq_succ_zero, Nat.sub_add_cancel <| zero_lt_of_lt h,
           Nat.add_sub_add_left]
  · simp [ofDigits_one]
  · simp [lt_one_iff.mp h]
    cases L
    · rfl
    · 

Proof state:
case inr.inr.cons
n p : ℕ
h : p < 1
head✝ : ℕ
tail✝ : List ℕ
h_nonempty : head✝ :: tail✝ ≠ []
h_ne_zero : List.getLast (head✝ :: tail✝) h_nonempty ≠ 0
h_lt : ∀ l ∈ head✝ :: tail✝, l < p
⊢ 0 = ofDigits 0 (head✝ :: tail✝) - List.sum (head✝ :: tail✝)

Next tactic:
simp [ofDigits]
theorem sub_one_mul_sum_log_div_pow_eq_sub_sum_digits (n : ℕ) :
    (p - 1) * ∑ i in range (log p n).succ, n / p ^ i.succ = n - (p.digits n).sum := by
  

Proof state:
n✝ p n : ℕ
⊢ (p - 1) * ∑ i in range (succ (log p n)), n / p ^ succ i = n - List.sum (digits p n)

Next tactic:
obtain h | rfl | h : 1 < p ∨ 1 = p ∨ p < 1 := trichotomous 1 p
theorem sub_one_mul_sum_log_div_pow_eq_sub_sum_digits (n : ℕ) :
    (p - 1) * ∑ i in range (log p n).succ, n / p ^ i.succ = n - (p.digits n).sum := by
  obtain h | rfl | h : 1 < p ∨ 1 = p ∨ p < 1 := trichotomous 1 p
  · 

Proof state:
case inl
n✝ p n : ℕ
h : 1 < p
⊢ (p - 1) * ∑ i in range (succ (log p n)), n / p ^ succ i = n - List.sum (digits p n)

Next tactic:
rcases eq_or_ne n 0 with rfl | hn
theorem sub_one_mul_sum_log_div_pow_eq_sub_sum_digits (n : ℕ) :
    (p - 1) * ∑ i in range (log p n).succ, n / p ^ i.succ = n - (p.digits n).sum := by
  obtain h | rfl | h : 1 < p ∨ 1 = p ∨ p < 1 := trichotomous 1 p
  · rcases eq_or_ne n 0 with rfl | hn
    · 

Proof state:
case inl.inl
n p : ℕ
h : 1 < p
⊢ (p - 1) * ∑ i in range (succ (log p 0)), 0 / p ^ succ i = 0 - List.sum (digits p 0)

Next tactic:
simp
theorem sub_one_mul_sum_log_div_pow_eq_sub_sum_digits (n : ℕ) :
    (p - 1) * ∑ i in range (log p n).succ, n / p ^ i.succ = n - (p.digits n).sum := by
  obtain h | rfl | h : 1 < p ∨ 1 = p ∨ p < 1 := trichotomous 1 p
  · rcases eq_or_ne n 0 with rfl | hn
    · simp
    · 

Proof state:
case inl.inr
n✝ p n : ℕ
h : 1 < p
hn : n ≠ 0
⊢ (p - 1) * ∑ i in range (succ (log p n)), n / p ^ succ i = n - List.sum (digits p n)

Next tactic:
convert sub_one_mul_sum_div_pow_eq_sub_sum_digits (p.digits n) (getLast_digit_ne_zero p hn) <|
          (fun l a ↦ digits_lt_base h a)
theorem sub_one_mul_sum_log_div_pow_eq_sub_sum_digits (n : ℕ) :
    (p - 1) * ∑ i in range (log p n).succ, n / p ^ i.succ = n - (p.digits n).sum := by
  obtain h | rfl | h : 1 < p ∨ 1 = p ∨ p < 1 := trichotomous 1 p
  · rcases eq_or_ne n 0 with rfl | hn
    · simp
    · convert sub_one_mul_sum_div_pow_eq_sub_sum_digits (p.digits n) (getLast_digit_ne_zero p hn) <|
          (fun l a ↦ digits_lt_base h a)
      · 

Proof state:
case h.e'_2.h.e'_6.h.h.e'_1
n✝ p n : ℕ
h : 1 < p
hn : n ≠ 0
⊢ succ (log p n) = List.length (digits p n)

Next tactic:
refine' (digits_len p n h hn).symm
theorem sub_one_mul_sum_log_div_pow_eq_sub_sum_digits (n : ℕ) :
    (p - 1) * ∑ i in range (log p n).succ, n / p ^ i.succ = n - (p.digits n).sum := by
  obtain h | rfl | h : 1 < p ∨ 1 = p ∨ p < 1 := trichotomous 1 p
  · rcases eq_or_ne n 0 with rfl | hn
    · simp
    · convert sub_one_mul_sum_div_pow_eq_sub_sum_digits (p.digits n) (getLast_digit_ne_zero p hn) <|
          (fun l a ↦ digits_lt_base h a)
      · refine' (digits_len p n h hn).symm
      

Proof state:
case h.e'_2.h.e'_6.a.h.e'_5
n✝ p n : ℕ
h : 1 < p
hn : n ≠ 0
x✝ : ℕ
a✝ : x✝ ∈ range (List.length (digits p n))
⊢ n = ofDigits p (digits p n)
case h.e'_3.h.e'_5 n✝ p n : ℕ h : 1 < p hn : n ≠ 0 ⊢ n = ofDigits p (digits p n)

Next tactic:
all_goals exact (ofDigits_digits p n).symm
theorem sub_one_mul_sum_log_div_pow_eq_sub_sum_digits (n : ℕ) :
    (p - 1) * ∑ i in range (log p n).succ, n / p ^ i.succ = n - (p.digits n).sum := by
  obtain h | rfl | h : 1 < p ∨ 1 = p ∨ p < 1 := trichotomous 1 p
  · rcases eq_or_ne n 0 with rfl | hn
    · simp
    · convert sub_one_mul_sum_div_pow_eq_sub_sum_digits (p.digits n) (getLast_digit_ne_zero p hn) <|
          (fun l a ↦ digits_lt_base h a)
      · refine' (digits_len p n h hn).symm
      all_goals 

Proof state:
case h.e'_2.h.e'_6.a.h.e'_5
n✝ p n : ℕ
h : 1 < p
hn : n ≠ 0
x✝ : ℕ
a✝ : x✝ ∈ range (List.length (digits p n))
⊢ n = ofDigits p (digits p n)

Next tactic:
exact (ofDigits_digits p n).symm
theorem sub_one_mul_sum_log_div_pow_eq_sub_sum_digits (n : ℕ) :
    (p - 1) * ∑ i in range (log p n).succ, n / p ^ i.succ = n - (p.digits n).sum := by
  obtain h | rfl | h : 1 < p ∨ 1 = p ∨ p < 1 := trichotomous 1 p
  · rcases eq_or_ne n 0 with rfl | hn
    · simp
    · convert sub_one_mul_sum_div_pow_eq_sub_sum_digits (p.digits n) (getLast_digit_ne_zero p hn) <|
          (fun l a ↦ digits_lt_base h a)
      · refine' (digits_len p n h hn).symm
      all_goals 

Proof state:
case h.e'_3.h.e'_5
n✝ p n : ℕ
h : 1 < p
hn : n ≠ 0
⊢ n = ofDigits p (digits p n)

Next tactic:
exact (ofDigits_digits p n).symm
theorem sub_one_mul_sum_log_div_pow_eq_sub_sum_digits (n : ℕ) :
    (p - 1) * ∑ i in range (log p n).succ, n / p ^ i.succ = n - (p.digits n).sum := by
  obtain h | rfl | h : 1 < p ∨ 1 = p ∨ p < 1 := trichotomous 1 p
  · rcases eq_or_ne n 0 with rfl | hn
    · simp
    · convert sub_one_mul_sum_div_pow_eq_sub_sum_digits (p.digits n) (getLast_digit_ne_zero p hn) <|
          (fun l a ↦ digits_lt_base h a)
      · refine' (digits_len p n h hn).symm
      all_goals exact (ofDigits_digits p n).symm
  · 

Proof state:
case inr.inl
n✝ n : ℕ
⊢ (1 - 1) * ∑ i in range (succ (log 1 n)), n / 1 ^ succ i = n - List.sum (digits 1 n)

Next tactic:
simp
theorem sub_one_mul_sum_log_div_pow_eq_sub_sum_digits (n : ℕ) :
    (p - 1) * ∑ i in range (log p n).succ, n / p ^ i.succ = n - (p.digits n).sum := by
  obtain h | rfl | h : 1 < p ∨ 1 = p ∨ p < 1 := trichotomous 1 p
  · rcases eq_or_ne n 0 with rfl | hn
    · simp
    · convert sub_one_mul_sum_div_pow_eq_sub_sum_digits (p.digits n) (getLast_digit_ne_zero p hn) <|
          (fun l a ↦ digits_lt_base h a)
      · refine' (digits_len p n h hn).symm
      all_goals exact (ofDigits_digits p n).symm
  · simp
  · 

Proof state:
case inr.inr
n✝ p n : ℕ
h : p < 1
⊢ (p - 1) * ∑ i in range (succ (log p n)), n / p ^ succ i = n - List.sum (digits p n)

Next tactic:
simp [lt_one_iff.mp h]
theorem sub_one_mul_sum_log_div_pow_eq_sub_sum_digits (n : ℕ) :
    (p - 1) * ∑ i in range (log p n).succ, n / p ^ i.succ = n - (p.digits n).sum := by
  obtain h | rfl | h : 1 < p ∨ 1 = p ∨ p < 1 := trichotomous 1 p
  · rcases eq_or_ne n 0 with rfl | hn
    · simp
    · convert sub_one_mul_sum_div_pow_eq_sub_sum_digits (p.digits n) (getLast_digit_ne_zero p hn) <|
          (fun l a ↦ digits_lt_base h a)
      · refine' (digits_len p n h hn).symm
      all_goals exact (ofDigits_digits p n).symm
  · simp
  · simp [lt_one_iff.mp h]
    

Proof state:
case inr.inr
n✝ p n : ℕ
h : p < 1
⊢ 0 = n - List.sum (digits 0 n)

Next tactic:
cases n
theorem sub_one_mul_sum_log_div_pow_eq_sub_sum_digits (n : ℕ) :
    (p - 1) * ∑ i in range (log p n).succ, n / p ^ i.succ = n - (p.digits n).sum := by
  obtain h | rfl | h : 1 < p ∨ 1 = p ∨ p < 1 := trichotomous 1 p
  · rcases eq_or_ne n 0 with rfl | hn
    · simp
    · convert sub_one_mul_sum_div_pow_eq_sub_sum_digits (p.digits n) (getLast_digit_ne_zero p hn) <|
          (fun l a ↦ digits_lt_base h a)
      · refine' (digits_len p n h hn).symm
      all_goals exact (ofDigits_digits p n).symm
  · simp
  · simp [lt_one_iff.mp h]
    cases n
    

Proof state:
case inr.inr.zero
n p : ℕ
h : p < 1
⊢ 0 = zero - List.sum (digits 0 zero)
case inr.inr.succ n p : ℕ h : p < 1 n✝ : ℕ ⊢ 0 = succ n✝ - List.sum (digits 0 (succ n✝))

Next tactic:
all_goals simp
theorem sub_one_mul_sum_log_div_pow_eq_sub_sum_digits (n : ℕ) :
    (p - 1) * ∑ i in range (log p n).succ, n / p ^ i.succ = n - (p.digits n).sum := by
  obtain h | rfl | h : 1 < p ∨ 1 = p ∨ p < 1 := trichotomous 1 p
  · rcases eq_or_ne n 0 with rfl | hn
    · simp
    · convert sub_one_mul_sum_div_pow_eq_sub_sum_digits (p.digits n) (getLast_digit_ne_zero p hn) <|
          (fun l a ↦ digits_lt_base h a)
      · refine' (digits_len p n h hn).symm
      all_goals exact (ofDigits_digits p n).symm
  · simp
  · simp [lt_one_iff.mp h]
    cases n
    all_goals 

Proof state:
case inr.inr.zero
n p : ℕ
h : p < 1
⊢ 0 = zero - List.sum (digits 0 zero)

Next tactic:
simp
theorem sub_one_mul_sum_log_div_pow_eq_sub_sum_digits (n : ℕ) :
    (p - 1) * ∑ i in range (log p n).succ, n / p ^ i.succ = n - (p.digits n).sum := by
  obtain h | rfl | h : 1 < p ∨ 1 = p ∨ p < 1 := trichotomous 1 p
  · rcases eq_or_ne n 0 with rfl | hn
    · simp
    · convert sub_one_mul_sum_div_pow_eq_sub_sum_digits (p.digits n) (getLast_digit_ne_zero p hn) <|
          (fun l a ↦ digits_lt_base h a)
      · refine' (digits_len p n h hn).symm
      all_goals exact (ofDigits_digits p n).symm
  · simp
  · simp [lt_one_iff.mp h]
    cases n
    all_goals 

Proof state:
case inr.inr.succ
n p : ℕ
h : p < 1
n✝ : ℕ
⊢ 0 = succ n✝ - List.sum (digits 0 (succ n✝))

Next tactic:
simp
theorem digits_two_eq_bits (n : ℕ) : digits 2 n = n.bits.map fun b => cond b 1 0 := by
  

Proof state:
n✝ n : ℕ
⊢ digits 2 n = List.map (fun b => bif b then 1 else 0) (bits n)

Next tactic:
induction' n using Nat.binaryRecFromOne with b n h ih
theorem digits_two_eq_bits (n : ℕ) : digits 2 n = n.bits.map fun b => cond b 1 0 := by
  induction' n using Nat.binaryRecFromOne with b n h ih
  · 

Proof state:
case z₀
n : ℕ
⊢ digits 2 0 = List.map (fun b => bif b then 1 else 0) (bits 0)

Next tactic:
simp
theorem digits_two_eq_bits (n : ℕ) : digits 2 n = n.bits.map fun b => cond b 1 0 := by
  induction' n using Nat.binaryRecFromOne with b n h ih
  · simp
  · 

Proof state:
case z₁
n : ℕ
⊢ digits 2 1 = List.map (fun b => bif b then 1 else 0) (bits 1)

Next tactic:
rfl
theorem digits_two_eq_bits (n : ℕ) : digits 2 n = n.bits.map fun b => cond b 1 0 := by
  induction' n using Nat.binaryRecFromOne with b n h ih
  · simp
  · rfl
  

Proof state:
case f
n✝ : ℕ
b : Bool
n : ℕ
h : n ≠ 0
ih : digits 2 n = List.map (fun b => bif b then 1 else 0) (bits n)
⊢ digits 2 (bit b n) = List.map (fun b => bif b then 1 else 0) (bits (bit b n))

Next tactic:
rw [bits_append_bit _ _ fun hn => absurd hn h]
theorem digits_two_eq_bits (n : ℕ) : digits 2 n = n.bits.map fun b => cond b 1 0 := by
  induction' n using Nat.binaryRecFromOne with b n h ih
  · simp
  · rfl
  rw [bits_append_bit _ _ fun hn => absurd hn h]
  

Proof state:
case f
n✝ : ℕ
b : Bool
n : ℕ
h : n ≠ 0
ih : digits 2 n = List.map (fun b => bif b then 1 else 0) (bits n)
⊢ digits 2 (bit b n) = List.map (fun b => bif b then 1 else 0) (b :: bits n)

Next tactic:
cases b
theorem digits_two_eq_bits (n : ℕ) : digits 2 n = n.bits.map fun b => cond b 1 0 := by
  induction' n using Nat.binaryRecFromOne with b n h ih
  · simp
  · rfl
  rw [bits_append_bit _ _ fun hn => absurd hn h]
  cases b
  · 

Proof state:
case f.false
n✝ n : ℕ
h : n ≠ 0
ih : digits 2 n = List.map (fun b => bif b then 1 else 0) (bits n)
⊢ digits 2 (bit false n) = List.map (fun b => bif b then 1 else 0) (false :: bits n)

Next tactic:
rw [digits_def' one_lt_two]
theorem digits_two_eq_bits (n : ℕ) : digits 2 n = n.bits.map fun b => cond b 1 0 := by
  induction' n using Nat.binaryRecFromOne with b n h ih
  · simp
  · rfl
  rw [bits_append_bit _ _ fun hn => absurd hn h]
  cases b
  · rw [digits_def' one_lt_two]
    · 

Proof state:
case f.false
n✝ n : ℕ
h : n ≠ 0
ih : digits 2 n = List.map (fun b => bif b then 1 else 0) (bits n)
⊢ bit false n % 2 :: digits 2 (bit false n / 2) = List.map (fun b => bif b then 1 else 0) (false :: bits n)

Next tactic:
simpa [Nat.bit, Nat.bit0_val n]
theorem digits_two_eq_bits (n : ℕ) : digits 2 n = n.bits.map fun b => cond b 1 0 := by
  induction' n using Nat.binaryRecFromOne with b n h ih
  · simp
  · rfl
  rw [bits_append_bit _ _ fun hn => absurd hn h]
  cases b
  · rw [digits_def' one_lt_two]
    · simpa [Nat.bit, Nat.bit0_val n]
    · 

Proof state:
case f.false
n✝ n : ℕ
h : n ≠ 0
ih : digits 2 n = List.map (fun b => bif b then 1 else 0) (bits n)
⊢ 0 < bit false n

Next tactic:
simpa [pos_iff_ne_zero, bit_eq_zero_iff]
theorem digits_two_eq_bits (n : ℕ) : digits 2 n = n.bits.map fun b => cond b 1 0 := by
  induction' n using Nat.binaryRecFromOne with b n h ih
  · simp
  · rfl
  rw [bits_append_bit _ _ fun hn => absurd hn h]
  cases b
  · rw [digits_def' one_lt_two]
    · simpa [Nat.bit, Nat.bit0_val n]
    · simpa [pos_iff_ne_zero, bit_eq_zero_iff]
  · 

Proof state:
case f.true
n✝ n : ℕ
h : n ≠ 0
ih : digits 2 n = List.map (fun b => bif b then 1 else 0) (bits n)
⊢ digits 2 (bit true n) = List.map (fun b => bif b then 1 else 0) (true :: bits n)

Next tactic:
simpa [Nat.bit, Nat.bit1_val n, add_comm, digits_add 2 one_lt_two 1 n, Nat.add_mul_div_left]
theorem dvd_ofDigits_sub_ofDigits {α : Type*} [CommRing α] {a b k : α} (h : k ∣ a - b)
    (L : List ℕ) : k ∣ ofDigits a L - ofDigits b L := by
  

Proof state:
n : ℕ
α : Type u_1
inst✝ : CommRing α
a b k : α
h : k ∣ a - b
L : List ℕ
⊢ k ∣ ofDigits a L - ofDigits b L

Next tactic:
induction' L with d L ih
theorem dvd_ofDigits_sub_ofDigits {α : Type*} [CommRing α] {a b k : α} (h : k ∣ a - b)
    (L : List ℕ) : k ∣ ofDigits a L - ofDigits b L := by
  induction' L with d L ih
  · 

Proof state:
case nil
n : ℕ
α : Type u_1
inst✝ : CommRing α
a b k : α
h : k ∣ a - b
⊢ k ∣ ofDigits a [] - ofDigits b []

Next tactic:
change k ∣ 0 - 0
theorem dvd_ofDigits_sub_ofDigits {α : Type*} [CommRing α] {a b k : α} (h : k ∣ a - b)
    (L : List ℕ) : k ∣ ofDigits a L - ofDigits b L := by
  induction' L with d L ih
  · change k ∣ 0 - 0
    

Proof state:
case nil
n : ℕ
α : Type u_1
inst✝ : CommRing α
a b k : α
h : k ∣ a - b
⊢ k ∣ 0 - 0

Next tactic:
simp
theorem dvd_ofDigits_sub_ofDigits {α : Type*} [CommRing α] {a b k : α} (h : k ∣ a - b)
    (L : List ℕ) : k ∣ ofDigits a L - ofDigits b L := by
  induction' L with d L ih
  · change k ∣ 0 - 0
    simp
  · 

Proof state:
case cons
n : ℕ
α : Type u_1
inst✝ : CommRing α
a b k : α
h : k ∣ a - b
d : ℕ
L : List ℕ
ih : k ∣ ofDigits a L - ofDigits b L
⊢ k ∣ ofDigits a (d :: L) - ofDigits b (d :: L)

Next tactic:
simp only [ofDigits, add_sub_add_left_eq_sub]
theorem dvd_ofDigits_sub_ofDigits {α : Type*} [CommRing α] {a b k : α} (h : k ∣ a - b)
    (L : List ℕ) : k ∣ ofDigits a L - ofDigits b L := by
  induction' L with d L ih
  · change k ∣ 0 - 0
    simp
  · simp only [ofDigits, add_sub_add_left_eq_sub]
    

Proof state:
case cons
n : ℕ
α : Type u_1
inst✝ : CommRing α
a b k : α
h : k ∣ a - b
d : ℕ
L : List ℕ
ih : k ∣ ofDigits a L - ofDigits b L
⊢ k ∣ a * ofDigits a L - b * ofDigits b L

Next tactic:
exact dvd_mul_sub_mul h ih
theorem ofDigits_modEq' (b b' : ℕ) (k : ℕ) (h : b ≡ b' [MOD k]) (L : List ℕ) :
    ofDigits b L ≡ ofDigits b' L [MOD k] := by
  

Proof state:
n b b' k : ℕ
h : b ≡ b' [MOD k]
L : List ℕ
⊢ ofDigits b L ≡ ofDigits b' L [MOD k]

Next tactic:
induction' L with d L ih
theorem ofDigits_modEq' (b b' : ℕ) (k : ℕ) (h : b ≡ b' [MOD k]) (L : List ℕ) :
    ofDigits b L ≡ ofDigits b' L [MOD k] := by
  induction' L with d L ih
  · 

Proof state:
case nil
n b b' k : ℕ
h : b ≡ b' [MOD k]
⊢ ofDigits b [] ≡ ofDigits b' [] [MOD k]

Next tactic:
rfl
theorem ofDigits_modEq' (b b' : ℕ) (k : ℕ) (h : b ≡ b' [MOD k]) (L : List ℕ) :
    ofDigits b L ≡ ofDigits b' L [MOD k] := by
  induction' L with d L ih
  · rfl
  · 

Proof state:
case cons
n b b' k : ℕ
h : b ≡ b' [MOD k]
d : ℕ
L : List ℕ
ih : ofDigits b L ≡ ofDigits b' L [MOD k]
⊢ ofDigits b (d :: L) ≡ ofDigits b' (d :: L) [MOD k]

Next tactic:
dsimp [ofDigits]
theorem ofDigits_modEq' (b b' : ℕ) (k : ℕ) (h : b ≡ b' [MOD k]) (L : List ℕ) :
    ofDigits b L ≡ ofDigits b' L [MOD k] := by
  induction' L with d L ih
  · rfl
  · dsimp [ofDigits]
    

Proof state:
case cons
n b b' k : ℕ
h : b ≡ b' [MOD k]
d : ℕ
L : List ℕ
ih : ofDigits b L ≡ ofDigits b' L [MOD k]
⊢ d + b * ofDigits b L ≡ d + b' * ofDigits b' L [MOD k]

Next tactic:
dsimp [Nat.ModEq] at *
theorem ofDigits_modEq' (b b' : ℕ) (k : ℕ) (h : b ≡ b' [MOD k]) (L : List ℕ) :
    ofDigits b L ≡ ofDigits b' L [MOD k] := by
  induction' L with d L ih
  · rfl
  · dsimp [ofDigits]
    dsimp [Nat.ModEq] at *
    

Proof state:
case cons
n b b' k : ℕ
h : b % k = b' % k
d : ℕ
L : List ℕ
ih : ofDigits b L % k = ofDigits b' L % k
⊢ (d + b * ofDigits b L) % k = (d + b' * ofDigits b' L) % k

Next tactic:
conv_lhs => rw [Nat.add_mod, Nat.mul_mod, h, ih]
theorem ofDigits_modEq' (b b' : ℕ) (k : ℕ) (h : b ≡ b' [MOD k]) (L : List ℕ) :
    ofDigits b L ≡ ofDigits b' L [MOD k] := by
  induction' L with d L ih
  · rfl
  · dsimp [ofDigits]
    dsimp [Nat.ModEq] at *
    conv_lhs => 

Proof state:
n b b' k : ℕ
h : b % k = b' % k
d : ℕ
L : List ℕ
ih : ofDigits b L % k = ofDigits b' L % k
| (d + b * ofDigits b L) % k

Next tactic:
rw [Nat.add_mod, Nat.mul_mod, h, ih]