l3lab/ntp-mathlib huggingface dataset:
theorem mul_eq_right_iff_opow_omega_dvd {a b : Ordinal} : a * b = b ↔ (a^omega) ∣ b := by
  rcases eq_zero_or_pos a with ha | ha
  · rw [ha, zero_mul, zero_opow omega_ne_zero, zero_dvd_iff]
    exact eq_comm
  refine' ⟨fun hab => _, fun h => _⟩
  · rw [dvd_iff_mod_eq_zero]
    rw [← div_add_mod b (a^omega), mul_add, ← mul_assoc, ← opow_one_add, one_add_omega,
      add_left_cancel] at hab
    cases' eq_zero_or_opow_omega_le_of_mul_eq_right hab with hab hab
    · exact hab
    refine' (not_lt_of_le hab (mod_lt b (opow_ne_zero omega _))).elim
    

Proof state:
case inr.refine'_1.inr
a b : Ordinal.{u_1}
ha : 0 < a
hab✝ : a * (b % a ^ ω) = b % a ^ ω
hab : a ^ ω ≤ b % a ^ ω
⊢ a ≠ 0

Next tactic:
rwa [← Ordinal.pos_iff_ne_zero]
theorem mul_eq_right_iff_opow_omega_dvd {a b : Ordinal} : a * b = b ↔ (a^omega) ∣ b := by
  rcases eq_zero_or_pos a with ha | ha
  · rw [ha, zero_mul, zero_opow omega_ne_zero, zero_dvd_iff]
    exact eq_comm
  refine' ⟨fun hab => _, fun h => _⟩
  · rw [dvd_iff_mod_eq_zero]
    rw [← div_add_mod b (a^omega), mul_add, ← mul_assoc, ← opow_one_add, one_add_omega,
      add_left_cancel] at hab
    cases' eq_zero_or_opow_omega_le_of_mul_eq_right hab with hab hab
    · exact hab
    refine' (not_lt_of_le hab (mod_lt b (opow_ne_zero omega _))).elim
    rwa [← Ordinal.pos_iff_ne_zero]
  

Proof state:
case inr.refine'_2
a b : Ordinal.{u_1}
ha : 0 < a
h : a ^ ω ∣ b
⊢ a * b = b

Next tactic:
cases' h with c hc
theorem mul_eq_right_iff_opow_omega_dvd {a b : Ordinal} : a * b = b ↔ (a^omega) ∣ b := by
  rcases eq_zero_or_pos a with ha | ha
  · rw [ha, zero_mul, zero_opow omega_ne_zero, zero_dvd_iff]
    exact eq_comm
  refine' ⟨fun hab => _, fun h => _⟩
  · rw [dvd_iff_mod_eq_zero]
    rw [← div_add_mod b (a^omega), mul_add, ← mul_assoc, ← opow_one_add, one_add_omega,
      add_left_cancel] at hab
    cases' eq_zero_or_opow_omega_le_of_mul_eq_right hab with hab hab
    · exact hab
    refine' (not_lt_of_le hab (mod_lt b (opow_ne_zero omega _))).elim
    rwa [← Ordinal.pos_iff_ne_zero]
  cases' h with c hc
  

Proof state:
case inr.refine'_2.intro
a b : Ordinal.{u_1}
ha : 0 < a
c : Ordinal.{u_1}
hc : b = a ^ ω * c
⊢ a * b = b

Next tactic:
rw [hc, ← mul_assoc, ← opow_one_add, one_add_omega]
theorem mul_le_right_iff_opow_omega_dvd {a b : Ordinal} (ha : 0 < a) :
    a * b ≤ b ↔ (a^omega) ∣ b := by
  

Proof state:
a b : Ordinal.{u_1}
ha : 0 < a
⊢ a * b ≤ b ↔ a ^ ω ∣ b

Next tactic:
rw [← mul_eq_right_iff_opow_omega_dvd]
theorem mul_le_right_iff_opow_omega_dvd {a b : Ordinal} (ha : 0 < a) :
    a * b ≤ b ↔ (a^omega) ∣ b := by
  rw [← mul_eq_right_iff_opow_omega_dvd]
  

Proof state:
a b : Ordinal.{u_1}
ha : 0 < a
⊢ a * b ≤ b ↔ a * b = b

Next tactic:
exact (mul_isNormal ha).le_iff_eq
theorem nfp_mul_opow_omega_add {a c : Ordinal} (b) (ha : 0 < a) (hc : 0 < c) (hca : c ≤ (a^omega)) :
    nfp (a * ·) ((a^omega) * b + c) = (a^omega.{u}) * succ b := by
  

Proof state:
a c b : Ordinal.{u}
ha : 0 < a
hc : 0 < c
hca : c ≤ a ^ ω
⊢ nfp (fun x => a * x) (a ^ ω * b + c) = a ^ ω * succ b

Next tactic:
apply le_antisymm
theorem nfp_mul_opow_omega_add {a c : Ordinal} (b) (ha : 0 < a) (hc : 0 < c) (hca : c ≤ (a^omega)) :
    nfp (a * ·) ((a^omega) * b + c) = (a^omega.{u}) * succ b := by
  apply le_antisymm
  · 

Proof state:
case a
a c b : Ordinal.{u}
ha : 0 < a
hc : 0 < c
hca : c ≤ a ^ ω
⊢ nfp (fun x => a * x) (a ^ ω * b + c) ≤ a ^ ω * succ b

Next tactic:
apply nfp_le_fp (mul_isNormal ha).monotone
theorem nfp_mul_opow_omega_add {a c : Ordinal} (b) (ha : 0 < a) (hc : 0 < c) (hca : c ≤ (a^omega)) :
    nfp (a * ·) ((a^omega) * b + c) = (a^omega.{u}) * succ b := by
  apply le_antisymm
  · apply nfp_le_fp (mul_isNormal ha).monotone
    · 

Proof state:
case a.ab
a c b : Ordinal.{u}
ha : 0 < a
hc : 0 < c
hca : c ≤ a ^ ω
⊢ a ^ ω * b + c ≤ a ^ ω * succ b

Next tactic:
rw [mul_succ]
theorem nfp_mul_opow_omega_add {a c : Ordinal} (b) (ha : 0 < a) (hc : 0 < c) (hca : c ≤ (a^omega)) :
    nfp (a * ·) ((a^omega) * b + c) = (a^omega.{u}) * succ b := by
  apply le_antisymm
  · apply nfp_le_fp (mul_isNormal ha).monotone
    · rw [mul_succ]
      

Proof state:
case a.ab
a c b : Ordinal.{u}
ha : 0 < a
hc : 0 < c
hca : c ≤ a ^ ω
⊢ a ^ ω * b + c ≤ a ^ ω * b + a ^ ω

Next tactic:
apply add_le_add_left hca
theorem nfp_mul_opow_omega_add {a c : Ordinal} (b) (ha : 0 < a) (hc : 0 < c) (hca : c ≤ (a^omega)) :
    nfp (a * ·) ((a^omega) * b + c) = (a^omega.{u}) * succ b := by
  apply le_antisymm
  · apply nfp_le_fp (mul_isNormal ha).monotone
    · rw [mul_succ]
      apply add_le_add_left hca
    · 

Proof state:
case a.h
a c b : Ordinal.{u}
ha : 0 < a
hc : 0 < c
hca : c ≤ a ^ ω
⊢ a * (a ^ ω * succ b) ≤ a ^ ω * succ b

Next tactic:
dsimp only
theorem nfp_mul_opow_omega_add {a c : Ordinal} (b) (ha : 0 < a) (hc : 0 < c) (hca : c ≤ (a^omega)) :
    nfp (a * ·) ((a^omega) * b + c) = (a^omega.{u}) * succ b := by
  apply le_antisymm
  · apply nfp_le_fp (mul_isNormal ha).monotone
    · rw [mul_succ]
      apply add_le_add_left hca
    · dsimp only; 

Proof state:
case a.h
a c b : Ordinal.{u}
ha : 0 < a
hc : 0 < c
hca : c ≤ a ^ ω
⊢ a * (a ^ ω * succ b) ≤ a ^ ω * succ b

Next tactic:
rw [← mul_assoc, ← opow_one_add, one_add_omega]
theorem nfp_mul_opow_omega_add {a c : Ordinal} (b) (ha : 0 < a) (hc : 0 < c) (hca : c ≤ (a^omega)) :
    nfp (a * ·) ((a^omega) * b + c) = (a^omega.{u}) * succ b := by
  apply le_antisymm
  · apply nfp_le_fp (mul_isNormal ha).monotone
    · rw [mul_succ]
      apply add_le_add_left hca
    · dsimp only; rw [← mul_assoc, ← opow_one_add, one_add_omega]
  · 

Proof state:
case a
a c b : Ordinal.{u}
ha : 0 < a
hc : 0 < c
hca : c ≤ a ^ ω
⊢ a ^ ω * succ b ≤ nfp (fun x => a * x) (a ^ ω * b + c)

Next tactic:
cases' mul_eq_right_iff_opow_omega_dvd.1 ((mul_isNormal ha).nfp_fp ((a^omega) * b + c)) with
      d hd
theorem nfp_mul_opow_omega_add {a c : Ordinal} (b) (ha : 0 < a) (hc : 0 < c) (hca : c ≤ (a^omega)) :
    nfp (a * ·) ((a^omega) * b + c) = (a^omega.{u}) * succ b := by
  apply le_antisymm
  · apply nfp_le_fp (mul_isNormal ha).monotone
    · rw [mul_succ]
      apply add_le_add_left hca
    · dsimp only; rw [← mul_assoc, ← opow_one_add, one_add_omega]
  · cases' mul_eq_right_iff_opow_omega_dvd.1 ((mul_isNormal ha).nfp_fp ((a^omega) * b + c)) with
      d hd
    

Proof state:
case a.intro
a c b : Ordinal.{u}
ha : 0 < a
hc : 0 < c
hca : c ≤ a ^ ω
d : Ordinal.{u}
hd : nfp (fun x => a * x) (a ^ ω * b + c) = a ^ ω * d
⊢ a ^ ω * succ b ≤ nfp (fun x => a * x) (a ^ ω * b + c)

Next tactic:
rw [hd]
theorem nfp_mul_opow_omega_add {a c : Ordinal} (b) (ha : 0 < a) (hc : 0 < c) (hca : c ≤ (a^omega)) :
    nfp (a * ·) ((a^omega) * b + c) = (a^omega.{u}) * succ b := by
  apply le_antisymm
  · apply nfp_le_fp (mul_isNormal ha).monotone
    · rw [mul_succ]
      apply add_le_add_left hca
    · dsimp only; rw [← mul_assoc, ← opow_one_add, one_add_omega]
  · cases' mul_eq_right_iff_opow_omega_dvd.1 ((mul_isNormal ha).nfp_fp ((a^omega) * b + c)) with
      d hd
    rw [hd]
    

Proof state:
case a.intro
a c b : Ordinal.{u}
ha : 0 < a
hc : 0 < c
hca : c ≤ a ^ ω
d : Ordinal.{u}
hd : nfp (fun x => a * x) (a ^ ω * b + c) = a ^ ω * d
⊢ a ^ ω * succ b ≤ a ^ ω * d

Next tactic:
apply mul_le_mul_left'
theorem nfp_mul_opow_omega_add {a c : Ordinal} (b) (ha : 0 < a) (hc : 0 < c) (hca : c ≤ (a^omega)) :
    nfp (a * ·) ((a^omega) * b + c) = (a^omega.{u}) * succ b := by
  apply le_antisymm
  · apply nfp_le_fp (mul_isNormal ha).monotone
    · rw [mul_succ]
      apply add_le_add_left hca
    · dsimp only; rw [← mul_assoc, ← opow_one_add, one_add_omega]
  · cases' mul_eq_right_iff_opow_omega_dvd.1 ((mul_isNormal ha).nfp_fp ((a^omega) * b + c)) with
      d hd
    rw [hd]
    apply mul_le_mul_left'
    

Proof state:
case a.intro.bc
a c b : Ordinal.{u}
ha : 0 < a
hc : 0 < c
hca : c ≤ a ^ ω
d : Ordinal.{u}
hd : nfp (fun x => a * x) (a ^ ω * b + c) = a ^ ω * d
⊢ succ b ≤ d

Next tactic:
have := le_nfp (Mul.mul a) ((a^omega) * b + c)
theorem nfp_mul_opow_omega_add {a c : Ordinal} (b) (ha : 0 < a) (hc : 0 < c) (hca : c ≤ (a^omega)) :
    nfp (a * ·) ((a^omega) * b + c) = (a^omega.{u}) * succ b := by
  apply le_antisymm
  · apply nfp_le_fp (mul_isNormal ha).monotone
    · rw [mul_succ]
      apply add_le_add_left hca
    · dsimp only; rw [← mul_assoc, ← opow_one_add, one_add_omega]
  · cases' mul_eq_right_iff_opow_omega_dvd.1 ((mul_isNormal ha).nfp_fp ((a^omega) * b + c)) with
      d hd
    rw [hd]
    apply mul_le_mul_left'
    have := le_nfp (Mul.mul a) ((a^omega) * b + c)
    

Proof state:
case a.intro.bc
a c b : Ordinal.{u}
ha : 0 < a
hc : 0 < c
hca : c ≤ a ^ ω
d : Ordinal.{u}
hd : nfp (fun x => a * x) (a ^ ω * b + c) = a ^ ω * d
this : a ^ ω * b + c ≤ nfp (Mul.mul a) (a ^ ω * b + c)
⊢ succ b ≤ d

Next tactic:
erw [hd] at this
theorem nfp_mul_opow_omega_add {a c : Ordinal} (b) (ha : 0 < a) (hc : 0 < c) (hca : c ≤ (a^omega)) :
    nfp (a * ·) ((a^omega) * b + c) = (a^omega.{u}) * succ b := by
  apply le_antisymm
  · apply nfp_le_fp (mul_isNormal ha).monotone
    · rw [mul_succ]
      apply add_le_add_left hca
    · dsimp only; rw [← mul_assoc, ← opow_one_add, one_add_omega]
  · cases' mul_eq_right_iff_opow_omega_dvd.1 ((mul_isNormal ha).nfp_fp ((a^omega) * b + c)) with
      d hd
    rw [hd]
    apply mul_le_mul_left'
    have := le_nfp (Mul.mul a) ((a^omega) * b + c)
    erw [hd] at this
    

Proof state:
case a.intro.bc
a c b : Ordinal.{u}
ha : 0 < a
hc : 0 < c
hca : c ≤ a ^ ω
d : Ordinal.{u}
hd : nfp (fun x => a * x) (a ^ ω * b + c) = a ^ ω * d
this : a ^ ω * b + c ≤ a ^ ω * d
⊢ succ b ≤ d

Next tactic:
have := (add_lt_add_left hc ((a^omega) * b)).trans_le this
theorem nfp_mul_opow_omega_add {a c : Ordinal} (b) (ha : 0 < a) (hc : 0 < c) (hca : c ≤ (a^omega)) :
    nfp (a * ·) ((a^omega) * b + c) = (a^omega.{u}) * succ b := by
  apply le_antisymm
  · apply nfp_le_fp (mul_isNormal ha).monotone
    · rw [mul_succ]
      apply add_le_add_left hca
    · dsimp only; rw [← mul_assoc, ← opow_one_add, one_add_omega]
  · cases' mul_eq_right_iff_opow_omega_dvd.1 ((mul_isNormal ha).nfp_fp ((a^omega) * b + c)) with
      d hd
    rw [hd]
    apply mul_le_mul_left'
    have := le_nfp (Mul.mul a) ((a^omega) * b + c)
    erw [hd] at this
    have := (add_lt_add_left hc ((a^omega) * b)).trans_le this
    

Proof state:
case a.intro.bc
a c b : Ordinal.{u}
ha : 0 < a
hc : 0 < c
hca : c ≤ a ^ ω
d : Ordinal.{u}
hd : nfp (fun x => a * x) (a ^ ω * b + c) = a ^ ω * d
this✝ : a ^ ω * b + c ≤ a ^ ω * d
this : a ^ ω * b + 0 < a ^ ω * d
⊢ succ b ≤ d

Next tactic:
rw [add_zero, mul_lt_mul_iff_left (opow_pos omega ha)] at this
theorem nfp_mul_opow_omega_add {a c : Ordinal} (b) (ha : 0 < a) (hc : 0 < c) (hca : c ≤ (a^omega)) :
    nfp (a * ·) ((a^omega) * b + c) = (a^omega.{u}) * succ b := by
  apply le_antisymm
  · apply nfp_le_fp (mul_isNormal ha).monotone
    · rw [mul_succ]
      apply add_le_add_left hca
    · dsimp only; rw [← mul_assoc, ← opow_one_add, one_add_omega]
  · cases' mul_eq_right_iff_opow_omega_dvd.1 ((mul_isNormal ha).nfp_fp ((a^omega) * b + c)) with
      d hd
    rw [hd]
    apply mul_le_mul_left'
    have := le_nfp (Mul.mul a) ((a^omega) * b + c)
    erw [hd] at this
    have := (add_lt_add_left hc ((a^omega) * b)).trans_le this
    rw [add_zero, mul_lt_mul_iff_left (opow_pos omega ha)] at this
    

Proof state:
case a.intro.bc
a c b : Ordinal.{u}
ha : 0 < a
hc : 0 < c
hca : c ≤ a ^ ω
d : Ordinal.{u}
hd : nfp (fun x => a * x) (a ^ ω * b + c) = a ^ ω * d
this✝ : a ^ ω * b + c ≤ a ^ ω * d
this : b < d
⊢ succ b ≤ d

Next tactic:
rwa [succ_le_iff]
theorem deriv_mul_eq_opow_omega_mul {a : Ordinal.{u}} (ha : 0 < a) (b) :
    deriv (a * ·) b = (a^omega) * b := by
  

Proof state:
a : Ordinal.{u}
ha : 0 < a
b : Ordinal.{u}
⊢ deriv (fun x => a * x) b = a ^ ω * b

Next tactic:
revert b
theorem deriv_mul_eq_opow_omega_mul {a : Ordinal.{u}} (ha : 0 < a) (b) :
    deriv (a * ·) b = (a^omega) * b := by
  revert b
  

Proof state:
a : Ordinal.{u}
ha : 0 < a
⊢ ∀ (b : Ordinal.{u}), deriv (fun x => a * x) b = a ^ ω * b

Next tactic:
rw [← funext_iff,
    IsNormal.eq_iff_zero_and_succ (deriv_isNormal _) (mul_isNormal (opow_pos omega ha))]
theorem deriv_mul_eq_opow_omega_mul {a : Ordinal.{u}} (ha : 0 < a) (b) :
    deriv (a * ·) b = (a^omega) * b := by
  revert b
  rw [← funext_iff,
    IsNormal.eq_iff_zero_and_succ (deriv_isNormal _) (mul_isNormal (opow_pos omega ha))]
  

Proof state:
a : Ordinal.{u}
ha : 0 < a
⊢ deriv (fun x => a * x) 0 = a ^ ω * 0 ∧
    ∀ (a_1 : Ordinal.{u}),
      deriv (fun x => a * x) a_1 = a ^ ω * a_1 → deriv (fun x => a * x) (succ a_1) = a ^ ω * succ a_1

Next tactic:
refine' ⟨_, fun c h => _⟩
theorem deriv_mul_eq_opow_omega_mul {a : Ordinal.{u}} (ha : 0 < a) (b) :
    deriv (a * ·) b = (a^omega) * b := by
  revert b
  rw [← funext_iff,
    IsNormal.eq_iff_zero_and_succ (deriv_isNormal _) (mul_isNormal (opow_pos omega ha))]
  refine' ⟨_, fun c h => _⟩
  · 

Proof state:
case refine'_1
a : Ordinal.{u}
ha : 0 < a
⊢ deriv (fun x => a * x) 0 = a ^ ω * 0

Next tactic:
dsimp only
theorem deriv_mul_eq_opow_omega_mul {a : Ordinal.{u}} (ha : 0 < a) (b) :
    deriv (a * ·) b = (a^omega) * b := by
  revert b
  rw [← funext_iff,
    IsNormal.eq_iff_zero_and_succ (deriv_isNormal _) (mul_isNormal (opow_pos omega ha))]
  refine' ⟨_, fun c h => _⟩
  · dsimp only; 

Proof state:
case refine'_1
a : Ordinal.{u}
ha : 0 < a
⊢ deriv (fun x => a * x) 0 = a ^ ω * 0

Next tactic:
rw [deriv_zero, nfp_mul_zero, mul_zero]
theorem deriv_mul_eq_opow_omega_mul {a : Ordinal.{u}} (ha : 0 < a) (b) :
    deriv (a * ·) b = (a^omega) * b := by
  revert b
  rw [← funext_iff,
    IsNormal.eq_iff_zero_and_succ (deriv_isNormal _) (mul_isNormal (opow_pos omega ha))]
  refine' ⟨_, fun c h => _⟩
  · dsimp only; rw [deriv_zero, nfp_mul_zero, mul_zero]
  · 

Proof state:
case refine'_2
a : Ordinal.{u}
ha : 0 < a
c : Ordinal.{u}
h : deriv (fun x => a * x) c = a ^ ω * c
⊢ deriv (fun x => a * x) (succ c) = a ^ ω * succ c

Next tactic:
rw [deriv_succ, h]
theorem deriv_mul_eq_opow_omega_mul {a : Ordinal.{u}} (ha : 0 < a) (b) :
    deriv (a * ·) b = (a^omega) * b := by
  revert b
  rw [← funext_iff,
    IsNormal.eq_iff_zero_and_succ (deriv_isNormal _) (mul_isNormal (opow_pos omega ha))]
  refine' ⟨_, fun c h => _⟩
  · dsimp only; rw [deriv_zero, nfp_mul_zero, mul_zero]
  · rw [deriv_succ, h]
    

Proof state:
case refine'_2
a : Ordinal.{u}
ha : 0 < a
c : Ordinal.{u}
h : deriv (fun x => a * x) c = a ^ ω * c
⊢ nfp (fun x => a * x) (succ (a ^ ω * c)) = a ^ ω * succ c

Next tactic:
exact nfp_mul_opow_omega_add c ha zero_lt_one (one_le_iff_pos.2 (opow_pos _ ha))
@[simp]
theorem count_not_add_count (l : List Bool) (b : Bool) : count (!b) l + count b l = length l := by
  -- Porting note: Proof re-written
  -- Old proof: simp only [length_eq_countP_add_countP (Eq (!b)), Bool.not_not_eq, count]
  

Proof state:
l : List Bool
b : Bool
⊢ count (!b) l + count b l = length l

Next tactic:
simp only [length_eq_countP_add_countP (· == !b), count, add_right_inj]
@[simp]
theorem count_not_add_count (l : List Bool) (b : Bool) : count (!b) l + count b l = length l := by
  -- Porting note: Proof re-written
  -- Old proof: simp only [length_eq_countP_add_countP (Eq (!b)), Bool.not_not_eq, count]
  simp only [length_eq_countP_add_countP (· == !b), count, add_right_inj]
  

Proof state:
l : List Bool
b : Bool
⊢ countP (fun x => x == b) l = countP (fun a => decide ¬(a == !b) = true) l

Next tactic:
suffices (fun x => x == b) = (fun a => decide ¬(a == !b) = true) by rw [this]
@[simp]
theorem count_not_add_count (l : List Bool) (b : Bool) : count (!b) l + count b l = length l := by
  -- Porting note: Proof re-written
  -- Old proof: simp only [length_eq_countP_add_countP (Eq (!b)), Bool.not_not_eq, count]
  simp only [length_eq_countP_add_countP (· == !b), count, add_right_inj]
  suffices (fun x => x == b) = (fun a => decide ¬(a == !b) = true) by 

Proof state:
l : List Bool
b : Bool
this : (fun x => x == b) = fun a => decide ¬(a == !b) = true
⊢ countP (fun x => x == b) l = countP (fun a => decide ¬(a == !b) = true) l

Next tactic:
rw [this]
@[simp]
theorem count_not_add_count (l : List Bool) (b : Bool) : count (!b) l + count b l = length l := by
  -- Porting note: Proof re-written
  -- Old proof: simp only [length_eq_countP_add_countP (Eq (!b)), Bool.not_not_eq, count]
  simp only [length_eq_countP_add_countP (· == !b), count, add_right_inj]
  suffices (fun x => x == b) = (fun a => decide ¬(a == !b) = true) by rw [this]
  

Proof state:
l : List Bool
b : Bool
⊢ (fun x => x == b) = fun a => decide ¬(a == !b) = true

Next tactic:
ext x
@[simp]
theorem count_not_add_count (l : List Bool) (b : Bool) : count (!b) l + count b l = length l := by
  -- Porting note: Proof re-written
  -- Old proof: simp only [length_eq_countP_add_countP (Eq (!b)), Bool.not_not_eq, count]
  simp only [length_eq_countP_add_countP (· == !b), count, add_right_inj]
  suffices (fun x => x == b) = (fun a => decide ¬(a == !b) = true) by rw [this]
  ext x; 

Proof state:
case h
l : List Bool
b x : Bool
⊢ (x == b) = decide ¬(x == !b) = true

Next tactic:
cases x
@[simp]
theorem count_not_add_count (l : List Bool) (b : Bool) : count (!b) l + count b l = length l := by
  -- Porting note: Proof re-written
  -- Old proof: simp only [length_eq_countP_add_countP (Eq (!b)), Bool.not_not_eq, count]
  simp only [length_eq_countP_add_countP (· == !b), count, add_right_inj]
  suffices (fun x => x == b) = (fun a => decide ¬(a == !b) = true) by rw [this]
  ext x; cases x <;> 

Proof state:
case h.false
l : List Bool
b : Bool
⊢ (false == b) = decide ¬(false == !b) = true

Next tactic:
cases b
@[simp]
theorem count_not_add_count (l : List Bool) (b : Bool) : count (!b) l + count b l = length l := by
  -- Porting note: Proof re-written
  -- Old proof: simp only [length_eq_countP_add_countP (Eq (!b)), Bool.not_not_eq, count]
  simp only [length_eq_countP_add_countP (· == !b), count, add_right_inj]
  suffices (fun x => x == b) = (fun a => decide ¬(a == !b) = true) by rw [this]
  ext x; cases x <;> 

Proof state:
case h.true
l : List Bool
b : Bool
⊢ (true == b) = decide ¬(true == !b) = true

Next tactic:
cases b
@[simp]
theorem count_not_add_count (l : List Bool) (b : Bool) : count (!b) l + count b l = length l := by
  -- Porting note: Proof re-written
  -- Old proof: simp only [length_eq_countP_add_countP (Eq (!b)), Bool.not_not_eq, count]
  simp only [length_eq_countP_add_countP (· == !b), count, add_right_inj]
  suffices (fun x => x == b) = (fun a => decide ¬(a == !b) = true) by rw [this]
  ext x; cases x <;> cases b <;> 

Proof state:
case h.false.false
l : List Bool
⊢ (false == false) = decide ¬(false == !false) = true

Next tactic:
rfl
@[simp]
theorem count_not_add_count (l : List Bool) (b : Bool) : count (!b) l + count b l = length l := by
  -- Porting note: Proof re-written
  -- Old proof: simp only [length_eq_countP_add_countP (Eq (!b)), Bool.not_not_eq, count]
  simp only [length_eq_countP_add_countP (· == !b), count, add_right_inj]
  suffices (fun x => x == b) = (fun a => decide ¬(a == !b) = true) by rw [this]
  ext x; cases x <;> cases b <;> 

Proof state:
case h.false.true
l : List Bool
⊢ (false == true) = decide ¬(false == !true) = true

Next tactic:
rfl
@[simp]
theorem count_not_add_count (l : List Bool) (b : Bool) : count (!b) l + count b l = length l := by
  -- Porting note: Proof re-written
  -- Old proof: simp only [length_eq_countP_add_countP (Eq (!b)), Bool.not_not_eq, count]
  simp only [length_eq_countP_add_countP (· == !b), count, add_right_inj]
  suffices (fun x => x == b) = (fun a => decide ¬(a == !b) = true) by rw [this]
  ext x; cases x <;> cases b <;> 

Proof state:
case h.true.false
l : List Bool
⊢ (true == false) = decide ¬(true == !false) = true

Next tactic:
rfl
@[simp]
theorem count_not_add_count (l : List Bool) (b : Bool) : count (!b) l + count b l = length l := by
  -- Porting note: Proof re-written
  -- Old proof: simp only [length_eq_countP_add_countP (Eq (!b)), Bool.not_not_eq, count]
  simp only [length_eq_countP_add_countP (· == !b), count, add_right_inj]
  suffices (fun x => x == b) = (fun a => decide ¬(a == !b) = true) by rw [this]
  ext x; cases x <;> cases b <;> 

Proof state:
case h.true.true
l : List Bool
⊢ (true == true) = decide ¬(true == !true) = true

Next tactic:
rfl
@[simp]
theorem count_add_count_not (l : List Bool) (b : Bool) : count b l + count (!b) l = length l := by
  

Proof state:
l : List Bool
b : Bool
⊢ count b l + count (!b) l = length l

Next tactic:
rw [add_comm, count_not_add_count]
theorem Chain.count_not :
    ∀ {b : Bool} {l : List Bool}, Chain (· ≠ ·) b l → count (!b) l = count b l + length l % 2
  | b, [], _h => rfl
  | b, x :: l, h => by
    

Proof state:
b x : Bool
l : List Bool
h : Chain (fun x x_1 => x ≠ x_1) b (x :: l)
⊢ count (!b) (x :: l) = count b (x :: l) + length (x :: l) % 2

Next tactic:
obtain rfl : b = !x := Bool.eq_not_iff.2 (rel_of_chain_cons h)
theorem Chain.count_not :
    ∀ {b : Bool} {l : List Bool}, Chain (· ≠ ·) b l → count (!b) l = count b l + length l % 2
  | b, [], _h => rfl
  | b, x :: l, h => by
    obtain rfl : b = !x := Bool.eq_not_iff.2 (rel_of_chain_cons h)
    

Proof state:
x : Bool
l : List Bool
h : Chain (fun x x_1 => x ≠ x_1) (!x) (x :: l)
⊢ count (!!x) (x :: l) = count (!x) (x :: l) + length (x :: l) % 2

Next tactic:
rw [Bool.not_not, count_cons_self, count_cons_of_ne x.not_ne_self,
      Chain.count_not (chain_of_chain_cons h), length, add_assoc, Nat.mod_two_add_succ_mod_two]
theorem count_not_eq_count (hl : Chain' (· ≠ ·) l) (h2 : Even (length l)) (b : Bool) :
    count (!b) l = count b l := by
  

Proof state:
l : List Bool
hl : Chain' (fun x x_1 => x ≠ x_1) l
h2 : Even (length l)
b : Bool
⊢ count (!b) l = count b l

Next tactic:
cases' l with x l
theorem count_not_eq_count (hl : Chain' (· ≠ ·) l) (h2 : Even (length l)) (b : Bool) :
    count (!b) l = count b l := by
  cases' l with x l
  · 

Proof state:
case nil
b : Bool
hl : Chain' (fun x x_1 => x ≠ x_1) []
h2 : Even (length [])
⊢ count (!b) [] = count b []

Next tactic:
rfl
theorem count_not_eq_count (hl : Chain' (· ≠ ·) l) (h2 : Even (length l)) (b : Bool) :
    count (!b) l = count b l := by
  cases' l with x l
  · rfl
  

Proof state:
case cons
b x : Bool
l : List Bool
hl : Chain' (fun x x_1 => x ≠ x_1) (x :: l)
h2 : Even (length (x :: l))
⊢ count (!b) (x :: l) = count b (x :: l)

Next tactic:
rw [length_cons, Nat.even_add_one, Nat.not_even_iff] at h2
theorem count_not_eq_count (hl : Chain' (· ≠ ·) l) (h2 : Even (length l)) (b : Bool) :
    count (!b) l = count b l := by
  cases' l with x l
  · rfl
  rw [length_cons, Nat.even_add_one, Nat.not_even_iff] at h2
  

Proof state:
case cons
b x : Bool
l : List Bool
hl : Chain' (fun x x_1 => x ≠ x_1) (x :: l)
h2 : length l % 2 = 1
⊢ count (!b) (x :: l) = count b (x :: l)

Next tactic:
suffices count (!x) (x :: l) = count x (x :: l) by
    -- Porting note: old proof is
    -- cases b <;> cases x <;> try exact this;
    cases b <;> cases x <;>
    revert this <;> simp only [Bool.not_false, Bool.not_true] <;> intro this <;>
    (try exact this) <;> exact this.symm
theorem count_not_eq_count (hl : Chain' (· ≠ ·) l) (h2 : Even (length l)) (b : Bool) :
    count (!b) l = count b l := by
  cases' l with x l
  · rfl
  rw [length_cons, Nat.even_add_one, Nat.not_even_iff] at h2
  suffices count (!x) (x :: l) = count x (x :: l) by
    -- Porting note: old proof is
    -- cases b <;> cases x <;> try exact this;
    

Proof state:
b x : Bool
l : List Bool
hl : Chain' (fun x x_1 => x ≠ x_1) (x :: l)
h2 : length l % 2 = 1
this : count (!x) (x :: l) = count x (x :: l)
⊢ count (!b) (x :: l) = count b (x :: l)

Next tactic:
cases b
theorem count_not_eq_count (hl : Chain' (· ≠ ·) l) (h2 : Even (length l)) (b : Bool) :
    count (!b) l = count b l := by
  cases' l with x l
  · rfl
  rw [length_cons, Nat.even_add_one, Nat.not_even_iff] at h2
  suffices count (!x) (x :: l) = count x (x :: l) by
    -- Porting note: old proof is
    -- cases b <;> cases x <;> try exact this;
    cases b <;> 

Proof state:
case false
x : Bool
l : List Bool
hl : Chain' (fun x x_1 => x ≠ x_1) (x :: l)
h2 : length l % 2 = 1
this : count (!x) (x :: l) = count x (x :: l)
⊢ count (!false) (x :: l) = count false (x :: l)

Next tactic:
cases x