l3lab/ntp-mathlib huggingface dataset:
theorem splits_iff_card_roots (ha : P.a ≠ 0) :
    Splits φ P.toPoly ↔ Multiset.card (map φ P).roots = 3 := by
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic F
inst✝¹ : Field F
inst✝ : Field K
φ : F →+* K
x y z : K
ha : P.a ≠ 0
⊢ Splits φ (toPoly P) ↔ card (roots (map φ P)) = 3

Next tactic:
replace ha : (map φ P).a ≠ 0 := (_root_.map_ne_zero φ).mpr ha
theorem splits_iff_card_roots (ha : P.a ≠ 0) :
    Splits φ P.toPoly ↔ Multiset.card (map φ P).roots = 3 := by
  replace ha : (map φ P).a ≠ 0 := (_root_.map_ne_zero φ).mpr ha
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic F
inst✝¹ : Field F
inst✝ : Field K
φ : F →+* K
x y z : K
ha : (map φ P).a ≠ 0
⊢ Splits φ (toPoly P) ↔ card (roots (map φ P)) = 3

Next tactic:
nth_rw 1 [← RingHom.id_comp φ]
theorem splits_iff_card_roots (ha : P.a ≠ 0) :
    Splits φ P.toPoly ↔ Multiset.card (map φ P).roots = 3 := by
  replace ha : (map φ P).a ≠ 0 := (_root_.map_ne_zero φ).mpr ha
  nth_rw 1 [← RingHom.id_comp φ]
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic F
inst✝¹ : Field F
inst✝ : Field K
φ : F →+* K
x y z : K
ha : (map φ P).a ≠ 0
⊢ Splits (RingHom.comp (RingHom.id K) φ) (toPoly P) ↔ card (roots (map φ P)) = 3

Next tactic:
rw [roots, ← splits_map_iff, ← map_toPoly, Polynomial.splits_iff_card_roots,
    ← ((degree_eq_iff_natDegree_eq <| ne_zero_of_a_ne_zero ha).1 <| degree_of_a_ne_zero ha : _ = 3)]
theorem splits_iff_roots_eq_three (ha : P.a ≠ 0) :
    Splits φ P.toPoly ↔ ∃ x y z : K, (map φ P).roots = {x, y, z} := by
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic F
inst✝¹ : Field F
inst✝ : Field K
φ : F →+* K
x y z : K
ha : P.a ≠ 0
⊢ Splits φ (toPoly P) ↔ ∃ x y z, roots (map φ P) = {x, y, z}

Next tactic:
rw [splits_iff_card_roots ha, card_eq_three]
theorem eq_prod_three_roots (ha : P.a ≠ 0) (h3 : (map φ P).roots = {x, y, z}) :
    (map φ P).toPoly = C (φ P.a) * (X - C x) * (X - C y) * (X - C z) := by
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic F
inst✝¹ : Field F
inst✝ : Field K
φ : F →+* K
x y z : K
ha : P.a ≠ 0
h3 : roots (map φ P) = {x, y, z}
⊢ toPoly (map φ P) = C (φ P.a) * (X - C x) * (X - C y) * (X - C z)

Next tactic:
rw [map_toPoly,
    eq_prod_roots_of_splits <|
      (splits_iff_roots_eq_three ha).mpr <| Exists.intro x <| Exists.intro y <| Exists.intro z h3,
    leadingCoeff_of_a_ne_zero ha, ← map_roots, h3]
theorem eq_prod_three_roots (ha : P.a ≠ 0) (h3 : (map φ P).roots = {x, y, z}) :
    (map φ P).toPoly = C (φ P.a) * (X - C x) * (X - C y) * (X - C z) := by
  rw [map_toPoly,
    eq_prod_roots_of_splits <|
      (splits_iff_roots_eq_three ha).mpr <| Exists.intro x <| Exists.intro y <| Exists.intro z h3,
    leadingCoeff_of_a_ne_zero ha, ← map_roots, h3]
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic F
inst✝¹ : Field F
inst✝ : Field K
φ : F →+* K
x y z : K
ha : P.a ≠ 0
h3 : roots (map φ P) = {x, y, z}
⊢ C (φ P.a) * prod (Multiset.map (fun a => X - C a) {x, y, z}) = C (φ P.a) * (X - C x) * (X - C y) * (X - C z)

Next tactic:
change C (φ P.a) * ((X - C x) ::ₘ (X - C y) ::ₘ {X - C z}).prod = _
theorem eq_prod_three_roots (ha : P.a ≠ 0) (h3 : (map φ P).roots = {x, y, z}) :
    (map φ P).toPoly = C (φ P.a) * (X - C x) * (X - C y) * (X - C z) := by
  rw [map_toPoly,
    eq_prod_roots_of_splits <|
      (splits_iff_roots_eq_three ha).mpr <| Exists.intro x <| Exists.intro y <| Exists.intro z h3,
    leadingCoeff_of_a_ne_zero ha, ← map_roots, h3]
  change C (φ P.a) * ((X - C x) ::ₘ (X - C y) ::ₘ {X - C z}).prod = _
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic F
inst✝¹ : Field F
inst✝ : Field K
φ : F →+* K
x y z : K
ha : P.a ≠ 0
h3 : roots (map φ P) = {x, y, z}
⊢ C (φ P.a) * prod ((X - C x) ::ₘ (X - C y) ::ₘ {X - C z}) = C (φ P.a) * (X - C x) * (X - C y) * (X - C z)

Next tactic:
rw [prod_cons, prod_cons, prod_singleton, mul_assoc, mul_assoc]
theorem eq_sum_three_roots (ha : P.a ≠ 0) (h3 : (map φ P).roots = {x, y, z}) :
    map φ P =
      ⟨φ P.a, φ P.a * -(x + y + z), φ P.a * (x * y + x * z + y * z), φ P.a * -(x * y * z)⟩ := by
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic F
inst✝¹ : Field F
inst✝ : Field K
φ : F →+* K
x y z : K
ha : P.a ≠ 0
h3 : roots (map φ P) = {x, y, z}
⊢ map φ P = { a := φ P.a, b := φ P.a * -(x + y + z), c := φ P.a * (x * y + x * z + y * z), d := φ P.a * -(x * y * z) }

Next tactic:
apply_fun @toPoly _ _
theorem eq_sum_three_roots (ha : P.a ≠ 0) (h3 : (map φ P).roots = {x, y, z}) :
    map φ P =
      ⟨φ P.a, φ P.a * -(x + y + z), φ P.a * (x * y + x * z + y * z), φ P.a * -(x * y * z)⟩ := by
  apply_fun @toPoly _ _
  · 

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic F
inst✝¹ : Field F
inst✝ : Field K
φ : F →+* K
x y z : K
ha : P.a ≠ 0
h3 : roots (map φ P) = {x, y, z}
⊢ toPoly (map φ P) =
    toPoly { a := φ P.a, b := φ P.a * -(x + y + z), c := φ P.a * (x * y + x * z + y * z), d := φ P.a * -(x * y * z) }

Next tactic:
rw [eq_prod_three_roots ha h3, C_mul_prod_X_sub_C_eq]
theorem eq_sum_three_roots (ha : P.a ≠ 0) (h3 : (map φ P).roots = {x, y, z}) :
    map φ P =
      ⟨φ P.a, φ P.a * -(x + y + z), φ P.a * (x * y + x * z + y * z), φ P.a * -(x * y * z)⟩ := by
  apply_fun @toPoly _ _
  · rw [eq_prod_three_roots ha h3, C_mul_prod_X_sub_C_eq]
  · 

Proof state:
case inj
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic F
inst✝¹ : Field F
inst✝ : Field K
φ : F →+* K
x y z : K
ha : P.a ≠ 0
h3 : roots (map φ P) = {x, y, z}
⊢ Function.Injective toPoly

Next tactic:
exact fun P Q ↦ (toPoly_injective P Q).mp
theorem b_eq_three_roots (ha : P.a ≠ 0) (h3 : (map φ P).roots = {x, y, z}) :
    φ P.b = φ P.a * -(x + y + z) := by
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic F
inst✝¹ : Field F
inst✝ : Field K
φ : F →+* K
x y z : K
ha : P.a ≠ 0
h3 : roots (map φ P) = {x, y, z}
⊢ φ P.b = φ P.a * -(x + y + z)

Next tactic:
injection eq_sum_three_roots ha h3
theorem c_eq_three_roots (ha : P.a ≠ 0) (h3 : (map φ P).roots = {x, y, z}) :
    φ P.c = φ P.a * (x * y + x * z + y * z) := by
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic F
inst✝¹ : Field F
inst✝ : Field K
φ : F →+* K
x y z : K
ha : P.a ≠ 0
h3 : roots (map φ P) = {x, y, z}
⊢ φ P.c = φ P.a * (x * y + x * z + y * z)

Next tactic:
injection eq_sum_three_roots ha h3
theorem d_eq_three_roots (ha : P.a ≠ 0) (h3 : (map φ P).roots = {x, y, z}) :
    φ P.d = φ P.a * -(x * y * z) := by
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic F
inst✝¹ : Field F
inst✝ : Field K
φ : F →+* K
x y z : K
ha : P.a ≠ 0
h3 : roots (map φ P) = {x, y, z}
⊢ φ P.d = φ P.a * -(x * y * z)

Next tactic:
injection eq_sum_three_roots ha h3
theorem disc_eq_prod_three_roots (ha : P.a ≠ 0) (h3 : (map φ P).roots = {x, y, z}) :
    φ P.disc = (φ P.a * φ P.a * (x - y) * (x - z) * (y - z)) ^ 2 := by
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic F
inst✝¹ : Field F
inst✝ : Field K
φ : F →+* K
x y z : K
ha : P.a ≠ 0
h3 : roots (map φ P) = {x, y, z}
⊢ φ (disc P) = (φ P.a * φ P.a * (x - y) * (x - z) * (y - z)) ^ 2

Next tactic:
simp only [disc, RingHom.map_add, RingHom.map_sub, RingHom.map_mul, map_pow]
theorem disc_eq_prod_three_roots (ha : P.a ≠ 0) (h3 : (map φ P).roots = {x, y, z}) :
    φ P.disc = (φ P.a * φ P.a * (x - y) * (x - z) * (y - z)) ^ 2 := by
  simp only [disc, RingHom.map_add, RingHom.map_sub, RingHom.map_mul, map_pow]
  -- Porting note: Replaced `simp only [RingHom.map_one, map_bit0, map_bit1]` with f4, f18, f27
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic F
inst✝¹ : Field F
inst✝ : Field K
φ : F →+* K
x y z : K
ha : P.a ≠ 0
h3 : roots (map φ P) = {x, y, z}
⊢ φ P.b ^ 2 * φ P.c ^ 2 - φ 4 * φ P.a * φ P.c ^ 3 - φ 4 * φ P.b ^ 3 * φ P.d - φ 27 * φ P.a ^ 2 * φ P.d ^ 2 +
      φ 18 * φ P.a * φ P.b * φ P.c * φ P.d =
    (φ P.a * φ P.a * (x - y) * (x - z) * (y - z)) ^ 2

Next tactic:
have f4 : φ 4 = 4 := map_natCast φ 4
theorem disc_eq_prod_three_roots (ha : P.a ≠ 0) (h3 : (map φ P).roots = {x, y, z}) :
    φ P.disc = (φ P.a * φ P.a * (x - y) * (x - z) * (y - z)) ^ 2 := by
  simp only [disc, RingHom.map_add, RingHom.map_sub, RingHom.map_mul, map_pow]
  -- Porting note: Replaced `simp only [RingHom.map_one, map_bit0, map_bit1]` with f4, f18, f27
  have f4 : φ 4 = 4 := map_natCast φ 4
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic F
inst✝¹ : Field F
inst✝ : Field K
φ : F →+* K
x y z : K
ha : P.a ≠ 0
h3 : roots (map φ P) = {x, y, z}
f4 : φ 4 = 4
⊢ φ P.b ^ 2 * φ P.c ^ 2 - φ 4 * φ P.a * φ P.c ^ 3 - φ 4 * φ P.b ^ 3 * φ P.d - φ 27 * φ P.a ^ 2 * φ P.d ^ 2 +
      φ 18 * φ P.a * φ P.b * φ P.c * φ P.d =
    (φ P.a * φ P.a * (x - y) * (x - z) * (y - z)) ^ 2

Next tactic:
have f18 : φ 18 = 18 := map_natCast φ 18
theorem disc_eq_prod_three_roots (ha : P.a ≠ 0) (h3 : (map φ P).roots = {x, y, z}) :
    φ P.disc = (φ P.a * φ P.a * (x - y) * (x - z) * (y - z)) ^ 2 := by
  simp only [disc, RingHom.map_add, RingHom.map_sub, RingHom.map_mul, map_pow]
  -- Porting note: Replaced `simp only [RingHom.map_one, map_bit0, map_bit1]` with f4, f18, f27
  have f4 : φ 4 = 4 := map_natCast φ 4
  have f18 : φ 18 = 18 := map_natCast φ 18
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic F
inst✝¹ : Field F
inst✝ : Field K
φ : F →+* K
x y z : K
ha : P.a ≠ 0
h3 : roots (map φ P) = {x, y, z}
f4 : φ 4 = 4
f18 : φ 18 = 18
⊢ φ P.b ^ 2 * φ P.c ^ 2 - φ 4 * φ P.a * φ P.c ^ 3 - φ 4 * φ P.b ^ 3 * φ P.d - φ 27 * φ P.a ^ 2 * φ P.d ^ 2 +
      φ 18 * φ P.a * φ P.b * φ P.c * φ P.d =
    (φ P.a * φ P.a * (x - y) * (x - z) * (y - z)) ^ 2

Next tactic:
have f27 : φ 27 = 27 := map_natCast φ 27
theorem disc_eq_prod_three_roots (ha : P.a ≠ 0) (h3 : (map φ P).roots = {x, y, z}) :
    φ P.disc = (φ P.a * φ P.a * (x - y) * (x - z) * (y - z)) ^ 2 := by
  simp only [disc, RingHom.map_add, RingHom.map_sub, RingHom.map_mul, map_pow]
  -- Porting note: Replaced `simp only [RingHom.map_one, map_bit0, map_bit1]` with f4, f18, f27
  have f4 : φ 4 = 4 := map_natCast φ 4
  have f18 : φ 18 = 18 := map_natCast φ 18
  have f27 : φ 27 = 27 := map_natCast φ 27
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic F
inst✝¹ : Field F
inst✝ : Field K
φ : F →+* K
x y z : K
ha : P.a ≠ 0
h3 : roots (map φ P) = {x, y, z}
f4 : φ 4 = 4
f18 : φ 18 = 18
f27 : φ 27 = 27
⊢ φ P.b ^ 2 * φ P.c ^ 2 - φ 4 * φ P.a * φ P.c ^ 3 - φ 4 * φ P.b ^ 3 * φ P.d - φ 27 * φ P.a ^ 2 * φ P.d ^ 2 +
      φ 18 * φ P.a * φ P.b * φ P.c * φ P.d =
    (φ P.a * φ P.a * (x - y) * (x - z) * (y - z)) ^ 2

Next tactic:
rw [f4, f18, f27, b_eq_three_roots ha h3, c_eq_three_roots ha h3, d_eq_three_roots ha h3]
theorem disc_eq_prod_three_roots (ha : P.a ≠ 0) (h3 : (map φ P).roots = {x, y, z}) :
    φ P.disc = (φ P.a * φ P.a * (x - y) * (x - z) * (y - z)) ^ 2 := by
  simp only [disc, RingHom.map_add, RingHom.map_sub, RingHom.map_mul, map_pow]
  -- Porting note: Replaced `simp only [RingHom.map_one, map_bit0, map_bit1]` with f4, f18, f27
  have f4 : φ 4 = 4 := map_natCast φ 4
  have f18 : φ 18 = 18 := map_natCast φ 18
  have f27 : φ 27 = 27 := map_natCast φ 27
  rw [f4, f18, f27, b_eq_three_roots ha h3, c_eq_three_roots ha h3, d_eq_three_roots ha h3]
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic F
inst✝¹ : Field F
inst✝ : Field K
φ : F →+* K
x y z : K
ha : P.a ≠ 0
h3 : roots (map φ P) = {x, y, z}
f4 : φ 4 = 4
f18 : φ 18 = 18
f27 : φ 27 = 27
⊢ (φ P.a * -(x + y + z)) ^ 2 * (φ P.a * (x * y + x * z + y * z)) ^ 2 -
            4 * φ P.a * (φ P.a * (x * y + x * z + y * z)) ^ 3 -
          4 * (φ P.a * -(x + y + z)) ^ 3 * (φ P.a * -(x * y * z)) -
        27 * φ P.a ^ 2 * (φ P.a * -(x * y * z)) ^ 2 +
      18 * φ P.a * (φ P.a * -(x + y + z)) * (φ P.a * (x * y + x * z + y * z)) * (φ P.a * -(x * y * z)) =
    (φ P.a * φ P.a * (x - y) * (x - z) * (y - z)) ^ 2

Next tactic:
ring1
theorem disc_ne_zero_iff_roots_ne (ha : P.a ≠ 0) (h3 : (map φ P).roots = {x, y, z}) :
    P.disc ≠ 0 ↔ x ≠ y ∧ x ≠ z ∧ y ≠ z := by
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic F
inst✝¹ : Field F
inst✝ : Field K
φ : F →+* K
x y z : K
ha : P.a ≠ 0
h3 : roots (map φ P) = {x, y, z}
⊢ disc P ≠ 0 ↔ x ≠ y ∧ x ≠ z ∧ y ≠ z

Next tactic:
rw [← _root_.map_ne_zero φ, disc_eq_prod_three_roots ha h3, pow_two]
theorem disc_ne_zero_iff_roots_ne (ha : P.a ≠ 0) (h3 : (map φ P).roots = {x, y, z}) :
    P.disc ≠ 0 ↔ x ≠ y ∧ x ≠ z ∧ y ≠ z := by
  rw [← _root_.map_ne_zero φ, disc_eq_prod_three_roots ha h3, pow_two]
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic F
inst✝¹ : Field F
inst✝ : Field K
φ : F →+* K
x y z : K
ha : P.a ≠ 0
h3 : roots (map φ P) = {x, y, z}
⊢ φ P.a * φ P.a * (x - y) * (x - z) * (y - z) * (φ P.a * φ P.a * (x - y) * (x - z) * (y - z)) ≠ 0 ↔
    x ≠ y ∧ x ≠ z ∧ y ≠ z

Next tactic:
simp_rw [mul_ne_zero_iff, sub_ne_zero, _root_.map_ne_zero, and_self_iff, and_iff_right ha,
    and_assoc]
theorem disc_ne_zero_iff_roots_nodup (ha : P.a ≠ 0) (h3 : (map φ P).roots = {x, y, z}) :
    P.disc ≠ 0 ↔ (map φ P).roots.Nodup := by
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic F
inst✝¹ : Field F
inst✝ : Field K
φ : F →+* K
x y z : K
ha : P.a ≠ 0
h3 : roots (map φ P) = {x, y, z}
⊢ disc P ≠ 0 ↔ Nodup (roots (map φ P))

Next tactic:
rw [disc_ne_zero_iff_roots_ne ha h3, h3]
theorem disc_ne_zero_iff_roots_nodup (ha : P.a ≠ 0) (h3 : (map φ P).roots = {x, y, z}) :
    P.disc ≠ 0 ↔ (map φ P).roots.Nodup := by
  rw [disc_ne_zero_iff_roots_ne ha h3, h3]
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic F
inst✝¹ : Field F
inst✝ : Field K
φ : F →+* K
x y z : K
ha : P.a ≠ 0
h3 : roots (map φ P) = {x, y, z}
⊢ x ≠ y ∧ x ≠ z ∧ y ≠ z ↔ Nodup {x, y, z}

Next tactic:
change _ ↔ (x ::ₘ y ::ₘ {z}).Nodup
theorem disc_ne_zero_iff_roots_nodup (ha : P.a ≠ 0) (h3 : (map φ P).roots = {x, y, z}) :
    P.disc ≠ 0 ↔ (map φ P).roots.Nodup := by
  rw [disc_ne_zero_iff_roots_ne ha h3, h3]
  change _ ↔ (x ::ₘ y ::ₘ {z}).Nodup
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic F
inst✝¹ : Field F
inst✝ : Field K
φ : F →+* K
x y z : K
ha : P.a ≠ 0
h3 : roots (map φ P) = {x, y, z}
⊢ x ≠ y ∧ x ≠ z ∧ y ≠ z ↔ Nodup (x ::ₘ y ::ₘ {z})

Next tactic:
rw [nodup_cons, nodup_cons, mem_cons, mem_singleton, mem_singleton]
theorem disc_ne_zero_iff_roots_nodup (ha : P.a ≠ 0) (h3 : (map φ P).roots = {x, y, z}) :
    P.disc ≠ 0 ↔ (map φ P).roots.Nodup := by
  rw [disc_ne_zero_iff_roots_ne ha h3, h3]
  change _ ↔ (x ::ₘ y ::ₘ {z}).Nodup
  rw [nodup_cons, nodup_cons, mem_cons, mem_singleton, mem_singleton]
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic F
inst✝¹ : Field F
inst✝ : Field K
φ : F →+* K
x y z : K
ha : P.a ≠ 0
h3 : roots (map φ P) = {x, y, z}
⊢ x ≠ y ∧ x ≠ z ∧ y ≠ z ↔ ¬(x = y ∨ x = z) ∧ ¬y = z ∧ Nodup {z}

Next tactic:
simp only [nodup_singleton]
theorem disc_ne_zero_iff_roots_nodup (ha : P.a ≠ 0) (h3 : (map φ P).roots = {x, y, z}) :
    P.disc ≠ 0 ↔ (map φ P).roots.Nodup := by
  rw [disc_ne_zero_iff_roots_ne ha h3, h3]
  change _ ↔ (x ::ₘ y ::ₘ {z}).Nodup
  rw [nodup_cons, nodup_cons, mem_cons, mem_singleton, mem_singleton]
  simp only [nodup_singleton]
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic F
inst✝¹ : Field F
inst✝ : Field K
φ : F →+* K
x y z : K
ha : P.a ≠ 0
h3 : roots (map φ P) = {x, y, z}
⊢ x ≠ y ∧ x ≠ z ∧ y ≠ z ↔ ¬(x = y ∨ x = z) ∧ ¬y = z ∧ True

Next tactic:
tauto
theorem card_roots_of_disc_ne_zero [DecidableEq K] (ha : P.a ≠ 0) (h3 : (map φ P).roots = {x, y, z})
    (hd : P.disc ≠ 0) : (map φ P).roots.toFinset.card = 3 := by
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic F
inst✝² : Field F
inst✝¹ : Field K
φ : F →+* K
x y z : K
inst✝ : DecidableEq K
ha : P.a ≠ 0
h3 : roots (map φ P) = {x, y, z}
hd : disc P ≠ 0
⊢ Finset.card (toFinset (roots (map φ P))) = 3

Next tactic:
rw [toFinset_card_of_nodup <| (disc_ne_zero_iff_roots_nodup ha h3).mp hd,
    ← splits_iff_card_roots ha, splits_iff_roots_eq_three ha]
theorem card_roots_of_disc_ne_zero [DecidableEq K] (ha : P.a ≠ 0) (h3 : (map φ P).roots = {x, y, z})
    (hd : P.disc ≠ 0) : (map φ P).roots.toFinset.card = 3 := by
  rw [toFinset_card_of_nodup <| (disc_ne_zero_iff_roots_nodup ha h3).mp hd,
    ← splits_iff_card_roots ha, splits_iff_roots_eq_three ha]
  

Proof state:
R : Type u_1
S : Type u_2
F : Type u_3
K : Type u_4
P : Cubic F
inst✝² : Field F
inst✝¹ : Field K
φ : F →+* K
x y z : K
inst✝ : DecidableEq K
ha : P.a ≠ 0
h3 : roots (map φ P) = {x, y, z}
hd : disc P ≠ 0
⊢ ∃ x y z, roots (map φ P) = {x, y, z}

Next tactic:
exact ⟨x, ⟨y, ⟨z, h3⟩⟩⟩
noncomputable instance : DivInvMonoid M :=
  { show Monoid M by 

Proof state:
n' : Type u_1
inst✝² : DecidableEq n'
inst✝¹ : Fintype n'
R : Type u_2
inst✝ : CommRing R
⊢ Monoid M

Next tactic:
infer_instance
noncomputable instance : DivInvMonoid M :=
  { show Monoid M by infer_instance, show Inv M by 

Proof state:
n' : Type u_1
inst✝² : DecidableEq n'
inst✝¹ : Fintype n'
R : Type u_2
inst✝ : CommRing R
src✝ : Monoid M :=
  let_fun this := inferInstance;
  this
⊢ Inv M

Next tactic:
infer_instance
@[simp]
theorem inv_pow' (A : M) (n : ℕ) : A⁻¹ ^ n = (A ^ n)⁻¹ := by
  

Proof state:
n' : Type u_1
inst✝² : DecidableEq n'
inst✝¹ : Fintype n'
R : Type u_2
inst✝ : CommRing R
A : M
n : ℕ
⊢ A⁻¹ ^ n = (A ^ n)⁻¹

Next tactic:
induction' n with n ih
@[simp]
theorem inv_pow' (A : M) (n : ℕ) : A⁻¹ ^ n = (A ^ n)⁻¹ := by
  induction' n with n ih
  · 

Proof state:
case zero
n' : Type u_1
inst✝² : DecidableEq n'
inst✝¹ : Fintype n'
R : Type u_2
inst✝ : CommRing R
A : M
⊢ A⁻¹ ^ Nat.zero = (A ^ Nat.zero)⁻¹

Next tactic:
simp
@[simp]
theorem inv_pow' (A : M) (n : ℕ) : A⁻¹ ^ n = (A ^ n)⁻¹ := by
  induction' n with n ih
  · simp
  · 

Proof state:
case succ
n' : Type u_1
inst✝² : DecidableEq n'
inst✝¹ : Fintype n'
R : Type u_2
inst✝ : CommRing R
A : M
n : ℕ
ih : A⁻¹ ^ n = (A ^ n)⁻¹
⊢ A⁻¹ ^ Nat.succ n = (A ^ Nat.succ n)⁻¹

Next tactic:
rw [pow_succ A, mul_inv_rev, ← ih, ← pow_succ']
theorem pow_sub' (A : M) {m n : ℕ} (ha : IsUnit A.det) (h : n ≤ m) :
    A ^ (m - n) = A ^ m * (A ^ n)⁻¹ := by
  

Proof state:
n' : Type u_1
inst✝² : DecidableEq n'
inst✝¹ : Fintype n'
R : Type u_2
inst✝ : CommRing R
A : M
m n : ℕ
ha : IsUnit (det A)
h : n ≤ m
⊢ A ^ (m - n) = A ^ m * (A ^ n)⁻¹

Next tactic:
rw [← tsub_add_cancel_of_le h, pow_add, Matrix.mul_assoc, mul_nonsing_inv,
    tsub_add_cancel_of_le h, Matrix.mul_one]
theorem pow_sub' (A : M) {m n : ℕ} (ha : IsUnit A.det) (h : n ≤ m) :
    A ^ (m - n) = A ^ m * (A ^ n)⁻¹ := by
  rw [← tsub_add_cancel_of_le h, pow_add, Matrix.mul_assoc, mul_nonsing_inv,
    tsub_add_cancel_of_le h, Matrix.mul_one]
  

Proof state:
case h
n' : Type u_1
inst✝² : DecidableEq n'
inst✝¹ : Fintype n'
R : Type u_2
inst✝ : CommRing R
A : M
m n : ℕ
ha : IsUnit (det A)
h : n ≤ m
⊢ IsUnit (det (A ^ n))

Next tactic:
simpa using ha.pow n
theorem pow_inv_comm' (A : M) (m n : ℕ) : A⁻¹ ^ m * A ^ n = A ^ n * A⁻¹ ^ m := by
  

Proof state:
n' : Type u_1
inst✝² : DecidableEq n'
inst✝¹ : Fintype n'
R : Type u_2
inst✝ : CommRing R
A : M
m n : ℕ
⊢ A⁻¹ ^ m * A ^ n = A ^ n * A⁻¹ ^ m

Next tactic:
induction' n with n IH generalizing m
theorem pow_inv_comm' (A : M) (m n : ℕ) : A⁻¹ ^ m * A ^ n = A ^ n * A⁻¹ ^ m := by
  induction' n with n IH generalizing m
  · 

Proof state:
case zero
n' : Type u_1
inst✝² : DecidableEq n'
inst✝¹ : Fintype n'
R : Type u_2
inst✝ : CommRing R
A : M
m : ℕ
⊢ A⁻¹ ^ m * A ^ Nat.zero = A ^ Nat.zero * A⁻¹ ^ m

Next tactic:
simp
theorem pow_inv_comm' (A : M) (m n : ℕ) : A⁻¹ ^ m * A ^ n = A ^ n * A⁻¹ ^ m := by
  induction' n with n IH generalizing m
  · simp
  

Proof state:
case succ
n' : Type u_1
inst✝² : DecidableEq n'
inst✝¹ : Fintype n'
R : Type u_2
inst✝ : CommRing R
A : M
n : ℕ
IH : ∀ (m : ℕ), A⁻¹ ^ m * A ^ n = A ^ n * A⁻¹ ^ m
m : ℕ
⊢ A⁻¹ ^ m * A ^ Nat.succ n = A ^ Nat.succ n * A⁻¹ ^ m

Next tactic:
cases' m with m m
theorem pow_inv_comm' (A : M) (m n : ℕ) : A⁻¹ ^ m * A ^ n = A ^ n * A⁻¹ ^ m := by
  induction' n with n IH generalizing m
  · simp
  cases' m with m m
  · 

Proof state:
case succ.zero
n' : Type u_1
inst✝² : DecidableEq n'
inst✝¹ : Fintype n'
R : Type u_2
inst✝ : CommRing R
A : M
n : ℕ
IH : ∀ (m : ℕ), A⁻¹ ^ m * A ^ n = A ^ n * A⁻¹ ^ m
⊢ A⁻¹ ^ Nat.zero * A ^ Nat.succ n = A ^ Nat.succ n * A⁻¹ ^ Nat.zero

Next tactic:
simp
theorem pow_inv_comm' (A : M) (m n : ℕ) : A⁻¹ ^ m * A ^ n = A ^ n * A⁻¹ ^ m := by
  induction' n with n IH generalizing m
  · simp
  cases' m with m m
  · simp
  

Proof state:
case succ.succ
n' : Type u_1
inst✝² : DecidableEq n'
inst✝¹ : Fintype n'
R : Type u_2
inst✝ : CommRing R
A : M
n : ℕ
IH : ∀ (m : ℕ), A⁻¹ ^ m * A ^ n = A ^ n * A⁻¹ ^ m
m : ℕ
⊢ A⁻¹ ^ Nat.succ m * A ^ Nat.succ n = A ^ Nat.succ n * A⁻¹ ^ Nat.succ m

Next tactic:
rcases nonsing_inv_cancel_or_zero A with (⟨h, h'⟩ | h)
theorem pow_inv_comm' (A : M) (m n : ℕ) : A⁻¹ ^ m * A ^ n = A ^ n * A⁻¹ ^ m := by
  induction' n with n IH generalizing m
  · simp
  cases' m with m m
  · simp
  rcases nonsing_inv_cancel_or_zero A with (⟨h, h'⟩ | h)
  · 

Proof state:
case succ.succ.inl.intro
n' : Type u_1
inst✝² : DecidableEq n'
inst✝¹ : Fintype n'
R : Type u_2
inst✝ : CommRing R
A : M
n : ℕ
IH : ∀ (m : ℕ), A⁻¹ ^ m * A ^ n = A ^ n * A⁻¹ ^ m
m : ℕ
h : A⁻¹ * A = 1
h' : A * A⁻¹ = 1
⊢ A⁻¹ ^ Nat.succ m * A ^ Nat.succ n = A ^ Nat.succ n * A⁻¹ ^ Nat.succ m

Next tactic:
simp only [Nat.succ_eq_add_one]
theorem pow_inv_comm' (A : M) (m n : ℕ) : A⁻¹ ^ m * A ^ n = A ^ n * A⁻¹ ^ m := by
  induction' n with n IH generalizing m
  · simp
  cases' m with m m
  · simp
  rcases nonsing_inv_cancel_or_zero A with (⟨h, h'⟩ | h)
  · simp only [Nat.succ_eq_add_one]
    

Proof state:
case succ.succ.inl.intro
n' : Type u_1
inst✝² : DecidableEq n'
inst✝¹ : Fintype n'
R : Type u_2
inst✝ : CommRing R
A : M
n : ℕ
IH : ∀ (m : ℕ), A⁻¹ ^ m * A ^ n = A ^ n * A⁻¹ ^ m
m : ℕ
h : A⁻¹ * A = 1
h' : A * A⁻¹ = 1
⊢ A⁻¹ ^ (m + 1) * A ^ (n + 1) = A ^ (n + 1) * A⁻¹ ^ (m + 1)

Next tactic:
calc
       A⁻¹ ^ (m + 1) * A ^ (n + 1) = A⁻¹ ^ m * (A⁻¹ * A) * A ^ n := by
        simp only [pow_succ' A⁻¹, pow_succ A, Matrix.mul_assoc]
      _ = A ^ n * A⁻¹ ^ m := by simp only [h, Matrix.mul_one, Matrix.one_mul, IH m]
      _ = A ^ n * (A * A⁻¹) * A⁻¹ ^ m := by simp only [h', Matrix.mul_one, Matrix.one_mul]
      _ = A ^ (n + 1) * A⁻¹ ^ (m + 1) := by
        simp only [pow_succ' A, pow_succ A⁻¹, Matrix.mul_assoc]
theorem pow_inv_comm' (A : M) (m n : ℕ) : A⁻¹ ^ m * A ^ n = A ^ n * A⁻¹ ^ m := by
  induction' n with n IH generalizing m
  · simp
  cases' m with m m
  · simp
  rcases nonsing_inv_cancel_or_zero A with (⟨h, h'⟩ | h)
  · simp only [Nat.succ_eq_add_one]
    calc
       A⁻¹ ^ (m + 1) * A ^ (n + 1) = A⁻¹ ^ m * (A⁻¹ * A) * A ^ n := by
        

Proof state:
n' : Type u_1
inst✝² : DecidableEq n'
inst✝¹ : Fintype n'
R : Type u_2
inst✝ : CommRing R
A : M
n : ℕ
IH : ∀ (m : ℕ), A⁻¹ ^ m * A ^ n = A ^ n * A⁻¹ ^ m
m : ℕ
h : A⁻¹ * A = 1
h' : A * A⁻¹ = 1
⊢ A⁻¹ ^ (m + 1) * A ^ (n + 1) = A⁻¹ ^ m * (A⁻¹ * A) * A ^ n

Next tactic:
simp only [pow_succ' A⁻¹, pow_succ A, Matrix.mul_assoc]
theorem pow_inv_comm' (A : M) (m n : ℕ) : A⁻¹ ^ m * A ^ n = A ^ n * A⁻¹ ^ m := by
  induction' n with n IH generalizing m
  · simp
  cases' m with m m
  · simp
  rcases nonsing_inv_cancel_or_zero A with (⟨h, h'⟩ | h)
  · simp only [Nat.succ_eq_add_one]
    calc
       A⁻¹ ^ (m + 1) * A ^ (n + 1) = A⁻¹ ^ m * (A⁻¹ * A) * A ^ n := by
        simp only [pow_succ' A⁻¹, pow_succ A, Matrix.mul_assoc]
      _ = A ^ n * A⁻¹ ^ m := by 

Proof state:
n' : Type u_1
inst✝² : DecidableEq n'
inst✝¹ : Fintype n'
R : Type u_2
inst✝ : CommRing R
A : M
n : ℕ
IH : ∀ (m : ℕ), A⁻¹ ^ m * A ^ n = A ^ n * A⁻¹ ^ m
m : ℕ
h : A⁻¹ * A = 1
h' : A * A⁻¹ = 1
⊢ A⁻¹ ^ m * (A⁻¹ * A) * A ^ n = A ^ n * A⁻¹ ^ m

Next tactic:
simp only [h, Matrix.mul_one, Matrix.one_mul, IH m]