l3lab/ntp-mathlib huggingface dataset:
@[to_additive le_sum_nonempty_of_subadditive_on_pred]
theorem le_prod_nonempty_of_submultiplicative_on_pred [CommMonoid α] [OrderedCommMonoid β]
    (f : α → β) (p : α → Prop) (h_mul : ∀ a b, p a → p b → f (a * b) ≤ f a * f b)
    (hp_mul : ∀ a b, p a → p b → p (a * b)) (s : Multiset α) (hs_nonempty : s ≠ ∅)
    (hs : ∀ a, a ∈ s → p a) : f s.prod ≤ (s.map f).prod := by
  revert s
  refine' Multiset.induction _ _
  · intro h
    exfalso
    

Proof state:
case refine'_1.h
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝¹ : CommMonoid α
inst✝ : OrderedCommMonoid β
f : α → β
p : α → Prop
h_mul : ∀ (a b : α), p a → p b → f (a * b) ≤ f a * f b
hp_mul : ∀ (a b : α), p a → p b → p (a * b)
h : 0 ≠ ∅
⊢ False

Next tactic:
exact h rfl
@[to_additive le_sum_nonempty_of_subadditive_on_pred]
theorem le_prod_nonempty_of_submultiplicative_on_pred [CommMonoid α] [OrderedCommMonoid β]
    (f : α → β) (p : α → Prop) (h_mul : ∀ a b, p a → p b → f (a * b) ≤ f a * f b)
    (hp_mul : ∀ a b, p a → p b → p (a * b)) (s : Multiset α) (hs_nonempty : s ≠ ∅)
    (hs : ∀ a, a ∈ s → p a) : f s.prod ≤ (s.map f).prod := by
  revert s
  refine' Multiset.induction _ _
  · intro h
    exfalso
    exact h rfl
  

Proof state:
case refine'_2
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝¹ : CommMonoid α
inst✝ : OrderedCommMonoid β
f : α → β
p : α → Prop
h_mul : ∀ (a b : α), p a → p b → f (a * b) ≤ f a * f b
hp_mul : ∀ (a b : α), p a → p b → p (a * b)
⊢ ∀ ⦃a : α⦄ {s : Multiset α},
    (s ≠ ∅ → (∀ a ∈ s, p a) → f (prod s) ≤ prod (map f s)) →
      a ::ₘ s ≠ ∅ → (∀ a_2 ∈ a ::ₘ s, p a_2) → f (prod (a ::ₘ s)) ≤ prod (map f (a ::ₘ s))

Next tactic:
rintro a s hs - hsa_prop
@[to_additive le_sum_nonempty_of_subadditive_on_pred]
theorem le_prod_nonempty_of_submultiplicative_on_pred [CommMonoid α] [OrderedCommMonoid β]
    (f : α → β) (p : α → Prop) (h_mul : ∀ a b, p a → p b → f (a * b) ≤ f a * f b)
    (hp_mul : ∀ a b, p a → p b → p (a * b)) (s : Multiset α) (hs_nonempty : s ≠ ∅)
    (hs : ∀ a, a ∈ s → p a) : f s.prod ≤ (s.map f).prod := by
  revert s
  refine' Multiset.induction _ _
  · intro h
    exfalso
    exact h rfl
  rintro a s hs - hsa_prop
  

Proof state:
case refine'_2
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝¹ : CommMonoid α
inst✝ : OrderedCommMonoid β
f : α → β
p : α → Prop
h_mul : ∀ (a b : α), p a → p b → f (a * b) ≤ f a * f b
hp_mul : ∀ (a b : α), p a → p b → p (a * b)
a : α
s : Multiset α
hs : s ≠ ∅ → (∀ a ∈ s, p a) → f (prod s) ≤ prod (map f s)
hsa_prop : ∀ a_1 ∈ a ::ₘ s, p a_1
⊢ f (prod (a ::ₘ s)) ≤ prod (map f (a ::ₘ s))

Next tactic:
rw [prod_cons, map_cons, prod_cons]
@[to_additive le_sum_nonempty_of_subadditive_on_pred]
theorem le_prod_nonempty_of_submultiplicative_on_pred [CommMonoid α] [OrderedCommMonoid β]
    (f : α → β) (p : α → Prop) (h_mul : ∀ a b, p a → p b → f (a * b) ≤ f a * f b)
    (hp_mul : ∀ a b, p a → p b → p (a * b)) (s : Multiset α) (hs_nonempty : s ≠ ∅)
    (hs : ∀ a, a ∈ s → p a) : f s.prod ≤ (s.map f).prod := by
  revert s
  refine' Multiset.induction _ _
  · intro h
    exfalso
    exact h rfl
  rintro a s hs - hsa_prop
  rw [prod_cons, map_cons, prod_cons]
  

Proof state:
case refine'_2
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝¹ : CommMonoid α
inst✝ : OrderedCommMonoid β
f : α → β
p : α → Prop
h_mul : ∀ (a b : α), p a → p b → f (a * b) ≤ f a * f b
hp_mul : ∀ (a b : α), p a → p b → p (a * b)
a : α
s : Multiset α
hs : s ≠ ∅ → (∀ a ∈ s, p a) → f (prod s) ≤ prod (map f s)
hsa_prop : ∀ a_1 ∈ a ::ₘ s, p a_1
⊢ f (a * prod s) ≤ f a * prod (map f s)

Next tactic:
by_cases hs_empty : s = ∅
@[to_additive le_sum_nonempty_of_subadditive_on_pred]
theorem le_prod_nonempty_of_submultiplicative_on_pred [CommMonoid α] [OrderedCommMonoid β]
    (f : α → β) (p : α → Prop) (h_mul : ∀ a b, p a → p b → f (a * b) ≤ f a * f b)
    (hp_mul : ∀ a b, p a → p b → p (a * b)) (s : Multiset α) (hs_nonempty : s ≠ ∅)
    (hs : ∀ a, a ∈ s → p a) : f s.prod ≤ (s.map f).prod := by
  revert s
  refine' Multiset.induction _ _
  · intro h
    exfalso
    exact h rfl
  rintro a s hs - hsa_prop
  rw [prod_cons, map_cons, prod_cons]
  by_cases hs_empty : s = ∅
  · 

Proof state:
case pos
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝¹ : CommMonoid α
inst✝ : OrderedCommMonoid β
f : α → β
p : α → Prop
h_mul : ∀ (a b : α), p a → p b → f (a * b) ≤ f a * f b
hp_mul : ∀ (a b : α), p a → p b → p (a * b)
a : α
s : Multiset α
hs : s ≠ ∅ → (∀ a ∈ s, p a) → f (prod s) ≤ prod (map f s)
hsa_prop : ∀ a_1 ∈ a ::ₘ s, p a_1
hs_empty : s = ∅
⊢ f (a * prod s) ≤ f a * prod (map f s)

Next tactic:
simp [hs_empty]
@[to_additive le_sum_nonempty_of_subadditive_on_pred]
theorem le_prod_nonempty_of_submultiplicative_on_pred [CommMonoid α] [OrderedCommMonoid β]
    (f : α → β) (p : α → Prop) (h_mul : ∀ a b, p a → p b → f (a * b) ≤ f a * f b)
    (hp_mul : ∀ a b, p a → p b → p (a * b)) (s : Multiset α) (hs_nonempty : s ≠ ∅)
    (hs : ∀ a, a ∈ s → p a) : f s.prod ≤ (s.map f).prod := by
  revert s
  refine' Multiset.induction _ _
  · intro h
    exfalso
    exact h rfl
  rintro a s hs - hsa_prop
  rw [prod_cons, map_cons, prod_cons]
  by_cases hs_empty : s = ∅
  · simp [hs_empty]
  

Proof state:
case neg
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝¹ : CommMonoid α
inst✝ : OrderedCommMonoid β
f : α → β
p : α → Prop
h_mul : ∀ (a b : α), p a → p b → f (a * b) ≤ f a * f b
hp_mul : ∀ (a b : α), p a → p b → p (a * b)
a : α
s : Multiset α
hs : s ≠ ∅ → (∀ a ∈ s, p a) → f (prod s) ≤ prod (map f s)
hsa_prop : ∀ a_1 ∈ a ::ₘ s, p a_1
hs_empty : ¬s = ∅
⊢ f (a * prod s) ≤ f a * prod (map f s)

Next tactic:
have hsa_restrict : ∀ x, x ∈ s → p x := fun x hx => hsa_prop x (mem_cons_of_mem hx)
@[to_additive le_sum_nonempty_of_subadditive_on_pred]
theorem le_prod_nonempty_of_submultiplicative_on_pred [CommMonoid α] [OrderedCommMonoid β]
    (f : α → β) (p : α → Prop) (h_mul : ∀ a b, p a → p b → f (a * b) ≤ f a * f b)
    (hp_mul : ∀ a b, p a → p b → p (a * b)) (s : Multiset α) (hs_nonempty : s ≠ ∅)
    (hs : ∀ a, a ∈ s → p a) : f s.prod ≤ (s.map f).prod := by
  revert s
  refine' Multiset.induction _ _
  · intro h
    exfalso
    exact h rfl
  rintro a s hs - hsa_prop
  rw [prod_cons, map_cons, prod_cons]
  by_cases hs_empty : s = ∅
  · simp [hs_empty]
  have hsa_restrict : ∀ x, x ∈ s → p x := fun x hx => hsa_prop x (mem_cons_of_mem hx)
  

Proof state:
case neg
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝¹ : CommMonoid α
inst✝ : OrderedCommMonoid β
f : α → β
p : α → Prop
h_mul : ∀ (a b : α), p a → p b → f (a * b) ≤ f a * f b
hp_mul : ∀ (a b : α), p a → p b → p (a * b)
a : α
s : Multiset α
hs : s ≠ ∅ → (∀ a ∈ s, p a) → f (prod s) ≤ prod (map f s)
hsa_prop : ∀ a_1 ∈ a ::ₘ s, p a_1
hs_empty : ¬s = ∅
hsa_restrict : ∀ x ∈ s, p x
⊢ f (a * prod s) ≤ f a * prod (map f s)

Next tactic:
have hp_sup : p s.prod := prod_induction_nonempty p hp_mul hs_empty hsa_restrict
@[to_additive le_sum_nonempty_of_subadditive_on_pred]
theorem le_prod_nonempty_of_submultiplicative_on_pred [CommMonoid α] [OrderedCommMonoid β]
    (f : α → β) (p : α → Prop) (h_mul : ∀ a b, p a → p b → f (a * b) ≤ f a * f b)
    (hp_mul : ∀ a b, p a → p b → p (a * b)) (s : Multiset α) (hs_nonempty : s ≠ ∅)
    (hs : ∀ a, a ∈ s → p a) : f s.prod ≤ (s.map f).prod := by
  revert s
  refine' Multiset.induction _ _
  · intro h
    exfalso
    exact h rfl
  rintro a s hs - hsa_prop
  rw [prod_cons, map_cons, prod_cons]
  by_cases hs_empty : s = ∅
  · simp [hs_empty]
  have hsa_restrict : ∀ x, x ∈ s → p x := fun x hx => hsa_prop x (mem_cons_of_mem hx)
  have hp_sup : p s.prod := prod_induction_nonempty p hp_mul hs_empty hsa_restrict
  

Proof state:
case neg
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝¹ : CommMonoid α
inst✝ : OrderedCommMonoid β
f : α → β
p : α → Prop
h_mul : ∀ (a b : α), p a → p b → f (a * b) ≤ f a * f b
hp_mul : ∀ (a b : α), p a → p b → p (a * b)
a : α
s : Multiset α
hs : s ≠ ∅ → (∀ a ∈ s, p a) → f (prod s) ≤ prod (map f s)
hsa_prop : ∀ a_1 ∈ a ::ₘ s, p a_1
hs_empty : ¬s = ∅
hsa_restrict : ∀ x ∈ s, p x
hp_sup : p (prod s)
⊢ f (a * prod s) ≤ f a * prod (map f s)

Next tactic:
have hp_a : p a := hsa_prop a (mem_cons_self a s)
@[to_additive le_sum_nonempty_of_subadditive_on_pred]
theorem le_prod_nonempty_of_submultiplicative_on_pred [CommMonoid α] [OrderedCommMonoid β]
    (f : α → β) (p : α → Prop) (h_mul : ∀ a b, p a → p b → f (a * b) ≤ f a * f b)
    (hp_mul : ∀ a b, p a → p b → p (a * b)) (s : Multiset α) (hs_nonempty : s ≠ ∅)
    (hs : ∀ a, a ∈ s → p a) : f s.prod ≤ (s.map f).prod := by
  revert s
  refine' Multiset.induction _ _
  · intro h
    exfalso
    exact h rfl
  rintro a s hs - hsa_prop
  rw [prod_cons, map_cons, prod_cons]
  by_cases hs_empty : s = ∅
  · simp [hs_empty]
  have hsa_restrict : ∀ x, x ∈ s → p x := fun x hx => hsa_prop x (mem_cons_of_mem hx)
  have hp_sup : p s.prod := prod_induction_nonempty p hp_mul hs_empty hsa_restrict
  have hp_a : p a := hsa_prop a (mem_cons_self a s)
  

Proof state:
case neg
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝¹ : CommMonoid α
inst✝ : OrderedCommMonoid β
f : α → β
p : α → Prop
h_mul : ∀ (a b : α), p a → p b → f (a * b) ≤ f a * f b
hp_mul : ∀ (a b : α), p a → p b → p (a * b)
a : α
s : Multiset α
hs : s ≠ ∅ → (∀ a ∈ s, p a) → f (prod s) ≤ prod (map f s)
hsa_prop : ∀ a_1 ∈ a ::ₘ s, p a_1
hs_empty : ¬s = ∅
hsa_restrict : ∀ x ∈ s, p x
hp_sup : p (prod s)
hp_a : p a
⊢ f (a * prod s) ≤ f a * prod (map f s)

Next tactic:
exact (h_mul a _ hp_a hp_sup).trans (mul_le_mul_left' (hs hs_empty hsa_restrict) _)
@[to_additive le_sum_nonempty_of_subadditive]
theorem le_prod_nonempty_of_submultiplicative [CommMonoid α] [OrderedCommMonoid β] (f : α → β)
    (h_mul : ∀ a b, f (a * b) ≤ f a * f b) (s : Multiset α) (hs_nonempty : s ≠ ∅) :
    f s.prod ≤ (s.map f).prod :=
  le_prod_nonempty_of_submultiplicative_on_pred f (fun _ => True) (by 

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝¹ : CommMonoid α
inst✝ : OrderedCommMonoid β
f : α → β
h_mul : ∀ (a b : α), f (a * b) ≤ f a * f b
s : Multiset α
hs_nonempty : s ≠ ∅
⊢ ∀ (a b : α), (fun x => True) a → (fun x => True) b → f (a * b) ≤ f a * f b

Next tactic:
simp [h_mul]
@[to_additive le_sum_nonempty_of_subadditive]
theorem le_prod_nonempty_of_submultiplicative [CommMonoid α] [OrderedCommMonoid β] (f : α → β)
    (h_mul : ∀ a b, f (a * b) ≤ f a * f b) (s : Multiset α) (hs_nonempty : s ≠ ∅) :
    f s.prod ≤ (s.map f).prod :=
  le_prod_nonempty_of_submultiplicative_on_pred f (fun _ => True) (by simp [h_mul]) (by 

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝¹ : CommMonoid α
inst✝ : OrderedCommMonoid β
f : α → β
h_mul : ∀ (a b : α), f (a * b) ≤ f a * f b
s : Multiset α
hs_nonempty : s ≠ ∅
⊢ ∀ (a b : α), (fun x => True) a → (fun x => True) b → (fun x => True) (a * b)

Next tactic:
simp
@[to_additive le_sum_nonempty_of_subadditive]
theorem le_prod_nonempty_of_submultiplicative [CommMonoid α] [OrderedCommMonoid β] (f : α → β)
    (h_mul : ∀ a b, f (a * b) ≤ f a * f b) (s : Multiset α) (hs_nonempty : s ≠ ∅) :
    f s.prod ≤ (s.map f).prod :=
  le_prod_nonempty_of_submultiplicative_on_pred f (fun _ => True) (by simp [h_mul]) (by simp) s
    hs_nonempty (by 

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
inst✝¹ : CommMonoid α
inst✝ : OrderedCommMonoid β
f : α → β
h_mul : ∀ (a b : α), f (a * b) ≤ f a * f b
s : Multiset α
hs_nonempty : s ≠ ∅
⊢ ∀ a ∈ s, (fun x => True) a

Next tactic:
simp
@[simp]
theorem sum_map_singleton (s : Multiset α) : (s.map fun a => ({a} : Multiset α)).sum = s :=
  Multiset.induction_on s (by 

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
s : Multiset α
⊢ sum (map (fun a => {a}) 0) = 0

Next tactic:
simp
@[simp]
theorem sum_map_singleton (s : Multiset α) : (s.map fun a => ({a} : Multiset α)).sum = s :=
  Multiset.induction_on s (by simp) (by 

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
s : Multiset α
⊢ ∀ ⦃a : α⦄ {s : Multiset α}, sum (map (fun a => {a}) s) = s → sum (map (fun a => {a}) (a ::ₘ s)) = a ::ₘ s

Next tactic:
simp
theorem sum_nat_mod (s : Multiset ℕ) (n : ℕ) : s.sum % n = (s.map (· % n)).sum % n := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
s : Multiset ℕ
n : ℕ
⊢ sum s % n = sum (map (fun x => x % n) s) % n

Next tactic:
induction s using Multiset.induction
theorem sum_nat_mod (s : Multiset ℕ) (n : ℕ) : s.sum % n = (s.map (· % n)).sum % n := by
  induction s using Multiset.induction <;> 

Proof state:
case empty
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
n : ℕ
⊢ sum 0 % n = sum (map (fun x => x % n) 0) % n

Next tactic:
simp [Nat.add_mod, *]
theorem sum_nat_mod (s : Multiset ℕ) (n : ℕ) : s.sum % n = (s.map (· % n)).sum % n := by
  induction s using Multiset.induction <;> 

Proof state:
case cons
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
n a✝¹ : ℕ
s✝ : Multiset ℕ
a✝ : sum s✝ % n = sum (map (fun x => x % n) s✝) % n
⊢ sum (a✝¹ ::ₘ s✝) % n = sum (map (fun x => x % n) (a✝¹ ::ₘ s✝)) % n

Next tactic:
simp [Nat.add_mod, *]
theorem prod_nat_mod (s : Multiset ℕ) (n : ℕ) : s.prod % n = (s.map (· % n)).prod % n := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
s : Multiset ℕ
n : ℕ
⊢ prod s % n = prod (map (fun x => x % n) s) % n

Next tactic:
induction s using Multiset.induction
theorem prod_nat_mod (s : Multiset ℕ) (n : ℕ) : s.prod % n = (s.map (· % n)).prod % n := by
  induction s using Multiset.induction <;> 

Proof state:
case empty
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
n : ℕ
⊢ prod 0 % n = prod (map (fun x => x % n) 0) % n

Next tactic:
simp [Nat.mul_mod, *]
theorem prod_nat_mod (s : Multiset ℕ) (n : ℕ) : s.prod % n = (s.map (· % n)).prod % n := by
  induction s using Multiset.induction <;> 

Proof state:
case cons
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
n a✝¹ : ℕ
s✝ : Multiset ℕ
a✝ : prod s✝ % n = prod (map (fun x => x % n) s✝) % n
⊢ prod (a✝¹ ::ₘ s✝) % n = prod (map (fun x => x % n) (a✝¹ ::ₘ s✝)) % n

Next tactic:
simp [Nat.mul_mod, *]
theorem sum_int_mod (s : Multiset ℤ) (n : ℤ) : s.sum % n = (s.map (· % n)).sum % n := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
s : Multiset ℤ
n : ℤ
⊢ sum s % n = sum (map (fun x => x % n) s) % n

Next tactic:
induction s using Multiset.induction
theorem sum_int_mod (s : Multiset ℤ) (n : ℤ) : s.sum % n = (s.map (· % n)).sum % n := by
  induction s using Multiset.induction <;> 

Proof state:
case empty
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
n : ℤ
⊢ sum 0 % n = sum (map (fun x => x % n) 0) % n

Next tactic:
simp [Int.add_emod, *]
theorem sum_int_mod (s : Multiset ℤ) (n : ℤ) : s.sum % n = (s.map (· % n)).sum % n := by
  induction s using Multiset.induction <;> 

Proof state:
case cons
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
n a✝¹ : ℤ
s✝ : Multiset ℤ
a✝ : sum s✝ % n = sum (map (fun x => x % n) s✝) % n
⊢ sum (a✝¹ ::ₘ s✝) % n = sum (map (fun x => x % n) (a✝¹ ::ₘ s✝)) % n

Next tactic:
simp [Int.add_emod, *]
theorem prod_int_mod (s : Multiset ℤ) (n : ℤ) : s.prod % n = (s.map (· % n)).prod % n := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
s : Multiset ℤ
n : ℤ
⊢ prod s % n = prod (map (fun x => x % n) s) % n

Next tactic:
induction s using Multiset.induction
theorem prod_int_mod (s : Multiset ℤ) (n : ℤ) : s.prod % n = (s.map (· % n)).prod % n := by
  induction s using Multiset.induction <;> 

Proof state:
case empty
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
n : ℤ
⊢ prod 0 % n = prod (map (fun x => x % n) 0) % n

Next tactic:
simp [Int.mul_emod, *]
theorem prod_int_mod (s : Multiset ℤ) (n : ℤ) : s.prod % n = (s.map (· % n)).prod % n := by
  induction s using Multiset.induction <;> 

Proof state:
case cons
ι : Type u_1
α : Type u_2
β : Type u_3
γ : Type u_4
n a✝¹ : ℤ
s✝ : Multiset ℤ
a✝ : prod s✝ % n = prod (map (fun x => x % n) s✝) % n
⊢ prod (a✝¹ ::ₘ s✝) % n = prod (map (fun x => x % n) (a✝¹ ::ₘ s✝)) % n

Next tactic:
simp [Int.mul_emod, *]
theorem toSplittingField_evalXSelf {s : Finset (MonicIrreducible k)} {f} (hf : f ∈ s) :
    toSplittingField k s (evalXSelf k f) = 0 := by
  

Proof state:
k : Type u
inst✝ : Field k
s : Finset (MonicIrreducible k)
f : MonicIrreducible k
hf : f ∈ s
⊢ (toSplittingField k s) (evalXSelf k f) = 0

Next tactic:
rw [toSplittingField, evalXSelf, ← AlgHom.coe_toRingHom, hom_eval₂, AlgHom.coe_toRingHom,
    MvPolynomial.aeval_X, dif_pos hf, ← algebraMap_eq, AlgHom.comp_algebraMap]
theorem toSplittingField_evalXSelf {s : Finset (MonicIrreducible k)} {f} (hf : f ∈ s) :
    toSplittingField k s (evalXSelf k f) = 0 := by
  rw [toSplittingField, evalXSelf, ← AlgHom.coe_toRingHom, hom_eval₂, AlgHom.coe_toRingHom,
    MvPolynomial.aeval_X, dif_pos hf, ← algebraMap_eq, AlgHom.comp_algebraMap]
  

Proof state:
k : Type u
inst✝ : Field k
s : Finset (MonicIrreducible k)
f : MonicIrreducible k
hf : f ∈ s
⊢ Polynomial.eval₂ (algebraMap k (SplittingField (∏ x in s, ↑x)))
      (rootOfSplits (algebraMap k (SplittingField (∏ x in s, ↑x)))
        (_ : Splits (algebraMap k (SplittingField (∏ x in s, ↑x))) ↑f) (_ : ¬degree ↑f = 0))
      ↑f =
    0

Next tactic:
exact map_rootOfSplits _ _ _
theorem spanEval_ne_top : spanEval k ≠ ⊤ := by
  

Proof state:
k : Type u
inst✝ : Field k
⊢ spanEval k ≠ ⊤

Next tactic:
rw [Ideal.ne_top_iff_one, spanEval, Ideal.span, ← Set.image_univ,
    Finsupp.mem_span_image_iff_total]
theorem spanEval_ne_top : spanEval k ≠ ⊤ := by
  rw [Ideal.ne_top_iff_one, spanEval, Ideal.span, ← Set.image_univ,
    Finsupp.mem_span_image_iff_total]
  

Proof state:
k : Type u
inst✝ : Field k
⊢ ¬∃ l ∈ Finsupp.supported (MvPolynomial (MonicIrreducible k) k) (MvPolynomial (MonicIrreducible k) k) Set.univ,
      (Finsupp.total (MonicIrreducible k) (MvPolynomial (MonicIrreducible k) k) (MvPolynomial (MonicIrreducible k) k)
            (evalXSelf k))
          l =
        1

Next tactic:
rintro ⟨v, _, hv⟩
theorem spanEval_ne_top : spanEval k ≠ ⊤ := by
  rw [Ideal.ne_top_iff_one, spanEval, Ideal.span, ← Set.image_univ,
    Finsupp.mem_span_image_iff_total]
  rintro ⟨v, _, hv⟩
  

Proof state:
case intro.intro
k : Type u
inst✝ : Field k
v : MonicIrreducible k →₀ MvPolynomial (MonicIrreducible k) k
left✝ : v ∈ Finsupp.supported (MvPolynomial (MonicIrreducible k) k) (MvPolynomial (MonicIrreducible k) k) Set.univ
hv :
  (Finsupp.total (MonicIrreducible k) (MvPolynomial (MonicIrreducible k) k) (MvPolynomial (MonicIrreducible k) k)
        (evalXSelf k))
      v =
    1
⊢ False

Next tactic:
replace hv := congr_arg (toSplittingField k v.support) hv
theorem spanEval_ne_top : spanEval k ≠ ⊤ := by
  rw [Ideal.ne_top_iff_one, spanEval, Ideal.span, ← Set.image_univ,
    Finsupp.mem_span_image_iff_total]
  rintro ⟨v, _, hv⟩
  replace hv := congr_arg (toSplittingField k v.support) hv
  

Proof state:
case intro.intro
k : Type u
inst✝ : Field k
v : MonicIrreducible k →₀ MvPolynomial (MonicIrreducible k) k
left✝ : v ∈ Finsupp.supported (MvPolynomial (MonicIrreducible k) k) (MvPolynomial (MonicIrreducible k) k) Set.univ
hv :
  (toSplittingField k v.support)
      ((Finsupp.total (MonicIrreducible k) (MvPolynomial (MonicIrreducible k) k) (MvPolynomial (MonicIrreducible k) k)
          (evalXSelf k))
        v) =
    (toSplittingField k v.support) 1
⊢ False

Next tactic:
rw [AlgHom.map_one, Finsupp.total_apply, Finsupp.sum, AlgHom.map_sum, Finset.sum_eq_zero] at hv
theorem spanEval_ne_top : spanEval k ≠ ⊤ := by
  rw [Ideal.ne_top_iff_one, spanEval, Ideal.span, ← Set.image_univ,
    Finsupp.mem_span_image_iff_total]
  rintro ⟨v, _, hv⟩
  replace hv := congr_arg (toSplittingField k v.support) hv
  rw [AlgHom.map_one, Finsupp.total_apply, Finsupp.sum, AlgHom.map_sum, Finset.sum_eq_zero] at hv
  · 

Proof state:
case intro.intro
k : Type u
inst✝ : Field k
v : MonicIrreducible k →₀ MvPolynomial (MonicIrreducible k) k
left✝ : v ∈ Finsupp.supported (MvPolynomial (MonicIrreducible k) k) (MvPolynomial (MonicIrreducible k) k) Set.univ
hv : 0 = 1
⊢ False

Next tactic:
exact zero_ne_one hv
theorem spanEval_ne_top : spanEval k ≠ ⊤ := by
  rw [Ideal.ne_top_iff_one, spanEval, Ideal.span, ← Set.image_univ,
    Finsupp.mem_span_image_iff_total]
  rintro ⟨v, _, hv⟩
  replace hv := congr_arg (toSplittingField k v.support) hv
  rw [AlgHom.map_one, Finsupp.total_apply, Finsupp.sum, AlgHom.map_sum, Finset.sum_eq_zero] at hv
  · exact zero_ne_one hv
  

Proof state:
case intro.intro
k : Type u
inst✝ : Field k
v : MonicIrreducible k →₀ MvPolynomial (MonicIrreducible k) k
left✝ : v ∈ Finsupp.supported (MvPolynomial (MonicIrreducible k) k) (MvPolynomial (MonicIrreducible k) k) Set.univ
hv : ∑ x in v.support, (toSplittingField k v.support) (v x • evalXSelf k x) = 1
⊢ ∀ x ∈ v.support, (toSplittingField k v.support) (v x • evalXSelf k x) = 0

Next tactic:
intro j hj
theorem spanEval_ne_top : spanEval k ≠ ⊤ := by
  rw [Ideal.ne_top_iff_one, spanEval, Ideal.span, ← Set.image_univ,
    Finsupp.mem_span_image_iff_total]
  rintro ⟨v, _, hv⟩
  replace hv := congr_arg (toSplittingField k v.support) hv
  rw [AlgHom.map_one, Finsupp.total_apply, Finsupp.sum, AlgHom.map_sum, Finset.sum_eq_zero] at hv
  · exact zero_ne_one hv
  intro j hj
  

Proof state:
case intro.intro
k : Type u
inst✝ : Field k
v : MonicIrreducible k →₀ MvPolynomial (MonicIrreducible k) k
left✝ : v ∈ Finsupp.supported (MvPolynomial (MonicIrreducible k) k) (MvPolynomial (MonicIrreducible k) k) Set.univ
hv : ∑ x in v.support, (toSplittingField k v.support) (v x • evalXSelf k x) = 1
j : MonicIrreducible k
hj : j ∈ v.support
⊢ (toSplittingField k v.support) (v j • evalXSelf k j) = 0

Next tactic:
rw [smul_eq_mul, AlgHom.map_mul, toSplittingField_evalXSelf (s := v.support) hj,
    mul_zero]
theorem AdjoinMonic.isIntegral (z : AdjoinMonic k) : IsIntegral k z := by
  

Proof state:
k : Type u
inst✝ : Field k
z : AdjoinMonic k
⊢ IsIntegral k z

Next tactic:
let ⟨p, hp⟩ := Ideal.Quotient.mk_surjective z
theorem AdjoinMonic.isIntegral (z : AdjoinMonic k) : IsIntegral k z := by
  let ⟨p, hp⟩ := Ideal.Quotient.mk_surjective z
  

Proof state:
k : Type u
inst✝ : Field k
z : AdjoinMonic k
p : MvPolynomial (MonicIrreducible k) k
hp : (Ideal.Quotient.mk (maxIdeal k)) p = z
⊢ IsIntegral k z

Next tactic:
rw [← hp]
theorem AdjoinMonic.isIntegral (z : AdjoinMonic k) : IsIntegral k z := by
  let ⟨p, hp⟩ := Ideal.Quotient.mk_surjective z
  rw [← hp]
  

Proof state:
k : Type u
inst✝ : Field k
z : AdjoinMonic k
p : MvPolynomial (MonicIrreducible k) k
hp : (Ideal.Quotient.mk (maxIdeal k)) p = z
⊢ IsIntegral k ((Ideal.Quotient.mk (maxIdeal k)) p)

Next tactic:
induction p using MvPolynomial.induction_on generalizing z with
    | h_C => exact isIntegral_algebraMap
    | h_add _ _ ha hb => exact (ha _ rfl).add (hb _ rfl)
    | h_X p f ih =>
      · refine @IsIntegral.mul k _ _ _ _ _ (Ideal.Quotient.mk (maxIdeal k) _) (ih _ rfl) ?_
        refine ⟨f, f.2.1, ?_⟩
        erw [AdjoinMonic.algebraMap, ← hom_eval₂, Ideal.Quotient.eq_zero_iff_mem]
        exact le_maxIdeal k (Ideal.subset_span ⟨f, rfl⟩)
theorem AdjoinMonic.isIntegral (z : AdjoinMonic k) : IsIntegral k z := by
  let ⟨p, hp⟩ := Ideal.Quotient.mk_surjective z
  rw [← hp]
  induction p using MvPolynomial.induction_on generalizing z with
    

Proof state:
case h_C
k : Type u
inst✝ : Field k
a✝ : k
z : AdjoinMonic k
hp : (Ideal.Quotient.mk (maxIdeal k)) (MvPolynomial.C a✝) = z
⊢ IsIntegral k ((Ideal.Quotient.mk (maxIdeal k)) (MvPolynomial.C a✝))

Next tactic:
| h_C => exact isIntegral_algebraMap
theorem AdjoinMonic.isIntegral (z : AdjoinMonic k) : IsIntegral k z := by
  let ⟨p, hp⟩ := Ideal.Quotient.mk_surjective z
  rw [← hp]
  induction p using MvPolynomial.induction_on generalizing z with
    | h_C => 

Proof state:
case h_C
k : Type u
inst✝ : Field k
a✝ : k
z : AdjoinMonic k
hp : (Ideal.Quotient.mk (maxIdeal k)) (MvPolynomial.C a✝) = z
⊢ IsIntegral k ((Ideal.Quotient.mk (maxIdeal k)) (MvPolynomial.C a✝))

Next tactic:
exact isIntegral_algebraMap