l3lab/ntp-mathlib huggingface dataset:
/-- An irreducible polynomial of prime degree with 1-3 non-real roots has full Galois group. -/
theorem galActionHom_bijective_of_prime_degree' {p : ℚ[X]} (p_irr : Irreducible p)
    (p_deg : p.natDegree.Prime)
    (p_roots1 : Fintype.card (p.rootSet ℝ) + 1 ≤ Fintype.card (p.rootSet ℂ))
    (p_roots2 : Fintype.card (p.rootSet ℂ) ≤ Fintype.card (p.rootSet ℝ) + 3) :
    Function.Bijective (galActionHom p ℂ) := by
  apply galActionHom_bijective_of_prime_degree p_irr p_deg
  let n := (galActionHom p ℂ (restrict p ℂ (Complex.conjAe.restrictScalars ℚ))).support.card
  have hn : 2 ∣ n :=
    Equiv.Perm.two_dvd_card_support
      (by
         

Proof state:
F : Type u_1
inst✝² : Field F
p✝ q : F[X]
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
p : ℚ[X]
p_irr : Irreducible p
p_deg : Nat.Prime (natDegree p)
p_roots1 : Fintype.card ↑(rootSet p ℝ) + 1 ≤ Fintype.card ↑(rootSet p ℂ)
p_roots2 : Fintype.card ↑(rootSet p ℂ) ≤ Fintype.card ↑(rootSet p ℝ) + 3
n : ℕ :=
  Finset.card (Equiv.Perm.support ((galActionHom p ℂ) ((restrict p ℂ) (AlgEquiv.restrictScalars ℚ Complex.conjAe))))
⊢ (galActionHom p ℂ) ((restrict p ℂ) (AlgEquiv.restrictScalars ℚ Complex.conjAe)) ^ 2 = 1

Next tactic:
rw [← MonoidHom.map_pow, ← MonoidHom.map_pow,
          show AlgEquiv.restrictScalars ℚ Complex.conjAe ^ 2 = 1 from
            AlgEquiv.ext Complex.conj_conj,
          MonoidHom.map_one, MonoidHom.map_one]
/-- An irreducible polynomial of prime degree with 1-3 non-real roots has full Galois group. -/
theorem galActionHom_bijective_of_prime_degree' {p : ℚ[X]} (p_irr : Irreducible p)
    (p_deg : p.natDegree.Prime)
    (p_roots1 : Fintype.card (p.rootSet ℝ) + 1 ≤ Fintype.card (p.rootSet ℂ))
    (p_roots2 : Fintype.card (p.rootSet ℂ) ≤ Fintype.card (p.rootSet ℝ) + 3) :
    Function.Bijective (galActionHom p ℂ) := by
  apply galActionHom_bijective_of_prime_degree p_irr p_deg
  let n := (galActionHom p ℂ (restrict p ℂ (Complex.conjAe.restrictScalars ℚ))).support.card
  have hn : 2 ∣ n :=
    Equiv.Perm.two_dvd_card_support
      (by
         rw [← MonoidHom.map_pow, ← MonoidHom.map_pow,
          show AlgEquiv.restrictScalars ℚ Complex.conjAe ^ 2 = 1 from
            AlgEquiv.ext Complex.conj_conj,
          MonoidHom.map_one, MonoidHom.map_one])
  

Proof state:
F : Type u_1
inst✝² : Field F
p✝ q : F[X]
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
p : ℚ[X]
p_irr : Irreducible p
p_deg : Nat.Prime (natDegree p)
p_roots1 : Fintype.card ↑(rootSet p ℝ) + 1 ≤ Fintype.card ↑(rootSet p ℂ)
p_roots2 : Fintype.card ↑(rootSet p ℂ) ≤ Fintype.card ↑(rootSet p ℝ) + 3
n : ℕ :=
  Finset.card (Equiv.Perm.support ((galActionHom p ℂ) ((restrict p ℂ) (AlgEquiv.restrictScalars ℚ Complex.conjAe))))
hn : 2 ∣ n
⊢ Fintype.card ↑(rootSet p ℂ) = Fintype.card ↑(rootSet p ℝ) + 2

Next tactic:
have key := card_complex_roots_eq_card_real_add_card_not_gal_inv p
/-- An irreducible polynomial of prime degree with 1-3 non-real roots has full Galois group. -/
theorem galActionHom_bijective_of_prime_degree' {p : ℚ[X]} (p_irr : Irreducible p)
    (p_deg : p.natDegree.Prime)
    (p_roots1 : Fintype.card (p.rootSet ℝ) + 1 ≤ Fintype.card (p.rootSet ℂ))
    (p_roots2 : Fintype.card (p.rootSet ℂ) ≤ Fintype.card (p.rootSet ℝ) + 3) :
    Function.Bijective (galActionHom p ℂ) := by
  apply galActionHom_bijective_of_prime_degree p_irr p_deg
  let n := (galActionHom p ℂ (restrict p ℂ (Complex.conjAe.restrictScalars ℚ))).support.card
  have hn : 2 ∣ n :=
    Equiv.Perm.two_dvd_card_support
      (by
         rw [← MonoidHom.map_pow, ← MonoidHom.map_pow,
          show AlgEquiv.restrictScalars ℚ Complex.conjAe ^ 2 = 1 from
            AlgEquiv.ext Complex.conj_conj,
          MonoidHom.map_one, MonoidHom.map_one])
  have key := card_complex_roots_eq_card_real_add_card_not_gal_inv p
  

Proof state:
F : Type u_1
inst✝² : Field F
p✝ q : F[X]
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
p : ℚ[X]
p_irr : Irreducible p
p_deg : Nat.Prime (natDegree p)
p_roots1 : Fintype.card ↑(rootSet p ℝ) + 1 ≤ Fintype.card ↑(rootSet p ℂ)
p_roots2 : Fintype.card ↑(rootSet p ℂ) ≤ Fintype.card ↑(rootSet p ℝ) + 3
n : ℕ :=
  Finset.card (Equiv.Perm.support ((galActionHom p ℂ) ((restrict p ℂ) (AlgEquiv.restrictScalars ℚ Complex.conjAe))))
hn : 2 ∣ n
key :
  Finset.card (Set.toFinset (rootSet p ℂ)) =
    Finset.card (Set.toFinset (rootSet p ℝ)) +
      Finset.card (Equiv.Perm.support ((galActionHom p ℂ) ((restrict p ℂ) (AlgEquiv.restrictScalars ℚ Complex.conjAe))))
⊢ Fintype.card ↑(rootSet p ℂ) = Fintype.card ↑(rootSet p ℝ) + 2

Next tactic:
simp_rw [Set.toFinset_card] at key
/-- An irreducible polynomial of prime degree with 1-3 non-real roots has full Galois group. -/
theorem galActionHom_bijective_of_prime_degree' {p : ℚ[X]} (p_irr : Irreducible p)
    (p_deg : p.natDegree.Prime)
    (p_roots1 : Fintype.card (p.rootSet ℝ) + 1 ≤ Fintype.card (p.rootSet ℂ))
    (p_roots2 : Fintype.card (p.rootSet ℂ) ≤ Fintype.card (p.rootSet ℝ) + 3) :
    Function.Bijective (galActionHom p ℂ) := by
  apply galActionHom_bijective_of_prime_degree p_irr p_deg
  let n := (galActionHom p ℂ (restrict p ℂ (Complex.conjAe.restrictScalars ℚ))).support.card
  have hn : 2 ∣ n :=
    Equiv.Perm.two_dvd_card_support
      (by
         rw [← MonoidHom.map_pow, ← MonoidHom.map_pow,
          show AlgEquiv.restrictScalars ℚ Complex.conjAe ^ 2 = 1 from
            AlgEquiv.ext Complex.conj_conj,
          MonoidHom.map_one, MonoidHom.map_one])
  have key := card_complex_roots_eq_card_real_add_card_not_gal_inv p
  simp_rw [Set.toFinset_card] at key
  

Proof state:
F : Type u_1
inst✝² : Field F
p✝ q : F[X]
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
p : ℚ[X]
p_irr : Irreducible p
p_deg : Nat.Prime (natDegree p)
p_roots1 : Fintype.card ↑(rootSet p ℝ) + 1 ≤ Fintype.card ↑(rootSet p ℂ)
p_roots2 : Fintype.card ↑(rootSet p ℂ) ≤ Fintype.card ↑(rootSet p ℝ) + 3
n : ℕ :=
  Finset.card (Equiv.Perm.support ((galActionHom p ℂ) ((restrict p ℂ) (AlgEquiv.restrictScalars ℚ Complex.conjAe))))
hn : 2 ∣ n
key :
  Fintype.card ↑(rootSet p ℂ) =
    Fintype.card ↑(rootSet p ℝ) +
      Finset.card (Equiv.Perm.support ((galActionHom p ℂ) ((restrict p ℂ) (AlgEquiv.restrictScalars ℚ Complex.conjAe))))
⊢ Fintype.card ↑(rootSet p ℂ) = Fintype.card ↑(rootSet p ℝ) + 2

Next tactic:
rw [key, add_le_add_iff_left] at p_roots1 p_roots2
/-- An irreducible polynomial of prime degree with 1-3 non-real roots has full Galois group. -/
theorem galActionHom_bijective_of_prime_degree' {p : ℚ[X]} (p_irr : Irreducible p)
    (p_deg : p.natDegree.Prime)
    (p_roots1 : Fintype.card (p.rootSet ℝ) + 1 ≤ Fintype.card (p.rootSet ℂ))
    (p_roots2 : Fintype.card (p.rootSet ℂ) ≤ Fintype.card (p.rootSet ℝ) + 3) :
    Function.Bijective (galActionHom p ℂ) := by
  apply galActionHom_bijective_of_prime_degree p_irr p_deg
  let n := (galActionHom p ℂ (restrict p ℂ (Complex.conjAe.restrictScalars ℚ))).support.card
  have hn : 2 ∣ n :=
    Equiv.Perm.two_dvd_card_support
      (by
         rw [← MonoidHom.map_pow, ← MonoidHom.map_pow,
          show AlgEquiv.restrictScalars ℚ Complex.conjAe ^ 2 = 1 from
            AlgEquiv.ext Complex.conj_conj,
          MonoidHom.map_one, MonoidHom.map_one])
  have key := card_complex_roots_eq_card_real_add_card_not_gal_inv p
  simp_rw [Set.toFinset_card] at key
  rw [key, add_le_add_iff_left] at p_roots1 p_roots2
  

Proof state:
F : Type u_1
inst✝² : Field F
p✝ q : F[X]
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
p : ℚ[X]
p_irr : Irreducible p
p_deg : Nat.Prime (natDegree p)
p_roots1 :
  1 ≤ Finset.card (Equiv.Perm.support ((galActionHom p ℂ) ((restrict p ℂ) (AlgEquiv.restrictScalars ℚ Complex.conjAe))))
p_roots2 :
  Finset.card (Equiv.Perm.support ((galActionHom p ℂ) ((restrict p ℂ) (AlgEquiv.restrictScalars ℚ Complex.conjAe)))) ≤ 3
n : ℕ :=
  Finset.card (Equiv.Perm.support ((galActionHom p ℂ) ((restrict p ℂ) (AlgEquiv.restrictScalars ℚ Complex.conjAe))))
hn : 2 ∣ n
key :
  Fintype.card ↑(rootSet p ℂ) =
    Fintype.card ↑(rootSet p ℝ) +
      Finset.card (Equiv.Perm.support ((galActionHom p ℂ) ((restrict p ℂ) (AlgEquiv.restrictScalars ℚ Complex.conjAe))))
⊢ Fintype.card ↑(rootSet p ℂ) = Fintype.card ↑(rootSet p ℝ) + 2

Next tactic:
rw [key, add_right_inj]
/-- An irreducible polynomial of prime degree with 1-3 non-real roots has full Galois group. -/
theorem galActionHom_bijective_of_prime_degree' {p : ℚ[X]} (p_irr : Irreducible p)
    (p_deg : p.natDegree.Prime)
    (p_roots1 : Fintype.card (p.rootSet ℝ) + 1 ≤ Fintype.card (p.rootSet ℂ))
    (p_roots2 : Fintype.card (p.rootSet ℂ) ≤ Fintype.card (p.rootSet ℝ) + 3) :
    Function.Bijective (galActionHom p ℂ) := by
  apply galActionHom_bijective_of_prime_degree p_irr p_deg
  let n := (galActionHom p ℂ (restrict p ℂ (Complex.conjAe.restrictScalars ℚ))).support.card
  have hn : 2 ∣ n :=
    Equiv.Perm.two_dvd_card_support
      (by
         rw [← MonoidHom.map_pow, ← MonoidHom.map_pow,
          show AlgEquiv.restrictScalars ℚ Complex.conjAe ^ 2 = 1 from
            AlgEquiv.ext Complex.conj_conj,
          MonoidHom.map_one, MonoidHom.map_one])
  have key := card_complex_roots_eq_card_real_add_card_not_gal_inv p
  simp_rw [Set.toFinset_card] at key
  rw [key, add_le_add_iff_left] at p_roots1 p_roots2
  rw [key, add_right_inj]
  

Proof state:
F : Type u_1
inst✝² : Field F
p✝ q : F[X]
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
p : ℚ[X]
p_irr : Irreducible p
p_deg : Nat.Prime (natDegree p)
p_roots1 :
  1 ≤ Finset.card (Equiv.Perm.support ((galActionHom p ℂ) ((restrict p ℂ) (AlgEquiv.restrictScalars ℚ Complex.conjAe))))
p_roots2 :
  Finset.card (Equiv.Perm.support ((galActionHom p ℂ) ((restrict p ℂ) (AlgEquiv.restrictScalars ℚ Complex.conjAe)))) ≤ 3
n : ℕ :=
  Finset.card (Equiv.Perm.support ((galActionHom p ℂ) ((restrict p ℂ) (AlgEquiv.restrictScalars ℚ Complex.conjAe))))
hn : 2 ∣ n
key :
  Fintype.card ↑(rootSet p ℂ) =
    Fintype.card ↑(rootSet p ℝ) +
      Finset.card (Equiv.Perm.support ((galActionHom p ℂ) ((restrict p ℂ) (AlgEquiv.restrictScalars ℚ Complex.conjAe))))
⊢ Finset.card (Equiv.Perm.support ((galActionHom p ℂ) ((restrict p ℂ) (AlgEquiv.restrictScalars ℚ Complex.conjAe)))) = 2

Next tactic:
suffices ∀ m : ℕ, 2 ∣ m → 1 ≤ m → m ≤ 3 → m = 2 by exact this n hn p_roots1 p_roots2
/-- An irreducible polynomial of prime degree with 1-3 non-real roots has full Galois group. -/
theorem galActionHom_bijective_of_prime_degree' {p : ℚ[X]} (p_irr : Irreducible p)
    (p_deg : p.natDegree.Prime)
    (p_roots1 : Fintype.card (p.rootSet ℝ) + 1 ≤ Fintype.card (p.rootSet ℂ))
    (p_roots2 : Fintype.card (p.rootSet ℂ) ≤ Fintype.card (p.rootSet ℝ) + 3) :
    Function.Bijective (galActionHom p ℂ) := by
  apply galActionHom_bijective_of_prime_degree p_irr p_deg
  let n := (galActionHom p ℂ (restrict p ℂ (Complex.conjAe.restrictScalars ℚ))).support.card
  have hn : 2 ∣ n :=
    Equiv.Perm.two_dvd_card_support
      (by
         rw [← MonoidHom.map_pow, ← MonoidHom.map_pow,
          show AlgEquiv.restrictScalars ℚ Complex.conjAe ^ 2 = 1 from
            AlgEquiv.ext Complex.conj_conj,
          MonoidHom.map_one, MonoidHom.map_one])
  have key := card_complex_roots_eq_card_real_add_card_not_gal_inv p
  simp_rw [Set.toFinset_card] at key
  rw [key, add_le_add_iff_left] at p_roots1 p_roots2
  rw [key, add_right_inj]
  suffices ∀ m : ℕ, 2 ∣ m → 1 ≤ m → m ≤ 3 → m = 2 by 

Proof state:
F : Type u_1
inst✝² : Field F
p✝ q : F[X]
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
p : ℚ[X]
p_irr : Irreducible p
p_deg : Nat.Prime (natDegree p)
p_roots1 :
  1 ≤ Finset.card (Equiv.Perm.support ((galActionHom p ℂ) ((restrict p ℂ) (AlgEquiv.restrictScalars ℚ Complex.conjAe))))
p_roots2 :
  Finset.card (Equiv.Perm.support ((galActionHom p ℂ) ((restrict p ℂ) (AlgEquiv.restrictScalars ℚ Complex.conjAe)))) ≤ 3
n : ℕ :=
  Finset.card (Equiv.Perm.support ((galActionHom p ℂ) ((restrict p ℂ) (AlgEquiv.restrictScalars ℚ Complex.conjAe))))
hn : 2 ∣ n
key :
  Fintype.card ↑(rootSet p ℂ) =
    Fintype.card ↑(rootSet p ℝ) +
      Finset.card (Equiv.Perm.support ((galActionHom p ℂ) ((restrict p ℂ) (AlgEquiv.restrictScalars ℚ Complex.conjAe))))
this : ∀ (m : ℕ), 2 ∣ m → 1 ≤ m → m ≤ 3 → m = 2
⊢ Finset.card (Equiv.Perm.support ((galActionHom p ℂ) ((restrict p ℂ) (AlgEquiv.restrictScalars ℚ Complex.conjAe)))) = 2

Next tactic:
exact this n hn p_roots1 p_roots2
/-- An irreducible polynomial of prime degree with 1-3 non-real roots has full Galois group. -/
theorem galActionHom_bijective_of_prime_degree' {p : ℚ[X]} (p_irr : Irreducible p)
    (p_deg : p.natDegree.Prime)
    (p_roots1 : Fintype.card (p.rootSet ℝ) + 1 ≤ Fintype.card (p.rootSet ℂ))
    (p_roots2 : Fintype.card (p.rootSet ℂ) ≤ Fintype.card (p.rootSet ℝ) + 3) :
    Function.Bijective (galActionHom p ℂ) := by
  apply galActionHom_bijective_of_prime_degree p_irr p_deg
  let n := (galActionHom p ℂ (restrict p ℂ (Complex.conjAe.restrictScalars ℚ))).support.card
  have hn : 2 ∣ n :=
    Equiv.Perm.two_dvd_card_support
      (by
         rw [← MonoidHom.map_pow, ← MonoidHom.map_pow,
          show AlgEquiv.restrictScalars ℚ Complex.conjAe ^ 2 = 1 from
            AlgEquiv.ext Complex.conj_conj,
          MonoidHom.map_one, MonoidHom.map_one])
  have key := card_complex_roots_eq_card_real_add_card_not_gal_inv p
  simp_rw [Set.toFinset_card] at key
  rw [key, add_le_add_iff_left] at p_roots1 p_roots2
  rw [key, add_right_inj]
  suffices ∀ m : ℕ, 2 ∣ m → 1 ≤ m → m ≤ 3 → m = 2 by exact this n hn p_roots1 p_roots2
  

Proof state:
F : Type u_1
inst✝² : Field F
p✝ q : F[X]
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
p : ℚ[X]
p_irr : Irreducible p
p_deg : Nat.Prime (natDegree p)
p_roots1 :
  1 ≤ Finset.card (Equiv.Perm.support ((galActionHom p ℂ) ((restrict p ℂ) (AlgEquiv.restrictScalars ℚ Complex.conjAe))))
p_roots2 :
  Finset.card (Equiv.Perm.support ((galActionHom p ℂ) ((restrict p ℂ) (AlgEquiv.restrictScalars ℚ Complex.conjAe)))) ≤ 3
n : ℕ :=
  Finset.card (Equiv.Perm.support ((galActionHom p ℂ) ((restrict p ℂ) (AlgEquiv.restrictScalars ℚ Complex.conjAe))))
hn : 2 ∣ n
key :
  Fintype.card ↑(rootSet p ℂ) =
    Fintype.card ↑(rootSet p ℝ) +
      Finset.card (Equiv.Perm.support ((galActionHom p ℂ) ((restrict p ℂ) (AlgEquiv.restrictScalars ℚ Complex.conjAe))))
⊢ ∀ (m : ℕ), 2 ∣ m → 1 ≤ m → m ≤ 3 → m = 2

Next tactic:
rintro m ⟨k, rfl⟩ h2 h3
/-- An irreducible polynomial of prime degree with 1-3 non-real roots has full Galois group. -/
theorem galActionHom_bijective_of_prime_degree' {p : ℚ[X]} (p_irr : Irreducible p)
    (p_deg : p.natDegree.Prime)
    (p_roots1 : Fintype.card (p.rootSet ℝ) + 1 ≤ Fintype.card (p.rootSet ℂ))
    (p_roots2 : Fintype.card (p.rootSet ℂ) ≤ Fintype.card (p.rootSet ℝ) + 3) :
    Function.Bijective (galActionHom p ℂ) := by
  apply galActionHom_bijective_of_prime_degree p_irr p_deg
  let n := (galActionHom p ℂ (restrict p ℂ (Complex.conjAe.restrictScalars ℚ))).support.card
  have hn : 2 ∣ n :=
    Equiv.Perm.two_dvd_card_support
      (by
         rw [← MonoidHom.map_pow, ← MonoidHom.map_pow,
          show AlgEquiv.restrictScalars ℚ Complex.conjAe ^ 2 = 1 from
            AlgEquiv.ext Complex.conj_conj,
          MonoidHom.map_one, MonoidHom.map_one])
  have key := card_complex_roots_eq_card_real_add_card_not_gal_inv p
  simp_rw [Set.toFinset_card] at key
  rw [key, add_le_add_iff_left] at p_roots1 p_roots2
  rw [key, add_right_inj]
  suffices ∀ m : ℕ, 2 ∣ m → 1 ≤ m → m ≤ 3 → m = 2 by exact this n hn p_roots1 p_roots2
  rintro m ⟨k, rfl⟩ h2 h3
  

Proof state:
case intro
F : Type u_1
inst✝² : Field F
p✝ q : F[X]
E : Type u_2
inst✝¹ : Field E
inst✝ : Algebra F E
p : ℚ[X]
p_irr : Irreducible p
p_deg : Nat.Prime (natDegree p)
p_roots1 :
  1 ≤ Finset.card (Equiv.Perm.support ((galActionHom p ℂ) ((restrict p ℂ) (AlgEquiv.restrictScalars ℚ Complex.conjAe))))
p_roots2 :
  Finset.card (Equiv.Perm.support ((galActionHom p ℂ) ((restrict p ℂ) (AlgEquiv.restrictScalars ℚ Complex.conjAe)))) ≤ 3
n : ℕ :=
  Finset.card (Equiv.Perm.support ((galActionHom p ℂ) ((restrict p ℂ) (AlgEquiv.restrictScalars ℚ Complex.conjAe))))
hn : 2 ∣ n
key :
  Fintype.card ↑(rootSet p ℂ) =
    Fintype.card ↑(rootSet p ℝ) +
      Finset.card (Equiv.Perm.support ((galActionHom p ℂ) ((restrict p ℂ) (AlgEquiv.restrictScalars ℚ Complex.conjAe))))
k : ℕ
h2 : 1 ≤ 2 * k
h3 : 2 * k ≤ 3
⊢ 2 * k = 2

Next tactic:
exact le_antisymm
      (Nat.lt_succ_iff.mp
        (lt_of_le_of_ne h3 (show 2 * k ≠ 2 * 1 + 1 from Nat.two_mul_ne_two_mul_add_one)))
      (Nat.succ_le_iff.mpr
        (lt_of_le_of_ne h2 (show 2 * 0 + 1 ≠ 2 * k from Nat.two_mul_ne_two_mul_add_one.symm)))
theorem poly_eq_of_wittPolynomial_bind_eq' [Fact p.Prime] (f g : ℕ → MvPolynomial (idx × ℕ) ℤ)
    (h : ∀ n, bind₁ f (wittPolynomial p _ n) = bind₁ g (wittPolynomial p _ n)) : f = g := by
  

Proof state:
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
inst✝ : Fact (Nat.Prime p)
f g : ℕ → MvPolynomial (idx × ℕ) ℤ
h : ∀ (n : ℕ), (bind₁ f) (wittPolynomial p ℤ n) = (bind₁ g) (wittPolynomial p ℤ n)
⊢ f = g

Next tactic:
ext1 n
theorem poly_eq_of_wittPolynomial_bind_eq' [Fact p.Prime] (f g : ℕ → MvPolynomial (idx × ℕ) ℤ)
    (h : ∀ n, bind₁ f (wittPolynomial p _ n) = bind₁ g (wittPolynomial p _ n)) : f = g := by
  ext1 n
  

Proof state:
case h
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
inst✝ : Fact (Nat.Prime p)
f g : ℕ → MvPolynomial (idx × ℕ) ℤ
h : ∀ (n : ℕ), (bind₁ f) (wittPolynomial p ℤ n) = (bind₁ g) (wittPolynomial p ℤ n)
n : ℕ
⊢ f n = g n

Next tactic:
apply MvPolynomial.map_injective (Int.castRingHom ℚ) Int.cast_injective
theorem poly_eq_of_wittPolynomial_bind_eq' [Fact p.Prime] (f g : ℕ → MvPolynomial (idx × ℕ) ℤ)
    (h : ∀ n, bind₁ f (wittPolynomial p _ n) = bind₁ g (wittPolynomial p _ n)) : f = g := by
  ext1 n
  apply MvPolynomial.map_injective (Int.castRingHom ℚ) Int.cast_injective
  

Proof state:
case h.a
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
inst✝ : Fact (Nat.Prime p)
f g : ℕ → MvPolynomial (idx × ℕ) ℤ
h : ∀ (n : ℕ), (bind₁ f) (wittPolynomial p ℤ n) = (bind₁ g) (wittPolynomial p ℤ n)
n : ℕ
⊢ (MvPolynomial.map (Int.castRingHom ℚ)) (f n) = (MvPolynomial.map (Int.castRingHom ℚ)) (g n)

Next tactic:
rw [← Function.funext_iff] at h
theorem poly_eq_of_wittPolynomial_bind_eq' [Fact p.Prime] (f g : ℕ → MvPolynomial (idx × ℕ) ℤ)
    (h : ∀ n, bind₁ f (wittPolynomial p _ n) = bind₁ g (wittPolynomial p _ n)) : f = g := by
  ext1 n
  apply MvPolynomial.map_injective (Int.castRingHom ℚ) Int.cast_injective
  rw [← Function.funext_iff] at h
  

Proof state:
case h.a
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
inst✝ : Fact (Nat.Prime p)
f g : ℕ → MvPolynomial (idx × ℕ) ℤ
h : (fun n => (bind₁ f) (wittPolynomial p ℤ n)) = fun n => (bind₁ g) (wittPolynomial p ℤ n)
n : ℕ
⊢ (MvPolynomial.map (Int.castRingHom ℚ)) (f n) = (MvPolynomial.map (Int.castRingHom ℚ)) (g n)

Next tactic:
replace h :=
    congr_arg (fun fam => bind₁ (MvPolynomial.map (Int.castRingHom ℚ) ∘ fam) (xInTermsOfW p ℚ n)) h
theorem poly_eq_of_wittPolynomial_bind_eq' [Fact p.Prime] (f g : ℕ → MvPolynomial (idx × ℕ) ℤ)
    (h : ∀ n, bind₁ f (wittPolynomial p _ n) = bind₁ g (wittPolynomial p _ n)) : f = g := by
  ext1 n
  apply MvPolynomial.map_injective (Int.castRingHom ℚ) Int.cast_injective
  rw [← Function.funext_iff] at h
  replace h :=
    congr_arg (fun fam => bind₁ (MvPolynomial.map (Int.castRingHom ℚ) ∘ fam) (xInTermsOfW p ℚ n)) h
  

Proof state:
case h.a
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
inst✝ : Fact (Nat.Prime p)
f g : ℕ → MvPolynomial (idx × ℕ) ℤ
n : ℕ
h :
  ((fun fam => (bind₁ (⇑(MvPolynomial.map (Int.castRingHom ℚ)) ∘ fam)) (xInTermsOfW p ℚ n)) fun n =>
      (bind₁ f) (wittPolynomial p ℤ n)) =
    (fun fam => (bind₁ (⇑(MvPolynomial.map (Int.castRingHom ℚ)) ∘ fam)) (xInTermsOfW p ℚ n)) fun n =>
      (bind₁ g) (wittPolynomial p ℤ n)
⊢ (MvPolynomial.map (Int.castRingHom ℚ)) (f n) = (MvPolynomial.map (Int.castRingHom ℚ)) (g n)

Next tactic:
simpa only [Function.comp, map_bind₁, map_wittPolynomial, ← bind₁_bind₁,
    bind₁_wittPolynomial_xInTermsOfW, bind₁_X_right] using h
theorem poly_eq_of_wittPolynomial_bind_eq [Fact p.Prime] (f g : ℕ → MvPolynomial ℕ ℤ)
    (h : ∀ n, bind₁ f (wittPolynomial p _ n) = bind₁ g (wittPolynomial p _ n)) : f = g := by
  

Proof state:
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
inst✝ : Fact (Nat.Prime p)
f g : ℕ → MvPolynomial ℕ ℤ
h : ∀ (n : ℕ), (bind₁ f) (wittPolynomial p ℤ n) = (bind₁ g) (wittPolynomial p ℤ n)
⊢ f = g

Next tactic:
ext1 n
theorem poly_eq_of_wittPolynomial_bind_eq [Fact p.Prime] (f g : ℕ → MvPolynomial ℕ ℤ)
    (h : ∀ n, bind₁ f (wittPolynomial p _ n) = bind₁ g (wittPolynomial p _ n)) : f = g := by
  ext1 n
  

Proof state:
case h
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
inst✝ : Fact (Nat.Prime p)
f g : ℕ → MvPolynomial ℕ ℤ
h : ∀ (n : ℕ), (bind₁ f) (wittPolynomial p ℤ n) = (bind₁ g) (wittPolynomial p ℤ n)
n : ℕ
⊢ f n = g n

Next tactic:
apply MvPolynomial.map_injective (Int.castRingHom ℚ) Int.cast_injective
theorem poly_eq_of_wittPolynomial_bind_eq [Fact p.Prime] (f g : ℕ → MvPolynomial ℕ ℤ)
    (h : ∀ n, bind₁ f (wittPolynomial p _ n) = bind₁ g (wittPolynomial p _ n)) : f = g := by
  ext1 n
  apply MvPolynomial.map_injective (Int.castRingHom ℚ) Int.cast_injective
  

Proof state:
case h.a
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
inst✝ : Fact (Nat.Prime p)
f g : ℕ → MvPolynomial ℕ ℤ
h : ∀ (n : ℕ), (bind₁ f) (wittPolynomial p ℤ n) = (bind₁ g) (wittPolynomial p ℤ n)
n : ℕ
⊢ (MvPolynomial.map (Int.castRingHom ℚ)) (f n) = (MvPolynomial.map (Int.castRingHom ℚ)) (g n)

Next tactic:
rw [← Function.funext_iff] at h
theorem poly_eq_of_wittPolynomial_bind_eq [Fact p.Prime] (f g : ℕ → MvPolynomial ℕ ℤ)
    (h : ∀ n, bind₁ f (wittPolynomial p _ n) = bind₁ g (wittPolynomial p _ n)) : f = g := by
  ext1 n
  apply MvPolynomial.map_injective (Int.castRingHom ℚ) Int.cast_injective
  rw [← Function.funext_iff] at h
  

Proof state:
case h.a
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
inst✝ : Fact (Nat.Prime p)
f g : ℕ → MvPolynomial ℕ ℤ
h : (fun n => (bind₁ f) (wittPolynomial p ℤ n)) = fun n => (bind₁ g) (wittPolynomial p ℤ n)
n : ℕ
⊢ (MvPolynomial.map (Int.castRingHom ℚ)) (f n) = (MvPolynomial.map (Int.castRingHom ℚ)) (g n)

Next tactic:
replace h :=
    congr_arg (fun fam => bind₁ (MvPolynomial.map (Int.castRingHom ℚ) ∘ fam) (xInTermsOfW p ℚ n)) h
theorem poly_eq_of_wittPolynomial_bind_eq [Fact p.Prime] (f g : ℕ → MvPolynomial ℕ ℤ)
    (h : ∀ n, bind₁ f (wittPolynomial p _ n) = bind₁ g (wittPolynomial p _ n)) : f = g := by
  ext1 n
  apply MvPolynomial.map_injective (Int.castRingHom ℚ) Int.cast_injective
  rw [← Function.funext_iff] at h
  replace h :=
    congr_arg (fun fam => bind₁ (MvPolynomial.map (Int.castRingHom ℚ) ∘ fam) (xInTermsOfW p ℚ n)) h
  

Proof state:
case h.a
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
inst✝ : Fact (Nat.Prime p)
f g : ℕ → MvPolynomial ℕ ℤ
n : ℕ
h :
  ((fun fam => (bind₁ (⇑(MvPolynomial.map (Int.castRingHom ℚ)) ∘ fam)) (xInTermsOfW p ℚ n)) fun n =>
      (bind₁ f) (wittPolynomial p ℤ n)) =
    (fun fam => (bind₁ (⇑(MvPolynomial.map (Int.castRingHom ℚ)) ∘ fam)) (xInTermsOfW p ℚ n)) fun n =>
      (bind₁ g) (wittPolynomial p ℤ n)
⊢ (MvPolynomial.map (Int.castRingHom ℚ)) (f n) = (MvPolynomial.map (Int.castRingHom ℚ)) (g n)

Next tactic:
simpa only [Function.comp, map_bind₁, map_wittPolynomial, ← bind₁_bind₁,
    bind₁_wittPolynomial_xInTermsOfW, bind₁_X_right] using h
/-- The identity function on Witt vectors is a polynomial function. -/
instance idIsPoly : IsPoly p fun _ _ => id :=
  ⟨⟨X, by 

Proof state:
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝¹ : CommRing R
inst✝ : CommRing S
⊢ ∀ ⦃R : Type ?u.184478⦄ [inst : CommRing R] (x : 𝕎 R), (id x).coeff = fun n => (aeval x.coeff) (X n)

Next tactic:
intros
/-- The identity function on Witt vectors is a polynomial function. -/
instance idIsPoly : IsPoly p fun _ _ => id :=
  ⟨⟨X, by intros; 

Proof state:
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
R✝ : Type ?u.184478
inst✝ : CommRing R✝
x✝ : 𝕎 R✝
⊢ (id x✝).coeff = fun n => (aeval x✝.coeff) (X n)

Next tactic:
simp only [aeval_X, id]