[GOAL]
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
l : List S[X]
⊢ natDegree 0 ≤ 0
[PROOFSTEP]
simp
[GOAL]
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
l : Multiset S[X]
⊢ ∀ (a : List S[X]),
    natDegree (Multiset.sum (Quotient.mk (List.isSetoid S[X]) a)) ≤
      foldr max (_ : ∀ (a b c : ℕ), max a (max b c) = max b (max a c)) 0
        (Multiset.map natDegree (Quotient.mk (List.isSetoid S[X]) a))
[PROOFSTEP]
simpa using natDegree_list_sum_le
[GOAL]
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
f : ι → S[X]
⊢ natDegree (∑ i in s, f i) ≤ Finset.fold max 0 (natDegree ∘ f) s
[PROOFSTEP]
simpa using natDegree_multiset_sum_le (s.val.map f)
[GOAL]
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
l : List S[X]
⊢ degree (List.sum l) ≤ List.maximum (List.map natDegree l)
[PROOFSTEP]
by_cases h : l.sum = 0
[GOAL]
case pos
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
l : List S[X]
h : List.sum l = 0
⊢ degree (List.sum l) ≤ List.maximum (List.map natDegree l)
[PROOFSTEP]
simp [h]
[GOAL]
case neg
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
l : List S[X]
h : ¬List.sum l = 0
⊢ degree (List.sum l) ≤ List.maximum (List.map natDegree l)
[PROOFSTEP]
rw [degree_eq_natDegree h]
[GOAL]
case neg
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
l : List S[X]
h : ¬List.sum l = 0
⊢ ↑(natDegree (List.sum l)) ≤ List.maximum (List.map natDegree l)
[PROOFSTEP]
suffices (l.map natDegree).maximum = ((l.map natDegree).foldr max 0 : ℕ)
  by
  rw [this]
  simpa [this, Nat.cast_withBot] using natDegree_list_sum_le l
[GOAL]
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
l : List S[X]
h : ¬List.sum l = 0
this : List.maximum (List.map natDegree l) = ↑(List.foldr max 0 (List.map natDegree l))
⊢ ↑(natDegree (List.sum l)) ≤ List.maximum (List.map natDegree l)
[PROOFSTEP]
rw [this]
[GOAL]
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
l : List S[X]
h : ¬List.sum l = 0
this : List.maximum (List.map natDegree l) = ↑(List.foldr max 0 (List.map natDegree l))
⊢ ↑(natDegree (List.sum l)) ≤ ↑(List.foldr max 0 (List.map natDegree l))
[PROOFSTEP]
simpa [this, Nat.cast_withBot] using natDegree_list_sum_le l
[GOAL]
case neg
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
l : List S[X]
h : ¬List.sum l = 0
⊢ List.maximum (List.map natDegree l) = ↑(List.foldr max 0 (List.map natDegree l))
[PROOFSTEP]
rw [← List.foldr_max_of_ne_nil]
[GOAL]
case neg
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
l : List S[X]
h : ¬List.sum l = 0
⊢ ↑(List.foldr max ⊥ (List.map natDegree l)) = ↑(List.foldr max 0 (List.map natDegree l))
[PROOFSTEP]
congr
[GOAL]
case neg
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
l : List S[X]
h : ¬List.sum l = 0
⊢ List.map natDegree l ≠ []
[PROOFSTEP]
contrapose! h
[GOAL]
case neg
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
l : List S[X]
h : List.map natDegree l = []
⊢ List.sum l = 0
[PROOFSTEP]
rw [List.map_eq_nil] at h
[GOAL]
case neg
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
l : List S[X]
h : l = []
⊢ List.sum l = 0
[PROOFSTEP]
simp [h]
[GOAL]
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
l : List S[X]
⊢ natDegree (List.prod l) ≤ List.sum (List.map natDegree l)
[PROOFSTEP]
induction' l with hd tl IH
[GOAL]
case nil
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
⊢ natDegree (List.prod []) ≤ List.sum (List.map natDegree [])
[PROOFSTEP]
simp
[GOAL]
case cons
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
hd : S[X]
tl : List S[X]
IH : natDegree (List.prod tl) ≤ List.sum (List.map natDegree tl)
⊢ natDegree (List.prod (hd :: tl)) ≤ List.sum (List.map natDegree (hd :: tl))
[PROOFSTEP]
simpa using natDegree_mul_le.trans (add_le_add_left IH _)
[GOAL]
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
l : List S[X]
⊢ degree (List.prod l) ≤ List.sum (List.map degree l)
[PROOFSTEP]
induction' l with hd tl IH
[GOAL]
case nil
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
⊢ degree (List.prod []) ≤ List.sum (List.map degree [])
[PROOFSTEP]
simp
[GOAL]
case cons
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
hd : S[X]
tl : List S[X]
IH : degree (List.prod tl) ≤ List.sum (List.map degree tl)
⊢ degree (List.prod (hd :: tl)) ≤ List.sum (List.map degree (hd :: tl))
[PROOFSTEP]
simpa using (degree_mul_le _ _).trans (add_le_add_left IH _)
[GOAL]
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
l : List S[X]
n : ℕ
hl : ∀ (p : S[X]), p ∈ l → natDegree p ≤ n
⊢ coeff (List.prod l) (List.length l * n) = List.prod (List.map (fun p => coeff p n) l)
[PROOFSTEP]
induction' l with hd tl IH
[GOAL]
case nil
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
l : List S[X]
n : ℕ
hl✝ : ∀ (p : S[X]), p ∈ l → natDegree p ≤ n
hl : ∀ (p : S[X]), p ∈ [] → natDegree p ≤ n
⊢ coeff (List.prod []) (List.length [] * n) = List.prod (List.map (fun p => coeff p n) [])
[PROOFSTEP]
simp
[GOAL]
case cons
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
l : List S[X]
n : ℕ
hl✝ : ∀ (p : S[X]), p ∈ l → natDegree p ≤ n
hd : S[X]
tl : List S[X]
IH :
  (∀ (p : S[X]), p ∈ tl → natDegree p ≤ n) →
    coeff (List.prod tl) (List.length tl * n) = List.prod (List.map (fun p => coeff p n) tl)
hl : ∀ (p : S[X]), p ∈ hd :: tl → natDegree p ≤ n
⊢ coeff (List.prod (hd :: tl)) (List.length (hd :: tl) * n) = List.prod (List.map (fun p => coeff p n) (hd :: tl))
[PROOFSTEP]
have hl' : ∀ p ∈ tl, natDegree p ≤ n := fun p hp => hl p (List.mem_cons_of_mem _ hp)
[GOAL]
case cons
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
l : List S[X]
n : ℕ
hl✝ : ∀ (p : S[X]), p ∈ l → natDegree p ≤ n
hd : S[X]
tl : List S[X]
IH :
  (∀ (p : S[X]), p ∈ tl → natDegree p ≤ n) →
    coeff (List.prod tl) (List.length tl * n) = List.prod (List.map (fun p => coeff p n) tl)
hl : ∀ (p : S[X]), p ∈ hd :: tl → natDegree p ≤ n
hl' : ∀ (p : S[X]), p ∈ tl → natDegree p ≤ n
⊢ coeff (List.prod (hd :: tl)) (List.length (hd :: tl) * n) = List.prod (List.map (fun p => coeff p n) (hd :: tl))
[PROOFSTEP]
simp only [List.prod_cons, List.map, List.length]
[GOAL]
case cons
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
l : List S[X]
n : ℕ
hl✝ : ∀ (p : S[X]), p ∈ l → natDegree p ≤ n
hd : S[X]
tl : List S[X]
IH :
  (∀ (p : S[X]), p ∈ tl → natDegree p ≤ n) →
    coeff (List.prod tl) (List.length tl * n) = List.prod (List.map (fun p => coeff p n) tl)
hl : ∀ (p : S[X]), p ∈ hd :: tl → natDegree p ≤ n
hl' : ∀ (p : S[X]), p ∈ tl → natDegree p ≤ n
⊢ coeff (hd * List.prod tl) ((List.length tl + 1) * n) = coeff hd n * List.prod (List.map (fun p => coeff p n) tl)
[PROOFSTEP]
rw [add_mul, one_mul, add_comm, ← IH hl', mul_comm tl.length]
[GOAL]
case cons
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
l : List S[X]
n : ℕ
hl✝ : ∀ (p : S[X]), p ∈ l → natDegree p ≤ n
hd : S[X]
tl : List S[X]
IH :
  (∀ (p : S[X]), p ∈ tl → natDegree p ≤ n) →
    coeff (List.prod tl) (List.length tl * n) = List.prod (List.map (fun p => coeff p n) tl)
hl : ∀ (p : S[X]), p ∈ hd :: tl → natDegree p ≤ n
hl' : ∀ (p : S[X]), p ∈ tl → natDegree p ≤ n
⊢ coeff (hd * List.prod tl) (n + n * List.length tl) = coeff hd n * coeff (List.prod tl) (n * List.length tl)
[PROOFSTEP]
have h : natDegree tl.prod ≤ n * tl.length :=
  by
  refine' (natDegree_list_prod_le _).trans _
  rw [← tl.length_map natDegree, mul_comm]
  refine' List.sum_le_card_nsmul _ _ _
  simpa using hl'
[GOAL]
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
l : List S[X]
n : ℕ
hl✝ : ∀ (p : S[X]), p ∈ l → natDegree p ≤ n
hd : S[X]
tl : List S[X]
IH :
  (∀ (p : S[X]), p ∈ tl → natDegree p ≤ n) →
    coeff (List.prod tl) (List.length tl * n) = List.prod (List.map (fun p => coeff p n) tl)
hl : ∀ (p : S[X]), p ∈ hd :: tl → natDegree p ≤ n
hl' : ∀ (p : S[X]), p ∈ tl → natDegree p ≤ n
⊢ natDegree (List.prod tl) ≤ n * List.length tl
[PROOFSTEP]
refine' (natDegree_list_prod_le _).trans _
[GOAL]
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
l : List S[X]
n : ℕ
hl✝ : ∀ (p : S[X]), p ∈ l → natDegree p ≤ n
hd : S[X]
tl : List S[X]
IH :
  (∀ (p : S[X]), p ∈ tl → natDegree p ≤ n) →
    coeff (List.prod tl) (List.length tl * n) = List.prod (List.map (fun p => coeff p n) tl)
hl : ∀ (p : S[X]), p ∈ hd :: tl → natDegree p ≤ n
hl' : ∀ (p : S[X]), p ∈ tl → natDegree p ≤ n
⊢ List.sum (List.map natDegree tl) ≤ n * List.length tl
[PROOFSTEP]
rw [← tl.length_map natDegree, mul_comm]
[GOAL]
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
l : List S[X]
n : ℕ
hl✝ : ∀ (p : S[X]), p ∈ l → natDegree p ≤ n
hd : S[X]
tl : List S[X]
IH :
  (∀ (p : S[X]), p ∈ tl → natDegree p ≤ n) →
    coeff (List.prod tl) (List.length tl * n) = List.prod (List.map (fun p => coeff p n) tl)
hl : ∀ (p : S[X]), p ∈ hd :: tl → natDegree p ≤ n
hl' : ∀ (p : S[X]), p ∈ tl → natDegree p ≤ n
⊢ List.sum (List.map natDegree tl) ≤ List.length (List.map natDegree tl) * n
[PROOFSTEP]
refine' List.sum_le_card_nsmul _ _ _
[GOAL]
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
l : List S[X]
n : ℕ
hl✝ : ∀ (p : S[X]), p ∈ l → natDegree p ≤ n
hd : S[X]
tl : List S[X]
IH :
  (∀ (p : S[X]), p ∈ tl → natDegree p ≤ n) →
    coeff (List.prod tl) (List.length tl * n) = List.prod (List.map (fun p => coeff p n) tl)
hl : ∀ (p : S[X]), p ∈ hd :: tl → natDegree p ≤ n
hl' : ∀ (p : S[X]), p ∈ tl → natDegree p ≤ n
⊢ ∀ (x : ℕ), x ∈ List.map natDegree tl → x ≤ n
[PROOFSTEP]
simpa using hl'
[GOAL]
case cons
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
l : List S[X]
n : ℕ
hl✝ : ∀ (p : S[X]), p ∈ l → natDegree p ≤ n
hd : S[X]
tl : List S[X]
IH :
  (∀ (p : S[X]), p ∈ tl → natDegree p ≤ n) →
    coeff (List.prod tl) (List.length tl * n) = List.prod (List.map (fun p => coeff p n) tl)
hl : ∀ (p : S[X]), p ∈ hd :: tl → natDegree p ≤ n
hl' : ∀ (p : S[X]), p ∈ tl → natDegree p ≤ n
h : natDegree (List.prod tl) ≤ n * List.length tl
⊢ coeff (hd * List.prod tl) (n + n * List.length tl) = coeff hd n * coeff (List.prod tl) (n * List.length tl)
[PROOFSTEP]
have hdn : natDegree hd ≤ n := hl _ (List.mem_cons_self _ _)
[GOAL]
case cons
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
l : List S[X]
n : ℕ
hl✝ : ∀ (p : S[X]), p ∈ l → natDegree p ≤ n
hd : S[X]
tl : List S[X]
IH :
  (∀ (p : S[X]), p ∈ tl → natDegree p ≤ n) →
    coeff (List.prod tl) (List.length tl * n) = List.prod (List.map (fun p => coeff p n) tl)
hl : ∀ (p : S[X]), p ∈ hd :: tl → natDegree p ≤ n
hl' : ∀ (p : S[X]), p ∈ tl → natDegree p ≤ n
h : natDegree (List.prod tl) ≤ n * List.length tl
hdn : natDegree hd ≤ n
⊢ coeff (hd * List.prod tl) (n + n * List.length tl) = coeff hd n * coeff (List.prod tl) (n * List.length tl)
[PROOFSTEP]
rcases hdn.eq_or_lt with (rfl | hdn')
[GOAL]
case cons.inl
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
l : List S[X]
hd : S[X]
tl : List S[X]
hl✝ : ∀ (p : S[X]), p ∈ l → natDegree p ≤ natDegree hd
IH :
  (∀ (p : S[X]), p ∈ tl → natDegree p ≤ natDegree hd) →
    coeff (List.prod tl) (List.length tl * natDegree hd) = List.prod (List.map (fun p => coeff p (natDegree hd)) tl)
hl : ∀ (p : S[X]), p ∈ hd :: tl → natDegree p ≤ natDegree hd
hl' : ∀ (p : S[X]), p ∈ tl → natDegree p ≤ natDegree hd
h : natDegree (List.prod tl) ≤ natDegree hd * List.length tl
hdn : natDegree hd ≤ natDegree hd
⊢ coeff (hd * List.prod tl) (natDegree hd + natDegree hd * List.length tl) =
    coeff hd (natDegree hd) * coeff (List.prod tl) (natDegree hd * List.length tl)
[PROOFSTEP]
cases' h.eq_or_lt with h' h'
[GOAL]
case cons.inl.inl
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
l : List S[X]
hd : S[X]
tl : List S[X]
hl✝ : ∀ (p : S[X]), p ∈ l → natDegree p ≤ natDegree hd
IH :
  (∀ (p : S[X]), p ∈ tl → natDegree p ≤ natDegree hd) →
    coeff (List.prod tl) (List.length tl * natDegree hd) = List.prod (List.map (fun p => coeff p (natDegree hd)) tl)
hl : ∀ (p : S[X]), p ∈ hd :: tl → natDegree p ≤ natDegree hd
hl' : ∀ (p : S[X]), p ∈ tl → natDegree p ≤ natDegree hd
h : natDegree (List.prod tl) ≤ natDegree hd * List.length tl
hdn : natDegree hd ≤ natDegree hd
h' : natDegree (List.prod tl) = natDegree hd * List.length tl
⊢ coeff (hd * List.prod tl) (natDegree hd + natDegree hd * List.length tl) =
    coeff hd (natDegree hd) * coeff (List.prod tl) (natDegree hd * List.length tl)
[PROOFSTEP]
rw [← h', coeff_mul_degree_add_degree, leadingCoeff, leadingCoeff]
[GOAL]
case cons.inl.inr
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
l : List S[X]
hd : S[X]
tl : List S[X]
hl✝ : ∀ (p : S[X]), p ∈ l → natDegree p ≤ natDegree hd
IH :
  (∀ (p : S[X]), p ∈ tl → natDegree p ≤ natDegree hd) →
    coeff (List.prod tl) (List.length tl * natDegree hd) = List.prod (List.map (fun p => coeff p (natDegree hd)) tl)
hl : ∀ (p : S[X]), p ∈ hd :: tl → natDegree p ≤ natDegree hd
hl' : ∀ (p : S[X]), p ∈ tl → natDegree p ≤ natDegree hd
h : natDegree (List.prod tl) ≤ natDegree hd * List.length tl
hdn : natDegree hd ≤ natDegree hd
h' : natDegree (List.prod tl) < natDegree hd * List.length tl
⊢ coeff (hd * List.prod tl) (natDegree hd + natDegree hd * List.length tl) =
    coeff hd (natDegree hd) * coeff (List.prod tl) (natDegree hd * List.length tl)
[PROOFSTEP]
rw [coeff_eq_zero_of_natDegree_lt, coeff_eq_zero_of_natDegree_lt h', mul_zero]
[GOAL]
case cons.inl.inr
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
l : List S[X]
hd : S[X]
tl : List S[X]
hl✝ : ∀ (p : S[X]), p ∈ l → natDegree p ≤ natDegree hd
IH :
  (∀ (p : S[X]), p ∈ tl → natDegree p ≤ natDegree hd) →
    coeff (List.prod tl) (List.length tl * natDegree hd) = List.prod (List.map (fun p => coeff p (natDegree hd)) tl)
hl : ∀ (p : S[X]), p ∈ hd :: tl → natDegree p ≤ natDegree hd
hl' : ∀ (p : S[X]), p ∈ tl → natDegree p ≤ natDegree hd
h : natDegree (List.prod tl) ≤ natDegree hd * List.length tl
hdn : natDegree hd ≤ natDegree hd
h' : natDegree (List.prod tl) < natDegree hd * List.length tl
⊢ natDegree (hd * List.prod tl) < natDegree hd + natDegree hd * List.length tl
[PROOFSTEP]
exact natDegree_mul_le.trans_lt (add_lt_add_left h' _)
[GOAL]
case cons.inr
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
l : List S[X]
n : ℕ
hl✝ : ∀ (p : S[X]), p ∈ l → natDegree p ≤ n
hd : S[X]
tl : List S[X]
IH :
  (∀ (p : S[X]), p ∈ tl → natDegree p ≤ n) →
    coeff (List.prod tl) (List.length tl * n) = List.prod (List.map (fun p => coeff p n) tl)
hl : ∀ (p : S[X]), p ∈ hd :: tl → natDegree p ≤ n
hl' : ∀ (p : S[X]), p ∈ tl → natDegree p ≤ n
h : natDegree (List.prod tl) ≤ n * List.length tl
hdn : natDegree hd ≤ n
hdn' : natDegree hd < n
⊢ coeff (hd * List.prod tl) (n + n * List.length tl) = coeff hd n * coeff (List.prod tl) (n * List.length tl)
[PROOFSTEP]
rw [coeff_eq_zero_of_natDegree_lt hdn', coeff_eq_zero_of_natDegree_lt, zero_mul]
[GOAL]
case cons.inr
R : Type u
ι : Type w
s : Finset ι
S : Type u_1
inst✝ : Semiring S
l : List S[X]
n : ℕ
hl✝ : ∀ (p : S[X]), p ∈ l → natDegree p ≤ n
hd : S[X]
tl : List S[X]
IH :
  (∀ (p : S[X]), p ∈ tl → natDegree p ≤ n) →
    coeff (List.prod tl) (List.length tl * n) = List.prod (List.map (fun p => coeff p n) tl)
hl : ∀ (p : S[X]), p ∈ hd :: tl → natDegree p ≤ n
hl' : ∀ (p : S[X]), p ∈ tl → natDegree p ≤ n
h : natDegree (List.prod tl) ≤ n * List.length tl
hdn : natDegree hd ≤ n
hdn' : natDegree hd < n
⊢ natDegree (hd * List.prod tl) < n + n * List.length tl
[PROOFSTEP]
exact natDegree_mul_le.trans_lt (add_lt_add_of_lt_of_le hdn' h)
[GOAL]
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
⊢ ∀ (a : List R[X]),
    natDegree (prod (Quotient.mk (List.isSetoid R[X]) a)) ≤
      Multiset.sum (Multiset.map natDegree (Quotient.mk (List.isSetoid R[X]) a))
[PROOFSTEP]
simpa using natDegree_list_prod_le
[GOAL]
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
⊢ natDegree (∏ i in s, f i) ≤ ∑ i in s, natDegree (f i)
[PROOFSTEP]
simpa using natDegree_multiset_prod_le (s.1.map f)
[GOAL]
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
⊢ ∀ (a : List R[X]),
    degree (prod (Quotient.mk (List.isSetoid R[X]) a)) ≤
      Multiset.sum (Multiset.map degree (Quotient.mk (List.isSetoid R[X]) a))
[PROOFSTEP]
simpa using degree_list_prod_le
[GOAL]
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
⊢ degree (∏ i in s, f i) ≤ ∑ i in s, degree (f i)
[PROOFSTEP]
simpa only [Multiset.map_map] using degree_multiset_prod_le (s.1.map f)
[GOAL]
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : prod (Multiset.map leadingCoeff t) ≠ 0
⊢ leadingCoeff (prod t) = prod (Multiset.map leadingCoeff t)
[PROOFSTEP]
induction' t using Multiset.induction_on with a t ih
[GOAL]
case empty
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h✝ : prod (Multiset.map leadingCoeff t) ≠ 0
h : prod (Multiset.map leadingCoeff 0) ≠ 0
⊢ leadingCoeff (prod 0) = prod (Multiset.map leadingCoeff 0)
[PROOFSTEP]
simp
[GOAL]
case cons
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t✝ : Multiset R[X]
h✝ : prod (Multiset.map leadingCoeff t✝) ≠ 0
a : R[X]
t : Multiset R[X]
ih : prod (Multiset.map leadingCoeff t) ≠ 0 → leadingCoeff (prod t) = prod (Multiset.map leadingCoeff t)
h : prod (Multiset.map leadingCoeff (a ::ₘ t)) ≠ 0
⊢ leadingCoeff (prod (a ::ₘ t)) = prod (Multiset.map leadingCoeff (a ::ₘ t))
[PROOFSTEP]
simp only [Multiset.map_cons, Multiset.prod_cons] at h ⊢
[GOAL]
case cons
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t✝ : Multiset R[X]
h✝ : prod (Multiset.map leadingCoeff t✝) ≠ 0
a : R[X]
t : Multiset R[X]
ih : prod (Multiset.map leadingCoeff t) ≠ 0 → leadingCoeff (prod t) = prod (Multiset.map leadingCoeff t)
h : leadingCoeff a * prod (Multiset.map leadingCoeff t) ≠ 0
⊢ leadingCoeff (a * prod t) = leadingCoeff a * prod (Multiset.map leadingCoeff t)
[PROOFSTEP]
rw [Polynomial.leadingCoeff_mul']
[GOAL]
case cons
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t✝ : Multiset R[X]
h✝ : prod (Multiset.map leadingCoeff t✝) ≠ 0
a : R[X]
t : Multiset R[X]
ih : prod (Multiset.map leadingCoeff t) ≠ 0 → leadingCoeff (prod t) = prod (Multiset.map leadingCoeff t)
h : leadingCoeff a * prod (Multiset.map leadingCoeff t) ≠ 0
⊢ leadingCoeff a * leadingCoeff (prod t) = leadingCoeff a * prod (Multiset.map leadingCoeff t)
[PROOFSTEP]
rw [ih]
[GOAL]
case cons
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t✝ : Multiset R[X]
h✝ : prod (Multiset.map leadingCoeff t✝) ≠ 0
a : R[X]
t : Multiset R[X]
ih : prod (Multiset.map leadingCoeff t) ≠ 0 → leadingCoeff (prod t) = prod (Multiset.map leadingCoeff t)
h : leadingCoeff a * prod (Multiset.map leadingCoeff t) ≠ 0
⊢ prod (Multiset.map leadingCoeff t) ≠ 0
[PROOFSTEP]
simp [*]
[GOAL]
case cons
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t✝ : Multiset R[X]
h✝ : prod (Multiset.map leadingCoeff t✝) ≠ 0
a : R[X]
t : Multiset R[X]
ih : prod (Multiset.map leadingCoeff t) ≠ 0 → leadingCoeff (prod t) = prod (Multiset.map leadingCoeff t)
h : leadingCoeff a * prod (Multiset.map leadingCoeff t) ≠ 0
⊢ ¬prod (Multiset.map leadingCoeff t) = 0
[PROOFSTEP]
apply right_ne_zero_of_mul h
[GOAL]
case cons
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t✝ : Multiset R[X]
h✝ : prod (Multiset.map leadingCoeff t✝) ≠ 0
a : R[X]
t : Multiset R[X]
ih : prod (Multiset.map leadingCoeff t) ≠ 0 → leadingCoeff (prod t) = prod (Multiset.map leadingCoeff t)
h : leadingCoeff a * prod (Multiset.map leadingCoeff t) ≠ 0
⊢ leadingCoeff a * leadingCoeff (prod t) ≠ 0
[PROOFSTEP]
rw [ih]
[GOAL]
case cons
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t✝ : Multiset R[X]
h✝ : prod (Multiset.map leadingCoeff t✝) ≠ 0
a : R[X]
t : Multiset R[X]
ih : prod (Multiset.map leadingCoeff t) ≠ 0 → leadingCoeff (prod t) = prod (Multiset.map leadingCoeff t)
h : leadingCoeff a * prod (Multiset.map leadingCoeff t) ≠ 0
⊢ leadingCoeff a * prod (Multiset.map leadingCoeff t) ≠ 0
case cons
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t✝ : Multiset R[X]
h✝ : prod (Multiset.map leadingCoeff t✝) ≠ 0
a : R[X]
t : Multiset R[X]
ih : prod (Multiset.map leadingCoeff t) ≠ 0 → leadingCoeff (prod t) = prod (Multiset.map leadingCoeff t)
h : leadingCoeff a * prod (Multiset.map leadingCoeff t) ≠ 0
⊢ prod (Multiset.map leadingCoeff t) ≠ 0
[PROOFSTEP]
simp [*]
[GOAL]
case cons
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t✝ : Multiset R[X]
h✝ : prod (Multiset.map leadingCoeff t✝) ≠ 0
a : R[X]
t : Multiset R[X]
ih : prod (Multiset.map leadingCoeff t) ≠ 0 → leadingCoeff (prod t) = prod (Multiset.map leadingCoeff t)
h : leadingCoeff a * prod (Multiset.map leadingCoeff t) ≠ 0
⊢ prod (Multiset.map leadingCoeff t) ≠ 0
[PROOFSTEP]
apply right_ne_zero_of_mul h
[GOAL]
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∏ i in s, leadingCoeff (f i) ≠ 0
⊢ leadingCoeff (∏ i in s, f i) = ∏ i in s, leadingCoeff (f i)
[PROOFSTEP]
simpa using leadingCoeff_multiset_prod' (s.1.map f) (by simpa using h)
[GOAL]
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∏ i in s, leadingCoeff (f i) ≠ 0
⊢ prod (Multiset.map leadingCoeff (Multiset.map f s.val)) ≠ 0
[PROOFSTEP]
simpa using h
[GOAL]
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : prod (Multiset.map (fun f => leadingCoeff f) t) ≠ 0
⊢ natDegree (prod t) = Multiset.sum (Multiset.map (fun f => natDegree f) t)
[PROOFSTEP]
revert h
[GOAL]
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
⊢ prod (Multiset.map (fun f => leadingCoeff f) t) ≠ 0 →
    natDegree (prod t) = Multiset.sum (Multiset.map (fun f => natDegree f) t)
[PROOFSTEP]
refine' Multiset.induction_on t _ fun a t ih ht => _
[GOAL]
case refine'_1
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
⊢ prod (Multiset.map (fun f => leadingCoeff f) 0) ≠ 0 →
    natDegree (prod 0) = Multiset.sum (Multiset.map (fun f => natDegree f) 0)
[PROOFSTEP]
simp
[GOAL]
case refine'_2
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t✝ : Multiset R[X]
a : R[X]
t : Multiset R[X]
ih :
  prod (Multiset.map (fun f => leadingCoeff f) t) ≠ 0 →
    natDegree (prod t) = Multiset.sum (Multiset.map (fun f => natDegree f) t)
ht : prod (Multiset.map (fun f => leadingCoeff f) (a ::ₘ t)) ≠ 0
⊢ natDegree (prod (a ::ₘ t)) = Multiset.sum (Multiset.map (fun f => natDegree f) (a ::ₘ t))
[PROOFSTEP]
rw [Multiset.map_cons, Multiset.prod_cons] at ht ⊢
[GOAL]
case refine'_2
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t✝ : Multiset R[X]
a : R[X]
t : Multiset R[X]
ih :
  prod (Multiset.map (fun f => leadingCoeff f) t) ≠ 0 →
    natDegree (prod t) = Multiset.sum (Multiset.map (fun f => natDegree f) t)
ht : leadingCoeff a * prod (Multiset.map (fun f => leadingCoeff f) t) ≠ 0
⊢ natDegree (a * prod t) = Multiset.sum (natDegree a ::ₘ Multiset.map (fun f => natDegree f) t)
[PROOFSTEP]
rw [Multiset.sum_cons, Polynomial.natDegree_mul', ih]
[GOAL]
case refine'_2
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t✝ : Multiset R[X]
a : R[X]
t : Multiset R[X]
ih :
  prod (Multiset.map (fun f => leadingCoeff f) t) ≠ 0 →
    natDegree (prod t) = Multiset.sum (Multiset.map (fun f => natDegree f) t)
ht : leadingCoeff a * prod (Multiset.map (fun f => leadingCoeff f) t) ≠ 0
⊢ prod (Multiset.map (fun f => leadingCoeff f) t) ≠ 0
[PROOFSTEP]
apply right_ne_zero_of_mul ht
[GOAL]
case refine'_2
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t✝ : Multiset R[X]
a : R[X]
t : Multiset R[X]
ih :
  prod (Multiset.map (fun f => leadingCoeff f) t) ≠ 0 →
    natDegree (prod t) = Multiset.sum (Multiset.map (fun f => natDegree f) t)
ht : leadingCoeff a * prod (Multiset.map (fun f => leadingCoeff f) t) ≠ 0
⊢ leadingCoeff a * leadingCoeff (prod t) ≠ 0
[PROOFSTEP]
rwa [Polynomial.leadingCoeff_multiset_prod']
[GOAL]
case refine'_2.h
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t✝ : Multiset R[X]
a : R[X]
t : Multiset R[X]
ih :
  prod (Multiset.map (fun f => leadingCoeff f) t) ≠ 0 →
    natDegree (prod t) = Multiset.sum (Multiset.map (fun f => natDegree f) t)
ht : leadingCoeff a * prod (Multiset.map (fun f => leadingCoeff f) t) ≠ 0
⊢ prod (Multiset.map leadingCoeff t) ≠ 0
[PROOFSTEP]
apply right_ne_zero_of_mul ht
[GOAL]
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∏ i in s, leadingCoeff (f i) ≠ 0
⊢ natDegree (∏ i in s, f i) = ∑ i in s, natDegree (f i)
[PROOFSTEP]
simpa using natDegree_multiset_prod' (s.1.map f) (by simpa using h)
[GOAL]
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∏ i in s, leadingCoeff (f i) ≠ 0
⊢ prod (Multiset.map (fun f => leadingCoeff f) (Multiset.map f s.val)) ≠ 0
[PROOFSTEP]
simpa using h
[GOAL]
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∀ (f : R[X]), f ∈ t → Monic f
⊢ natDegree (prod t) = Multiset.sum (Multiset.map natDegree t)
[PROOFSTEP]
nontriviality R
[GOAL]
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∀ (f : R[X]), f ∈ t → Monic f
✝ : Nontrivial R
⊢ natDegree (prod t) = Multiset.sum (Multiset.map natDegree t)
[PROOFSTEP]
apply natDegree_multiset_prod'
[GOAL]
case h
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∀ (f : R[X]), f ∈ t → Monic f
✝ : Nontrivial R
⊢ prod (Multiset.map (fun f => leadingCoeff f) t) ≠ 0
[PROOFSTEP]
suffices (t.map fun f => leadingCoeff f).prod = 1 by
  rw [this]
  simp
[GOAL]
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∀ (f : R[X]), f ∈ t → Monic f
✝ : Nontrivial R
this : prod (Multiset.map (fun f => leadingCoeff f) t) = 1
⊢ prod (Multiset.map (fun f => leadingCoeff f) t) ≠ 0
[PROOFSTEP]
rw [this]
[GOAL]
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∀ (f : R[X]), f ∈ t → Monic f
✝ : Nontrivial R
this : prod (Multiset.map (fun f => leadingCoeff f) t) = 1
⊢ 1 ≠ 0
[PROOFSTEP]
simp
[GOAL]
case h
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∀ (f : R[X]), f ∈ t → Monic f
✝ : Nontrivial R
⊢ prod (Multiset.map (fun f => leadingCoeff f) t) = 1
[PROOFSTEP]
convert prod_replicate (Multiset.card t) (1 : R)
[GOAL]
case h.e'_2.h.e'_3
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∀ (f : R[X]), f ∈ t → Monic f
✝ : Nontrivial R
⊢ Multiset.map (fun f => leadingCoeff f) t = replicate (↑Multiset.card t) 1
[PROOFSTEP]
simp only [eq_replicate, Multiset.card_map, eq_self_iff_true, true_and_iff]
[GOAL]
case h.e'_2.h.e'_3
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∀ (f : R[X]), f ∈ t → Monic f
✝ : Nontrivial R
⊢ ∀ (b : R), b ∈ Multiset.map (fun f => leadingCoeff f) t → b = 1
[PROOFSTEP]
rintro i hi
[GOAL]
case h.e'_2.h.e'_3
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∀ (f : R[X]), f ∈ t → Monic f
✝ : Nontrivial R
i : R
hi : i ∈ Multiset.map (fun f => leadingCoeff f) t
⊢ i = 1
[PROOFSTEP]
obtain ⟨i, hi, rfl⟩ := Multiset.mem_map.mp hi
[GOAL]
case h.e'_2.h.e'_3.intro.intro
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∀ (f : R[X]), f ∈ t → Monic f
✝ : Nontrivial R
i : R[X]
hi✝ : i ∈ t
hi : leadingCoeff i ∈ Multiset.map (fun f => leadingCoeff f) t
⊢ leadingCoeff i = 1
[PROOFSTEP]
apply h
[GOAL]
case h.e'_2.h.e'_3.intro.intro.a
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∀ (f : R[X]), f ∈ t → Monic f
✝ : Nontrivial R
i : R[X]
hi✝ : i ∈ t
hi : leadingCoeff i ∈ Multiset.map (fun f => leadingCoeff f) t
⊢ i ∈ t
[PROOFSTEP]
assumption
[GOAL]
case h.e'_3
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∀ (f : R[X]), f ∈ t → Monic f
✝ : Nontrivial R
⊢ 1 = 1 ^ ↑Multiset.card t
[PROOFSTEP]
simp
[GOAL]
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∀ (i : ι), i ∈ s → Monic (f i)
⊢ natDegree (∏ i in s, f i) = ∑ i in s, natDegree (f i)
[PROOFSTEP]
simpa using natDegree_multiset_prod_of_monic (s.1.map f) (by simpa using h)
[GOAL]
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
h : ∀ (i : ι), i ∈ s → Monic (f i)
⊢ ∀ (f_1 : R[X]), f_1 ∈ Multiset.map f s.val → Monic f_1
[PROOFSTEP]
simpa using h
[GOAL]
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
n : ℕ
hl : ∀ (p : R[X]), p ∈ t → natDegree p ≤ n
⊢ coeff (prod t) (↑Multiset.card t * n) = prod (Multiset.map (fun p => coeff p n) t)
[PROOFSTEP]
induction t using Quotient.inductionOn
[GOAL]
case h
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
n : ℕ
a✝ : List R[X]
hl : ∀ (p : R[X]), p ∈ Quotient.mk (List.isSetoid R[X]) a✝ → natDegree p ≤ n
⊢ coeff (prod (Quotient.mk (List.isSetoid R[X]) a✝)) (↑Multiset.card (Quotient.mk (List.isSetoid R[X]) a✝) * n) =
    prod (Multiset.map (fun p => coeff p n) (Quotient.mk (List.isSetoid R[X]) a✝))
[PROOFSTEP]
simpa using coeff_list_prod_of_natDegree_le _ _ hl
[GOAL]
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f✝ : ι → R[X]
t : Multiset R[X]
f : ι → R[X]
n : ℕ
h : ∀ (p : ι), p ∈ s → natDegree (f p) ≤ n
⊢ coeff (∏ i in s, f i) (Finset.card s * n) = ∏ i in s, coeff (f i) n
[PROOFSTEP]
cases' s with l hl
[GOAL]
case mk
R : Type u
ι : Type w
inst✝ : CommSemiring R
f✝ : ι → R[X]
t : Multiset R[X]
f : ι → R[X]
n : ℕ
l : Multiset ι
hl : Nodup l
h : ∀ (p : ι), p ∈ { val := l, nodup := hl } → natDegree (f p) ≤ n
⊢ coeff (∏ i in { val := l, nodup := hl }, f i) (Finset.card { val := l, nodup := hl } * n) =
    ∏ i in { val := l, nodup := hl }, coeff (f i) n
[PROOFSTEP]
convert coeff_multiset_prod_of_natDegree_le (l.map f) n ?_
[GOAL]
case h.e'_2.h.e'_4.h.e'_5
R : Type u
ι : Type w
inst✝ : CommSemiring R
f✝ : ι → R[X]
t : Multiset R[X]
f : ι → R[X]
n : ℕ
l : Multiset ι
hl : Nodup l
h : ∀ (p : ι), p ∈ { val := l, nodup := hl } → natDegree (f p) ≤ n
⊢ Finset.card { val := l, nodup := hl } = ↑Multiset.card (Multiset.map f l)
[PROOFSTEP]
simp
[GOAL]
case h.e'_3
R : Type u
ι : Type w
inst✝ : CommSemiring R
f✝ : ι → R[X]
t : Multiset R[X]
f : ι → R[X]
n : ℕ
l : Multiset ι
hl : Nodup l
h : ∀ (p : ι), p ∈ { val := l, nodup := hl } → natDegree (f p) ≤ n
⊢ ∏ i in { val := l, nodup := hl }, coeff (f i) n = prod (Multiset.map (fun p => coeff p n) (Multiset.map f l))
[PROOFSTEP]
simp
[GOAL]
case mk
R : Type u
ι : Type w
inst✝ : CommSemiring R
f✝ : ι → R[X]
t : Multiset R[X]
f : ι → R[X]
n : ℕ
l : Multiset ι
hl : Nodup l
h : ∀ (p : ι), p ∈ { val := l, nodup := hl } → natDegree (f p) ≤ n
⊢ ∀ (p : R[X]), p ∈ Multiset.map f l → natDegree p ≤ n
[PROOFSTEP]
simpa using h
[GOAL]
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
⊢ coeff (prod t) 0 = prod (Multiset.map (fun f => coeff f 0) t)
[PROOFSTEP]
refine' Multiset.induction_on t _ fun a t ht => _
[GOAL]
case refine'_1
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
⊢ coeff (prod 0) 0 = prod (Multiset.map (fun f => coeff f 0) 0)
[PROOFSTEP]
simp
[GOAL]
case refine'_2
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t✝ : Multiset R[X]
a : R[X]
t : Multiset R[X]
ht : coeff (prod t) 0 = prod (Multiset.map (fun f => coeff f 0) t)
⊢ coeff (prod (a ::ₘ t)) 0 = prod (Multiset.map (fun f => coeff f 0) (a ::ₘ t))
[PROOFSTEP]
rw [Multiset.prod_cons, Multiset.map_cons, Multiset.prod_cons, Polynomial.mul_coeff_zero, ht]
[GOAL]
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommSemiring R
f : ι → R[X]
t : Multiset R[X]
⊢ coeff (∏ i in s, f i) 0 = ∏ i in s, coeff (f i) 0
[PROOFSTEP]
simpa using coeff_zero_multiset_prod (s.1.map f)
[GOAL]
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommRing R
t : Multiset R
⊢ nextCoeff (prod (Multiset.map (fun x => X - ↑C x) t)) = -Multiset.sum t
[PROOFSTEP]
rw [nextCoeff_multiset_prod]
[GOAL]
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommRing R
t : Multiset R
⊢ Multiset.sum (Multiset.map (fun i => nextCoeff (X - ↑C i)) t) = -Multiset.sum t
[PROOFSTEP]
simp only [nextCoeff_X_sub_C]
[GOAL]
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommRing R
t : Multiset R
⊢ Multiset.sum (Multiset.map (fun x => -x) t) = -Multiset.sum t
[PROOFSTEP]
exact t.sum_hom (-AddMonoidHom.id R)
[GOAL]
case h
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommRing R
t : Multiset R
⊢ ∀ (i : R), i ∈ t → Monic (X - ↑C i)
[PROOFSTEP]
intros
[GOAL]
case h
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommRing R
t : Multiset R
i✝ : R
a✝ : i✝ ∈ t
⊢ Monic (X - ↑C i✝)
[PROOFSTEP]
apply monic_X_sub_C
[GOAL]
R : Type u
ι : Type w
s✝ : Finset ι
inst✝ : CommRing R
s : Finset ι
f : ι → R
⊢ nextCoeff (∏ i in s, (X - ↑C (f i))) = -∑ i in s, f i
[PROOFSTEP]
simpa using multiset_prod_X_sub_C_nextCoeff (s.1.map f)
[GOAL]
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommRing R
t : Multiset R
ht : 0 < ↑Multiset.card t
⊢ coeff (prod (Multiset.map (fun x => X - ↑C x) t)) (↑Multiset.card t - 1) = -Multiset.sum t
[PROOFSTEP]
nontriviality R
[GOAL]
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommRing R
t : Multiset R
ht : 0 < ↑Multiset.card t
✝ : Nontrivial R
⊢ coeff (prod (Multiset.map (fun x => X - ↑C x) t)) (↑Multiset.card t - 1) = -Multiset.sum t
[PROOFSTEP]
convert multiset_prod_X_sub_C_nextCoeff (by assumption)
[GOAL]
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommRing R
t : Multiset R
ht : 0 < ↑Multiset.card t
✝ : Nontrivial R
⊢ Multiset ?m.927417
[PROOFSTEP]
assumption
[GOAL]
case h.e'_2
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommRing R
t : Multiset R
ht : 0 < ↑Multiset.card t
✝ : Nontrivial R
⊢ coeff (prod (Multiset.map (fun x => X - ↑C x) t)) (↑Multiset.card t - 1) =
    nextCoeff (prod (Multiset.map (fun x => X - ↑C x) t))
[PROOFSTEP]
rw [nextCoeff]
[GOAL]
case h.e'_2
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommRing R
t : Multiset R
ht : 0 < ↑Multiset.card t
✝ : Nontrivial R
⊢ coeff (prod (Multiset.map (fun x => X - ↑C x) t)) (↑Multiset.card t - 1) =
    if natDegree (prod (Multiset.map (fun x => X - ↑C x) t)) = 0 then 0
    else coeff (prod (Multiset.map (fun x => X - ↑C x) t)) (natDegree (prod (Multiset.map (fun x => X - ↑C x) t)) - 1)
[PROOFSTEP]
split_ifs with h
[GOAL]
case pos
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommRing R
t : Multiset R
ht : 0 < ↑Multiset.card t
✝ : Nontrivial R
h : natDegree (prod (Multiset.map (fun x => X - ↑C x) t)) = 0
⊢ coeff (prod (Multiset.map (fun x => X - ↑C x) t)) (↑Multiset.card t - 1) = 0
[PROOFSTEP]
rw [natDegree_multiset_prod_of_monic] at h
[GOAL]
case pos
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommRing R
t : Multiset R
ht : 0 < ↑Multiset.card t
✝ : Nontrivial R
h : Multiset.sum (Multiset.map natDegree (Multiset.map (fun x => X - ↑C x) t)) = 0
⊢ coeff (prod (Multiset.map (fun x => X - ↑C x) t)) (↑Multiset.card t - 1) = 0
[PROOFSTEP]
simp only [Multiset.mem_map] at *
[GOAL]
case pos.h
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommRing R
t : Multiset R
ht : 0 < ↑Multiset.card t
✝ : Nontrivial R
h : natDegree (prod (Multiset.map (fun x => X - ↑C x) t)) = 0
⊢ ∀ (f : R[X]), f ∈ Multiset.map (fun x => X - ↑C x) t → Monic f
[PROOFSTEP]
simp only [Multiset.mem_map] at *
[GOAL]
case pos
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommRing R
t : Multiset R
ht : 0 < ↑Multiset.card t
✝ : Nontrivial R
h : Multiset.sum (Multiset.map (fun x => natDegree x) (Multiset.map (fun x => X - ↑C x) t)) = 0
⊢ coeff (prod (Multiset.map (fun x => X - ↑C x) t)) (↑Multiset.card t - 1) = 0
case pos.h
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommRing R
t : Multiset R
ht : 0 < ↑Multiset.card t
✝ : Nontrivial R
h : natDegree (prod (Multiset.map (fun x => X - ↑C x) t)) = 0
⊢ ∀ (f : R[X]), (∃ a, a ∈ t ∧ X - ↑C a = f) → Monic f
[PROOFSTEP]
swap
[GOAL]
case pos.h
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommRing R
t : Multiset R
ht : 0 < ↑Multiset.card t
✝ : Nontrivial R
h : natDegree (prod (Multiset.map (fun x => X - ↑C x) t)) = 0
⊢ ∀ (f : R[X]), (∃ a, a ∈ t ∧ X - ↑C a = f) → Monic f
[PROOFSTEP]
rintro _ ⟨_, _, rfl⟩
[GOAL]
case pos.h.intro.intro
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommRing R
t : Multiset R
ht : 0 < ↑Multiset.card t
✝ : Nontrivial R
h : natDegree (prod (Multiset.map (fun x => X - ↑C x) t)) = 0
w✝ : R
left✝ : w✝ ∈ t
⊢ Monic (X - ↑C w✝)
[PROOFSTEP]
apply monic_X_sub_C
[GOAL]
case pos
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommRing R
t : Multiset R
ht : 0 < ↑Multiset.card t
✝ : Nontrivial R
h : Multiset.sum (Multiset.map (fun x => natDegree x) (Multiset.map (fun x => X - ↑C x) t)) = 0
⊢ coeff (prod (Multiset.map (fun x => X - ↑C x) t)) (↑Multiset.card t - 1) = 0
[PROOFSTEP]
simp_rw [Multiset.sum_eq_zero_iff, Multiset.mem_map] at h
[GOAL]
case pos
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommRing R
t : Multiset R
ht : 0 < ↑Multiset.card t
✝ : Nontrivial R
h : ∀ (x : ℕ), (∃ a, (∃ a_1, a_1 ∈ t ∧ X - ↑C a_1 = a) ∧ natDegree a = x) → x = 0
⊢ coeff (prod (Multiset.map (fun x => X - ↑C x) t)) (↑Multiset.card t - 1) = 0
[PROOFSTEP]
contrapose! h
[GOAL]
case pos
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommRing R
t : Multiset R
ht : 0 < ↑Multiset.card t
✝ : Nontrivial R
h : coeff (prod (Multiset.map (fun x => X - ↑C x) t)) (↑Multiset.card t - 1) ≠ 0
⊢ ∃ x, (∃ a, (∃ a_1, a_1 ∈ t ∧ X - ↑C a_1 = a) ∧ natDegree a = x) ∧ x ≠ 0
[PROOFSTEP]
obtain ⟨x, hx⟩ := card_pos_iff_exists_mem.mp ht
[GOAL]
case pos.intro
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommRing R
t : Multiset R
ht : 0 < ↑Multiset.card t
✝ : Nontrivial R
h : coeff (prod (Multiset.map (fun x => X - ↑C x) t)) (↑Multiset.card t - 1) ≠ 0
x : R
hx : x ∈ t
⊢ ∃ x, (∃ a, (∃ a_1, a_1 ∈ t ∧ X - ↑C a_1 = a) ∧ natDegree a = x) ∧ x ≠ 0
[PROOFSTEP]
exact ⟨_, ⟨_, ⟨x, hx, rfl⟩, natDegree_X_sub_C _⟩, one_ne_zero⟩
[GOAL]
case neg
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommRing R
t : Multiset R
ht : 0 < ↑Multiset.card t
✝ : Nontrivial R
h : ¬natDegree (prod (Multiset.map (fun x => X - ↑C x) t)) = 0
⊢ coeff (prod (Multiset.map (fun x => X - ↑C x) t)) (↑Multiset.card t - 1) =
    coeff (prod (Multiset.map (fun x => X - ↑C x) t)) (natDegree (prod (Multiset.map (fun x => X - ↑C x) t)) - 1)
[PROOFSTEP]
congr
[GOAL]
case neg.e_a.e_a
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommRing R
t : Multiset R
ht : 0 < ↑Multiset.card t
✝ : Nontrivial R
h : ¬natDegree (prod (Multiset.map (fun x => X - ↑C x) t)) = 0
⊢ ↑Multiset.card t = natDegree (prod (Multiset.map (fun x => X - ↑C x) t))
[PROOFSTEP]
rw [natDegree_multiset_prod_of_monic]
[GOAL]
case neg.e_a.e_a
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommRing R
t : Multiset R
ht : 0 < ↑Multiset.card t
✝ : Nontrivial R
h : ¬natDegree (prod (Multiset.map (fun x => X - ↑C x) t)) = 0
⊢ ↑Multiset.card t = Multiset.sum (Multiset.map natDegree (Multiset.map (fun x => X - ↑C x) t))
[PROOFSTEP]
simp [natDegree_X_sub_C, monic_X_sub_C]
[GOAL]
case neg.e_a.e_a.h
R : Type u
ι : Type w
s : Finset ι
inst✝ : CommRing R
t : Multiset R
ht : 0 < ↑Multiset.card t
✝ : Nontrivial R
h : ¬natDegree (prod (Multiset.map (fun x => X - ↑C x) t)) = 0
⊢ ∀ (f : R[X]), f ∈ Multiset.map (fun x => X - ↑C x) t → Monic f
[PROOFSTEP]
simp [natDegree_X_sub_C, monic_X_sub_C]
[GOAL]
R : Type u
ι : Type w
s✝ : Finset ι
inst✝ : CommRing R
s : Finset ι
f : ι → R
hs : 0 < Finset.card s
⊢ coeff (∏ i in s, (X - ↑C (f i))) (Finset.card s - 1) = -∑ i in s, f i
[PROOFSTEP]
simpa using multiset_prod_X_sub_C_coeff_card_pred (s.1.map f) (by simpa using hs)
[GOAL]
R : Type u
ι : Type w
s✝ : Finset ι
inst✝ : CommRing R
s : Finset ι
f : ι → R
hs : 0 < Finset.card s
⊢ 0 < ↑Multiset.card (Multiset.map f s.val)
[PROOFSTEP]
simpa using hs
[GOAL]
R : Type u
ι : Type w
s : Finset ι
inst✝¹ : CommSemiring R
inst✝ : NoZeroDivisors R
f : ι → R[X]
t : Multiset R[X]
h : ∀ (i : ι), i ∈ s → f i ≠ 0
⊢ natDegree (∏ i in s, f i) = ∑ i in s, natDegree (f i)
[PROOFSTEP]
nontriviality R
[GOAL]
R : Type u
ι : Type w
s : Finset ι
inst✝¹ : CommSemiring R
inst✝ : NoZeroDivisors R
f : ι → R[X]
t : Multiset R[X]
h : ∀ (i : ι), i ∈ s → f i ≠ 0
✝ : Nontrivial R
⊢ natDegree (∏ i in s, f i) = ∑ i in s, natDegree (f i)
[PROOFSTEP]
apply natDegree_prod'
[GOAL]
case h
R : Type u
ι : Type w
s : Finset ι
inst✝¹ : CommSemiring R
inst✝ : NoZeroDivisors R
f : ι → R[X]
t : Multiset R[X]
h : ∀ (i : ι), i ∈ s → f i ≠ 0
✝ : Nontrivial R
⊢ ∏ i in s, leadingCoeff (f i) ≠ 0
[PROOFSTEP]
rw [prod_ne_zero_iff]
[GOAL]
case h
R : Type u
ι : Type w
s : Finset ι
inst✝¹ : CommSemiring R
inst✝ : NoZeroDivisors R
f : ι → R[X]
t : Multiset R[X]
h : ∀ (i : ι), i ∈ s → f i ≠ 0
✝ : Nontrivial R
⊢ ∀ (a : ι), a ∈ s → leadingCoeff (f a) ≠ 0
[PROOFSTEP]
intro x hx
[GOAL]
case h
R : Type u
ι : Type w
s : Finset ι
inst✝¹ : CommSemiring R
inst✝ : NoZeroDivisors R
f : ι → R[X]
t : Multiset R[X]
h : ∀ (i : ι), i ∈ s → f i ≠ 0
✝ : Nontrivial R
x : ι
hx : x ∈ s
⊢ leadingCoeff (f x) ≠ 0
[PROOFSTEP]
simp [h x hx]
[GOAL]
R : Type u
ι : Type w
s : Finset ι
inst✝¹ : CommSemiring R
inst✝ : NoZeroDivisors R
f : ι → R[X]
t : Multiset R[X]
h : ¬0 ∈ t
⊢ natDegree (prod t) = Multiset.sum (Multiset.map natDegree t)
[PROOFSTEP]
nontriviality R
[GOAL]
R : Type u
ι : Type w
s : Finset ι
inst✝¹ : CommSemiring R
inst✝ : NoZeroDivisors R
f : ι → R[X]
t : Multiset R[X]
h : ¬0 ∈ t
✝ : Nontrivial R
⊢ natDegree (prod t) = Multiset.sum (Multiset.map natDegree t)
[PROOFSTEP]
rw [natDegree_multiset_prod']
[GOAL]
case h
R : Type u
ι : Type w
s : Finset ι
inst✝¹ : CommSemiring R
inst✝ : NoZeroDivisors R
f : ι → R[X]
t : Multiset R[X]
h : ¬0 ∈ t
✝ : Nontrivial R
⊢ prod (Multiset.map (fun f => leadingCoeff f) t) ≠ 0
[PROOFSTEP]
simp_rw [Ne.def, Multiset.prod_eq_zero_iff, Multiset.mem_map, leadingCoeff_eq_zero]
[GOAL]
case h
R : Type u
ι : Type w
s : Finset ι
inst✝¹ : CommSemiring R
inst✝ : NoZeroDivisors R
f : ι → R[X]
t : Multiset R[X]
h : ¬0 ∈ t
✝ : Nontrivial R
⊢ ¬∃ a, a ∈ t ∧ a = 0
[PROOFSTEP]
rintro ⟨_, h, rfl⟩
[GOAL]
case h.intro.intro
R : Type u
ι : Type w
s : Finset ι
inst✝¹ : CommSemiring R
inst✝ : NoZeroDivisors R
f : ι → R[X]
t : Multiset R[X]
h✝ : ¬0 ∈ t
✝ : Nontrivial R
h : 0 ∈ t
⊢ False
[PROOFSTEP]
contradiction
[GOAL]
R : Type u
ι : Type w
s : Finset ι
inst✝¹ : CommSemiring R
inst✝ : NoZeroDivisors R
f : ι → R[X]
t : Multiset R[X]
⊢ leadingCoeff (prod t) = prod (Multiset.map (fun f => leadingCoeff f) t)
[PROOFSTEP]
rw [← leadingCoeffHom_apply, MonoidHom.map_multiset_prod]
[GOAL]
R : Type u
ι : Type w
s : Finset ι
inst✝¹ : CommSemiring R
inst✝ : NoZeroDivisors R
f : ι → R[X]
t : Multiset R[X]
⊢ prod (Multiset.map (↑leadingCoeffHom) t) = prod (Multiset.map (fun f => leadingCoeff f) t)
[PROOFSTEP]
rfl
[GOAL]
R : Type u
ι : Type w
s : Finset ι
inst✝¹ : CommSemiring R
inst✝ : NoZeroDivisors R
f : ι → R[X]
t : Multiset R[X]
⊢ leadingCoeff (∏ i in s, f i) = ∏ i in s, leadingCoeff (f i)
[PROOFSTEP]
simpa using leadingCoeff_multiset_prod (s.1.map f)


[GOAL]
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
x : R
hx : x ∈ jacobson I
y : R
hxy : I ⊔ span {y * x + 1} = ⊤
p : R
hpi : p ∈ I
q : R
hq : q ∈ span {y * x + 1}
hpq : p + q = 1
r : R
hr : r * (y * x + 1) = q
⊢ r * y * x + r - 1 ∈ I
[PROOFSTEP]
rw [mul_assoc, ← mul_add_one r (y * x), hr, ← hpq, ← neg_sub, add_sub_cancel]
[GOAL]
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
x : R
hx : x ∈ jacobson I
y : R
hxy : I ⊔ span {y * x + 1} = ⊤
p : R
hpi : p ∈ I
q : R
hq : q ∈ span {y * x + 1}
hpq : p + q = 1
r : R
hr : r * (y * x + 1) = q
⊢ -p ∈ I
[PROOFSTEP]
exact I.neg_mem hpi
[GOAL]
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
x : R
hx : ∀ (y : R), ∃ z, z * y * x + z - 1 ∈ I
M : Ideal R
x✝ : M ∈ {J | I ≤ J ∧ IsMaximal J}
him : I ≤ M
hm : IsMaximal M
hxm : ¬x ∈ M
y i : R
hi : i ∈ M
df : y * x + i = 1
z : R
hz : z * -y * x + z - 1 ∈ I
⊢ z * -y * x + z ∈ M
[PROOFSTEP]
rw [mul_assoc, ← mul_add_one z, neg_mul, ← sub_eq_iff_eq_add.mpr df.symm, neg_sub, sub_add_cancel]
[GOAL]
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
x : R
hx : ∀ (y : R), ∃ z, z * y * x + z - 1 ∈ I
M : Ideal R
x✝ : M ∈ {J | I ≤ J ∧ IsMaximal J}
him : I ≤ M
hm : IsMaximal M
hxm : ¬x ∈ M
y i : R
hi : i ∈ M
df : y * x + i = 1
z : R
hz : z * -y * x + z - 1 ∈ I
⊢ z * i ∈ M
[PROOFSTEP]
exact M.mul_mem_left _ hi
[GOAL]
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I✝ I : Ideal R
r : R
h : r - 1 ∈ jacobson I
⊢ ∃ s, s * r - 1 ∈ I
[PROOFSTEP]
cases' mem_jacobson_iff.1 h 1 with s hs
[GOAL]
case intro
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I✝ I : Ideal R
r : R
h : r - 1 ∈ jacobson I
s : R
hs : s * 1 * (r - 1) + s - 1 ∈ I
⊢ ∃ s, s * r - 1 ∈ I
[PROOFSTEP]
use s
[GOAL]
case h
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I✝ I : Ideal R
r : R
h : r - 1 ∈ jacobson I
s : R
hs : s * 1 * (r - 1) + s - 1 ∈ I
⊢ s * r - 1 ∈ I
[PROOFSTEP]
simpa [mul_sub] using hs
[GOAL]
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
⊢ jacobson I = I ↔ ∃ M, (∀ (J : Ideal R), J ∈ M → IsMaximal J ∨ J = ⊤) ∧ I = sInf M
[PROOFSTEP]
use fun hI => ⟨{J : Ideal R | I ≤ J ∧ J.IsMaximal}, ⟨fun _ hJ => Or.inl hJ.right, hI.symm⟩⟩
[GOAL]
case mpr
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
⊢ (∃ M, (∀ (J : Ideal R), J ∈ M → IsMaximal J ∨ J = ⊤) ∧ I = sInf M) → jacobson I = I
[PROOFSTEP]
rintro ⟨M, hM, hInf⟩
[GOAL]
case mpr.intro.intro
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
M : Set (Ideal R)
hM : ∀ (J : Ideal R), J ∈ M → IsMaximal J ∨ J = ⊤
hInf : I = sInf M
⊢ jacobson I = I
[PROOFSTEP]
refine le_antisymm (fun x hx => ?_) le_jacobson
[GOAL]
case mpr.intro.intro
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
M : Set (Ideal R)
hM : ∀ (J : Ideal R), J ∈ M → IsMaximal J ∨ J = ⊤
hInf : I = sInf M
x : R
hx : x ∈ jacobson I
⊢ x ∈ I
[PROOFSTEP]
rw [hInf, mem_sInf]
[GOAL]
case mpr.intro.intro
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
M : Set (Ideal R)
hM : ∀ (J : Ideal R), J ∈ M → IsMaximal J ∨ J = ⊤
hInf : I = sInf M
x : R
hx : x ∈ jacobson I
⊢ ∀ ⦃I : Ideal R⦄, I ∈ M → x ∈ I
[PROOFSTEP]
intro I hI
[GOAL]
case mpr.intro.intro
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I✝ : Ideal R
M : Set (Ideal R)
hM : ∀ (J : Ideal R), J ∈ M → IsMaximal J ∨ J = ⊤
hInf : I✝ = sInf M
x : R
hx : x ∈ jacobson I✝
I : Ideal R
hI : I ∈ M
⊢ x ∈ I
[PROOFSTEP]
cases' hM I hI with is_max is_top
[GOAL]
case mpr.intro.intro.inl
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I✝ : Ideal R
M : Set (Ideal R)
hM : ∀ (J : Ideal R), J ∈ M → IsMaximal J ∨ J = ⊤
hInf : I✝ = sInf M
x : R
hx : x ∈ jacobson I✝
I : Ideal R
hI : I ∈ M
is_max : IsMaximal I
⊢ x ∈ I
[PROOFSTEP]
exact (mem_sInf.1 hx) ⟨le_sInf_iff.1 (le_of_eq hInf) I hI, is_max⟩
[GOAL]
case mpr.intro.intro.inr
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I✝ : Ideal R
M : Set (Ideal R)
hM : ∀ (J : Ideal R), J ∈ M → IsMaximal J ∨ J = ⊤
hInf : I✝ = sInf M
x : R
hx : x ∈ jacobson I✝
I : Ideal R
hI : I ∈ M
is_top : I = ⊤
⊢ x ∈ I
[PROOFSTEP]
exact is_top.symm ▸ Submodule.mem_top
[GOAL]
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
⊢ jacobson I = I ↔ ∀ (x : R), ¬x ∈ I → ∃ M, (I ≤ M ∧ IsMaximal M) ∧ ¬x ∈ M
[PROOFSTEP]
constructor
[GOAL]
case mp
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
⊢ jacobson I = I → ∀ (x : R), ¬x ∈ I → ∃ M, (I ≤ M ∧ IsMaximal M) ∧ ¬x ∈ M
[PROOFSTEP]
intro h x hx
[GOAL]
case mp
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
h : jacobson I = I
x : R
hx : ¬x ∈ I
⊢ ∃ M, (I ≤ M ∧ IsMaximal M) ∧ ¬x ∈ M
[PROOFSTEP]
erw [← h, mem_sInf] at hx
[GOAL]
case mp
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
h : jacobson I = I
x : R
hx : ¬∀ ⦃I_1 : Ideal R⦄, I_1 ∈ {J | I ≤ J ∧ IsMaximal J} → x ∈ I_1
⊢ ∃ M, (I ≤ M ∧ IsMaximal M) ∧ ¬x ∈ M
[PROOFSTEP]
push_neg at hx
[GOAL]
case mp
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
h : jacobson I = I
x : R
hx : Exists fun ⦃I_1⦄ => I_1 ∈ {J | I ≤ J ∧ IsMaximal J} ∧ ¬x ∈ I_1
⊢ ∃ M, (I ≤ M ∧ IsMaximal M) ∧ ¬x ∈ M
[PROOFSTEP]
exact hx
[GOAL]
case mpr
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
⊢ (∀ (x : R), ¬x ∈ I → ∃ M, (I ≤ M ∧ IsMaximal M) ∧ ¬x ∈ M) → jacobson I = I
[PROOFSTEP]
refine fun h => le_antisymm (fun x hx => ?_) le_jacobson
[GOAL]
case mpr
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
h : ∀ (x : R), ¬x ∈ I → ∃ M, (I ≤ M ∧ IsMaximal M) ∧ ¬x ∈ M
x : R
hx : x ∈ jacobson I
⊢ x ∈ I
[PROOFSTEP]
contrapose hx
[GOAL]
case mpr
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
h : ∀ (x : R), ¬x ∈ I → ∃ M, (I ≤ M ∧ IsMaximal M) ∧ ¬x ∈ M
x : R
hx : ¬x ∈ I
⊢ ¬x ∈ jacobson I
[PROOFSTEP]
erw [mem_sInf]
[GOAL]
case mpr
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
h : ∀ (x : R), ¬x ∈ I → ∃ M, (I ≤ M ∧ IsMaximal M) ∧ ¬x ∈ M
x : R
hx : ¬x ∈ I
⊢ ¬∀ ⦃I_1 : Ideal R⦄, I_1 ∈ {J | I ≤ J ∧ IsMaximal J} → x ∈ I_1
[PROOFSTEP]
push_neg
[GOAL]
case mpr
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
h : ∀ (x : R), ¬x ∈ I → ∃ M, (I ≤ M ∧ IsMaximal M) ∧ ¬x ∈ M
x : R
hx : ¬x ∈ I
⊢ Exists fun ⦃I_1⦄ => I_1 ∈ {J | I ≤ J ∧ IsMaximal J} ∧ ¬x ∈ I_1
[PROOFSTEP]
exact h x hx
[GOAL]
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
f : R →+* S
hf : Function.Surjective ↑f
⊢ RingHom.ker f ≤ I → map f (jacobson I) = jacobson (map f I)
[PROOFSTEP]
intro h
[GOAL]
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
f : R →+* S
hf : Function.Surjective ↑f
h : RingHom.ker f ≤ I
⊢ map f (jacobson I) = jacobson (map f I)
[PROOFSTEP]
unfold Ideal.jacobson
[GOAL]
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
f : R →+* S
hf : Function.Surjective ↑f
h : RingHom.ker f ≤ I
⊢ map f (sInf {J | I ≤ J ∧ IsMaximal J}) = sInf {J | map f I ≤ J ∧ IsMaximal J}
[PROOFSTEP]
have : ∀ J ∈ {J : Ideal R | I ≤ J ∧ J.IsMaximal}, RingHom.ker f ≤ J := fun J hJ => le_trans h hJ.left
[GOAL]
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
f : R →+* S
hf : Function.Surjective ↑f
h : RingHom.ker f ≤ I
this : ∀ (J : Ideal R), J ∈ {J | I ≤ J ∧ IsMaximal J} → RingHom.ker f ≤ J
⊢ map f (sInf {J | I ≤ J ∧ IsMaximal J}) = sInf {J | map f I ≤ J ∧ IsMaximal J}
[PROOFSTEP]
refine Trans.trans (map_sInf hf this) (le_antisymm ?_ ?_)
[GOAL]
case refine_1
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
f : R →+* S
hf : Function.Surjective ↑f
h : RingHom.ker f ≤ I
this : ∀ (J : Ideal R), J ∈ {J | I ≤ J ∧ IsMaximal J} → RingHom.ker f ≤ J
⊢ sInf (map f '' {J | I ≤ J ∧ IsMaximal J}) ≤ sInf {J | map f I ≤ J ∧ IsMaximal J}
[PROOFSTEP]
refine' sInf_le_sInf fun J hJ => ⟨comap f J, ⟨⟨le_comap_of_map_le hJ.1, _⟩, map_comap_of_surjective f hf J⟩⟩
[GOAL]
case refine_1
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
f : R →+* S
hf : Function.Surjective ↑f
h : RingHom.ker f ≤ I
this : ∀ (J : Ideal R), J ∈ {J | I ≤ J ∧ IsMaximal J} → RingHom.ker f ≤ J
J : Ideal S
hJ : J ∈ {J | map f I ≤ J ∧ IsMaximal J}
⊢ IsMaximal (comap f J)
[PROOFSTEP]
haveI : J.IsMaximal := hJ.right
[GOAL]
case refine_1
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
f : R →+* S
hf : Function.Surjective ↑f
h : RingHom.ker f ≤ I
this✝ : ∀ (J : Ideal R), J ∈ {J | I ≤ J ∧ IsMaximal J} → RingHom.ker f ≤ J
J : Ideal S
hJ : J ∈ {J | map f I ≤ J ∧ IsMaximal J}
this : IsMaximal J
⊢ IsMaximal (comap f J)
[PROOFSTEP]
exact comap_isMaximal_of_surjective f hf
[GOAL]
case refine_2
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
f : R →+* S
hf : Function.Surjective ↑f
h : RingHom.ker f ≤ I
this : ∀ (J : Ideal R), J ∈ {J | I ≤ J ∧ IsMaximal J} → RingHom.ker f ≤ J
⊢ sInf {J | map f I ≤ J ∧ IsMaximal J} ≤ sInf (map f '' {J | I ≤ J ∧ IsMaximal J})
[PROOFSTEP]
refine' sInf_le_sInf_of_subset_insert_top fun j hj => hj.recOn fun J hJ => _
[GOAL]
case refine_2
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
f : R →+* S
hf : Function.Surjective ↑f
h : RingHom.ker f ≤ I
this : ∀ (J : Ideal R), J ∈ {J | I ≤ J ∧ IsMaximal J} → RingHom.ker f ≤ J
j : Ideal S
hj : j ∈ map f '' {J | I ≤ J ∧ IsMaximal J}
J : Ideal R
hJ : J ∈ {J | I ≤ J ∧ IsMaximal J} ∧ map f J = j
⊢ j ∈ insert ⊤ {J | map f I ≤ J ∧ IsMaximal J}
[PROOFSTEP]
rw [← hJ.2]
[GOAL]
case refine_2
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
f : R →+* S
hf : Function.Surjective ↑f
h : RingHom.ker f ≤ I
this : ∀ (J : Ideal R), J ∈ {J | I ≤ J ∧ IsMaximal J} → RingHom.ker f ≤ J
j : Ideal S
hj : j ∈ map f '' {J | I ≤ J ∧ IsMaximal J}
J : Ideal R
hJ : J ∈ {J | I ≤ J ∧ IsMaximal J} ∧ map f J = j
⊢ map f J ∈ insert ⊤ {J | map f I ≤ J ∧ IsMaximal J}
[PROOFSTEP]
cases' map_eq_top_or_isMaximal_of_surjective f hf hJ.left.right with htop hmax
[GOAL]
case refine_2.inl
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
f : R →+* S
hf : Function.Surjective ↑f
h : RingHom.ker f ≤ I
this : ∀ (J : Ideal R), J ∈ {J | I ≤ J ∧ IsMaximal J} → RingHom.ker f ≤ J
j : Ideal S
hj : j ∈ map f '' {J | I ≤ J ∧ IsMaximal J}
J : Ideal R
hJ : J ∈ {J | I ≤ J ∧ IsMaximal J} ∧ map f J = j
htop : map f J = ⊤
⊢ map f J ∈ insert ⊤ {J | map f I ≤ J ∧ IsMaximal J}
[PROOFSTEP]
exact htop.symm ▸ Set.mem_insert ⊤ _
[GOAL]
case refine_2.inr
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
f : R →+* S
hf : Function.Surjective ↑f
h : RingHom.ker f ≤ I
this : ∀ (J : Ideal R), J ∈ {J | I ≤ J ∧ IsMaximal J} → RingHom.ker f ≤ J
j : Ideal S
hj : j ∈ map f '' {J | I ≤ J ∧ IsMaximal J}
J : Ideal R
hJ : J ∈ {J | I ≤ J ∧ IsMaximal J} ∧ map f J = j
hmax : IsMaximal (map f J)
⊢ map f J ∈ insert ⊤ {J | map f I ≤ J ∧ IsMaximal J}
[PROOFSTEP]
exact Set.mem_insert_of_mem ⊤ ⟨map_mono hJ.1.1, hmax⟩
[GOAL]
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
f : R →+* S
hf : Function.Surjective ↑f
K : Ideal S
⊢ comap f (jacobson K) = jacobson (comap f K)
[PROOFSTEP]
unfold Ideal.jacobson
[GOAL]
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
f : R →+* S
hf : Function.Surjective ↑f
K : Ideal S
⊢ comap f (sInf {J | K ≤ J ∧ IsMaximal J}) = sInf {J | comap f K ≤ J ∧ IsMaximal J}
[PROOFSTEP]
refine' le_antisymm _ _
[GOAL]
case refine'_1
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
f : R →+* S
hf : Function.Surjective ↑f
K : Ideal S
⊢ comap f (sInf {J | K ≤ J ∧ IsMaximal J}) ≤ sInf {J | comap f K ≤ J ∧ IsMaximal J}
[PROOFSTEP]
refine le_trans (comap_mono (le_of_eq (Trans.trans top_inf_eq.symm sInf_insert.symm))) ?_
[GOAL]
case refine'_1
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
f : R →+* S
hf : Function.Surjective ↑f
K : Ideal S
⊢ comap f (sInf (insert ⊤ {J | K ≤ J ∧ IsMaximal J})) ≤ sInf {J | comap f K ≤ J ∧ IsMaximal J}
[PROOFSTEP]
rw [comap_sInf', sInf_eq_iInf]
[GOAL]
case refine'_1
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
f : R →+* S
hf : Function.Surjective ↑f
K : Ideal S
⊢ ⨅ (I : Ideal R) (_ : I ∈ comap f '' insert ⊤ {J | K ≤ J ∧ IsMaximal J}), I ≤
    ⨅ (a : Ideal R) (_ : a ∈ {J | comap f K ≤ J ∧ IsMaximal J}), a
[PROOFSTEP]
refine' iInf_le_iInf_of_subset fun J hJ => _
[GOAL]
case refine'_1
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
f : R →+* S
hf : Function.Surjective ↑f
K : Ideal S
J : Ideal R
hJ : J ∈ {J | comap f K ≤ J ∧ IsMaximal J}
⊢ J ∈ comap f '' insert ⊤ {J | K ≤ J ∧ IsMaximal J}
[PROOFSTEP]
have : comap f (map f J) = J :=
  Trans.trans (comap_map_of_surjective f hf J)
    (le_antisymm (sup_le_iff.2 ⟨le_of_eq rfl, le_trans (comap_mono bot_le) hJ.left⟩) le_sup_left)
[GOAL]
case refine'_1
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
f : R →+* S
hf : Function.Surjective ↑f
K : Ideal S
J : Ideal R
hJ : J ∈ {J | comap f K ≤ J ∧ IsMaximal J}
this : comap f (map f J) = J
⊢ J ∈ comap f '' insert ⊤ {J | K ≤ J ∧ IsMaximal J}
[PROOFSTEP]
cases' map_eq_top_or_isMaximal_of_surjective _ hf hJ.right with htop hmax
[GOAL]
case refine'_1.inl
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
f : R →+* S
hf : Function.Surjective ↑f
K : Ideal S
J : Ideal R
hJ : J ∈ {J | comap f K ≤ J ∧ IsMaximal J}
this : comap f (map f J) = J
htop : map f J = ⊤
⊢ J ∈ comap f '' insert ⊤ {J | K ≤ J ∧ IsMaximal J}
[PROOFSTEP]
exact ⟨⊤, ⟨Set.mem_insert ⊤ _, htop ▸ this⟩⟩
[GOAL]
case refine'_1.inr
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
f : R →+* S
hf : Function.Surjective ↑f
K : Ideal S
J : Ideal R
hJ : J ∈ {J | comap f K ≤ J ∧ IsMaximal J}
this : comap f (map f J) = J
hmax : IsMaximal (map f J)
⊢ J ∈ comap f '' insert ⊤ {J | K ≤ J ∧ IsMaximal J}
[PROOFSTEP]
exact ⟨map f J, ⟨Set.mem_insert_of_mem _ ⟨le_map_of_comap_le_of_surjective f hf hJ.1, hmax⟩, this⟩⟩
[GOAL]
case refine'_2
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
f : R →+* S
hf : Function.Surjective ↑f
K : Ideal S
⊢ sInf {J | comap f K ≤ J ∧ IsMaximal J} ≤ comap f (sInf {J | K ≤ J ∧ IsMaximal J})
[PROOFSTEP]
rw [comap_sInf]
[GOAL]
case refine'_2
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
f : R →+* S
hf : Function.Surjective ↑f
K : Ideal S
⊢ sInf {J | comap f K ≤ J ∧ IsMaximal J} ≤ ⨅ (I : Ideal S) (_ : I ∈ {J | K ≤ J ∧ IsMaximal J}), comap f I
[PROOFSTEP]
refine' le_iInf_iff.2 fun J => le_iInf_iff.2 fun hJ => _
[GOAL]
case refine'_2
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
f : R →+* S
hf : Function.Surjective ↑f
K J : Ideal S
hJ : J ∈ {J | K ≤ J ∧ IsMaximal J}
⊢ sInf {J | comap f K ≤ J ∧ IsMaximal J} ≤ comap f J
[PROOFSTEP]
haveI : J.IsMaximal := hJ.right
[GOAL]
case refine'_2
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I : Ideal R
f : R →+* S
hf : Function.Surjective ↑f
K J : Ideal S
hJ : J ∈ {J | K ≤ J ∧ IsMaximal J}
this : IsMaximal J
⊢ sInf {J | comap f K ≤ J ∧ IsMaximal J} ≤ comap f J
[PROOFSTEP]
refine' sInf_le ⟨comap_mono hJ.left, comap_isMaximal_of_surjective _ hf⟩
[GOAL]
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I✝ I J : Ideal R
⊢ I ≤ J → jacobson I ≤ jacobson J
[PROOFSTEP]
intro h x hx
[GOAL]
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I✝ I J : Ideal R
h : I ≤ J
x : R
hx : x ∈ jacobson I
⊢ x ∈ jacobson J
[PROOFSTEP]
erw [mem_sInf] at hx ⊢
[GOAL]
R : Type u
S : Type v
inst✝¹ : Ring R
inst✝ : Ring S
I✝ I J : Ideal R
h : I ≤ J
x : R
hx : ∀ ⦃I_1 : Ideal R⦄, I_1 ∈ {J | I ≤ J ∧ IsMaximal J} → x ∈ I_1
⊢ ∀ ⦃I : Ideal R⦄, I ∈ {J_1 | J ≤ J_1 ∧ IsMaximal J_1} → x ∈ I
[PROOFSTEP]
exact fun K ⟨hK, hK_max⟩ => hx ⟨Trans.trans h hK, hK_max⟩
[GOAL]
R : Type u
S : Type v
inst✝¹ : CommRing R
inst✝ : CommRing S
I : Ideal R
r : R
h : r - 1 ∈ jacobson ⊥
⊢ IsUnit r
[PROOFSTEP]
cases' exists_mul_sub_mem_of_sub_one_mem_jacobson r h with s hs
[GOAL]
case intro
R : Type u
S : Type v
inst✝¹ : CommRing R
inst✝ : CommRing S
I : Ideal R
r : R
h : r - 1 ∈ jacobson ⊥
s : R
hs : s * r - 1 ∈ ⊥
⊢ IsUnit r
[PROOFSTEP]
rw [mem_bot, sub_eq_zero, mul_comm] at hs
[GOAL]
case intro
R : Type u
S : Type v
inst✝¹ : CommRing R
inst✝ : CommRing S
I : Ideal R
r : R
h : r - 1 ∈ jacobson ⊥
s : R
hs : r * s = 1
⊢ IsUnit r
[PROOFSTEP]
exact isUnit_of_mul_eq_one _ _ hs
[GOAL]
R : Type u
S : Type v
inst✝¹ : CommRing R
inst✝ : CommRing S
I : Ideal R
x : R
hx : x ∈ jacobson ⊥
y z : R
hz : z * y * x + z - 1 ∈ ⊥
⊢ (x * y + 1) * z = 1
[PROOFSTEP]
rwa [add_mul, one_mul, ← sub_eq_zero, mul_right_comm, mul_comm _ z, mul_right_comm]
[GOAL]
R : Type u
S : Type v
inst✝¹ : CommRing R
inst✝ : CommRing S
I : Ideal R
x : R
h : ∀ (y : R), IsUnit (x * y + 1)
y b : R
hb : (x * y + 1) * b = 1
⊢ b * y * x + b - (x * y + 1) * b = 0
[PROOFSTEP]
ring
[GOAL]
R : Type u
S : Type v
inst✝¹ : CommRing R
inst✝ : CommRing S
I : Ideal R
⊢ jacobson I = I ↔ jacobson ⊥ = ⊥
[PROOFSTEP]
have hf : Function.Surjective (Ideal.Quotient.mk I) := Submodule.Quotient.mk_surjective I
[GOAL]
R : Type u
S : Type v
inst✝¹ : CommRing R
inst✝ : CommRing S
I : Ideal R
hf : Function.Surjective ↑(Quotient.mk I)
⊢ jacobson I = I ↔ jacobson ⊥ = ⊥
[PROOFSTEP]
constructor
[GOAL]
case mp
R : Type u
S : Type v
inst✝¹ : CommRing R
inst✝ : CommRing S
I : Ideal R
hf : Function.Surjective ↑(Quotient.mk I)
⊢ jacobson I = I → jacobson ⊥ = ⊥
[PROOFSTEP]
intro h
[GOAL]
case mp
R : Type u
S : Type v
inst✝¹ : CommRing R
inst✝ : CommRing S
I : Ideal R
hf : Function.Surjective ↑(Quotient.mk I)
h : jacobson I = I
⊢ jacobson ⊥ = ⊥
[PROOFSTEP]
replace h := congr_arg (Ideal.map (Ideal.Quotient.mk I)) h
[GOAL]
case mp
R : Type u
S : Type v
inst✝¹ : CommRing R
inst✝ : CommRing S
I : Ideal R
hf : Function.Surjective ↑(Quotient.mk I)
h : map (Quotient.mk I) (jacobson I) = map (Quotient.mk I) I
⊢ jacobson ⊥ = ⊥
[PROOFSTEP]
rw [map_jacobson_of_surjective hf (le_of_eq mk_ker)] at h
[GOAL]
case mp
R : Type u
S : Type v
inst✝¹ : CommRing R
inst✝ : CommRing S
I : Ideal R
hf : Function.Surjective ↑(Quotient.mk I)
h : jacobson (map (Quotient.mk I) I) = map (Quotient.mk I) I
⊢ jacobson ⊥ = ⊥
[PROOFSTEP]
simpa using h
[GOAL]
case mpr
R : Type u
S : Type v
inst✝¹ : CommRing R
inst✝ : CommRing S
I : Ideal R
hf : Function.Surjective ↑(Quotient.mk I)
⊢ jacobson ⊥ = ⊥ → jacobson I = I
[PROOFSTEP]
intro h
[GOAL]
case mpr
R : Type u
S : Type v
inst✝¹ : CommRing R
inst✝ : CommRing S
I : Ideal R
hf : Function.Surjective ↑(Quotient.mk I)
h : jacobson ⊥ = ⊥
⊢ jacobson I = I
[PROOFSTEP]
replace h := congr_arg (comap (Ideal.Quotient.mk I)) h
[GOAL]
case mpr
R : Type u
S : Type v
inst✝¹ : CommRing R
inst✝ : CommRing S
I : Ideal R
hf : Function.Surjective ↑(Quotient.mk I)
h : comap (Quotient.mk I) (jacobson ⊥) = comap (Quotient.mk I) ⊥
⊢ jacobson I = I
[PROOFSTEP]
rw [comap_jacobson_of_surjective hf, ← RingHom.ker_eq_comap_bot (Ideal.Quotient.mk I)] at h
[GOAL]
case mpr
R : Type u
S : Type v
inst✝¹ : CommRing R
inst✝ : CommRing S
I : Ideal R
hf : Function.Surjective ↑(Quotient.mk I)
h : jacobson (RingHom.ker (Quotient.mk I)) = RingHom.ker (Quotient.mk I)
⊢ jacobson I = I
[PROOFSTEP]
simpa using h
[GOAL]
R : Type u
S : Type v
inst✝¹ : CommRing R
inst✝ : CommRing S
I : Ideal R
⊢ radical I = jacobson I ↔ radical ⊥ = jacobson ⊥
[PROOFSTEP]
have hf : Function.Surjective (Ideal.Quotient.mk I) := Submodule.Quotient.mk_surjective I
[GOAL]
R : Type u
S : Type v
inst✝¹ : CommRing R
inst✝ : CommRing S
I : Ideal R
hf : Function.Surjective ↑(Quotient.mk I)
⊢ radical I = jacobson I ↔ radical ⊥ = jacobson ⊥
[PROOFSTEP]
constructor
[GOAL]
case mp
R : Type u
S : Type v
inst✝¹ : CommRing R
inst✝ : CommRing S
I : Ideal R
hf : Function.Surjective ↑(Quotient.mk I)
⊢ radical I = jacobson I → radical ⊥ = jacobson ⊥
[PROOFSTEP]
intro h
[GOAL]
case mp
R : Type u
S : Type v
inst✝¹ : CommRing R
inst✝ : CommRing S
I : Ideal R
hf : Function.Surjective ↑(Quotient.mk I)
h : radical I = jacobson I
⊢ radical ⊥ = jacobson ⊥
[PROOFSTEP]
have := congr_arg (map (Ideal.Quotient.mk I)) h
[GOAL]
case mp
R : Type u
S : Type v
inst✝¹ : CommRing R
inst✝ : CommRing S
I : Ideal R
hf : Function.Surjective ↑(Quotient.mk I)
h : radical I = jacobson I
this : map (Quotient.mk I) (radical I) = map (Quotient.mk I) (jacobson I)
⊢ radical ⊥ = jacobson ⊥
[PROOFSTEP]
rw [map_radical_of_surjective hf (le_of_eq mk_ker), map_jacobson_of_surjective hf (le_of_eq mk_ker)] at this
[GOAL]
case mp
R : Type u
S : Type v
inst✝¹ : CommRing R
inst✝ : CommRing S
I : Ideal R
hf : Function.Surjective ↑(Quotient.mk I)
h : radical I = jacobson I
this : radical (map (Quotient.mk I) I) = jacobson (map (Quotient.mk I) I)
⊢ radical ⊥ = jacobson ⊥
[PROOFSTEP]
simpa using this
[GOAL]
case mpr
R : Type u
S : Type v
inst✝¹ : CommRing R
inst✝ : CommRing S
I : Ideal R
hf : Function.Surjective ↑(Quotient.mk I)
⊢ radical ⊥ = jacobson ⊥ → radical I = jacobson I
[PROOFSTEP]
intro h
[GOAL]
case mpr
R : Type u
S : Type v
inst✝¹ : CommRing R
inst✝ : CommRing S
I : Ideal R
hf : Function.Surjective ↑(Quotient.mk I)
h : radical ⊥ = jacobson ⊥
⊢ radical I = jacobson I
[PROOFSTEP]
have := congr_arg (comap (Ideal.Quotient.mk I)) h
[GOAL]
case mpr
R : Type u
S : Type v
inst✝¹ : CommRing R
inst✝ : CommRing S
I : Ideal R
hf : Function.Surjective ↑(Quotient.mk I)
h : radical ⊥ = jacobson ⊥
this : comap (Quotient.mk I) (radical ⊥) = comap (Quotient.mk I) (jacobson ⊥)
⊢ radical I = jacobson I
[PROOFSTEP]
rw [comap_radical, comap_jacobson_of_surjective hf, ← RingHom.ker_eq_comap_bot (Ideal.Quotient.mk I)] at this
[GOAL]
case mpr
R : Type u
S : Type v
inst✝¹ : CommRing R
inst✝ : CommRing S
I : Ideal R
hf : Function.Surjective ↑(Quotient.mk I)
h : radical ⊥ = jacobson ⊥
this : radical (RingHom.ker (Quotient.mk I)) = jacobson (RingHom.ker (Quotient.mk I))
⊢ radical I = jacobson I
[PROOFSTEP]
simpa using this
[GOAL]
R : Type u
S : Type v
inst✝ : CommRing R
⊢ jacobson ⊥ ≤ sInf (map C '' {J | IsMaximal J})
[PROOFSTEP]
refine' le_sInf fun J => exists_imp.2 fun j hj => _
[GOAL]
R : Type u
S : Type v
inst✝ : CommRing R
J : Ideal R[X]
j : Ideal R
hj : j ∈ {J | IsMaximal J} ∧ map C j = J
⊢ jacobson ⊥ ≤ J
[PROOFSTEP]
haveI : j.IsMaximal := hj.1
[GOAL]
R : Type u
S : Type v
inst✝ : CommRing R
J : Ideal R[X]
j : Ideal R
hj : j ∈ {J | IsMaximal J} ∧ map C j = J
this : IsMaximal j
⊢ jacobson ⊥ ≤ J
[PROOFSTEP]
refine' Trans.trans (jacobson_mono bot_le) (le_of_eq _ : J.jacobson ≤ J)
[GOAL]
R : Type u
S : Type v
inst✝ : CommRing R
J : Ideal R[X]
j : Ideal R
hj : j ∈ {J | IsMaximal J} ∧ map C j = J
this : IsMaximal j
⊢ jacobson J = J
[PROOFSTEP]
suffices t : (⊥ : Ideal (Polynomial (R ⧸ j))).jacobson = ⊥
  by
  rw [← hj.2, jacobson_eq_iff_jacobson_quotient_eq_bot]
  replace t := congr_arg (map (polynomialQuotientEquivQuotientPolynomial j).toRingHom) t
  rwa [map_jacobson_of_bijective _, map_bot] at t
  exact RingEquiv.bijective (polynomialQuotientEquivQuotientPolynomial j)
[GOAL]
R : Type u
S : Type v
inst✝ : CommRing R
J : Ideal R[X]
j : Ideal R
hj : j ∈ {J | IsMaximal J} ∧ map C j = J
this : IsMaximal j
t : jacobson ⊥ = ⊥
⊢ jacobson J = J
[PROOFSTEP]
rw [← hj.2, jacobson_eq_iff_jacobson_quotient_eq_bot]
[GOAL]
R : Type u
S : Type v
inst✝ : CommRing R
J : Ideal R[X]
j : Ideal R
hj : j ∈ {J | IsMaximal J} ∧ map C j = J
this : IsMaximal j
t : jacobson ⊥ = ⊥
⊢ jacobson ⊥ = ⊥
[PROOFSTEP]
replace t := congr_arg (map (polynomialQuotientEquivQuotientPolynomial j).toRingHom) t
[GOAL]
R : Type u
S : Type v
inst✝ : CommRing R
J : Ideal R[X]
j : Ideal R
hj : j ∈ {J | IsMaximal J} ∧ map C j = J
this : IsMaximal j
t :
  map (RingEquiv.toRingHom (polynomialQuotientEquivQuotientPolynomial j)) (jacobson ⊥) =
    map (RingEquiv.toRingHom (polynomialQuotientEquivQuotientPolynomial j)) ⊥
⊢ jacobson ⊥ = ⊥
[PROOFSTEP]
rwa [map_jacobson_of_bijective _, map_bot] at t
[GOAL]
R : Type u
S : Type v
inst✝ : CommRing R
J : Ideal R[X]
j : Ideal R
hj : j ∈ {J | IsMaximal J} ∧ map C j = J
this : IsMaximal j
t :
  map (RingEquiv.toRingHom (polynomialQuotientEquivQuotientPolynomial j)) (jacobson ⊥) =
    map (RingEquiv.toRingHom (polynomialQuotientEquivQuotientPolynomial j)) ⊥
⊢ Function.Bijective ↑(RingEquiv.toRingHom (polynomialQuotientEquivQuotientPolynomial j))
[PROOFSTEP]
exact RingEquiv.bijective (polynomialQuotientEquivQuotientPolynomial j)
[GOAL]
R : Type u
S : Type v
inst✝ : CommRing R
J : Ideal R[X]
j : Ideal R
hj : j ∈ {J | IsMaximal J} ∧ map C j = J
this : IsMaximal j
⊢ jacobson ⊥ = ⊥
[PROOFSTEP]
refine' eq_bot_iff.2 fun f hf => _
[GOAL]
R : Type u
S : Type v
inst✝ : CommRing R
J : Ideal R[X]
j : Ideal R
hj : j ∈ {J | IsMaximal J} ∧ map C j = J
this : IsMaximal j
f : (R ⧸ j)[X]
hf : f ∈ jacobson ⊥
⊢ f ∈ ⊥
[PROOFSTEP]
have r1 : (X : (R ⧸ j)[X]) ≠ 0 := fun hX =>
  by
  replace hX := congr_arg (fun f => coeff f 1) hX
  simp only [coeff_X_one, coeff_zero] at hX
  exact zero_ne_one hX.symm
[GOAL]
R : Type u
S : Type v
inst✝ : CommRing R
J : Ideal R[X]
j : Ideal R
hj : j ∈ {J | IsMaximal J} ∧ map C j = J
this : IsMaximal j
f : (R ⧸ j)[X]
hf : f ∈ jacobson ⊥
hX : X = 0
⊢ False
[PROOFSTEP]
replace hX := congr_arg (fun f => coeff f 1) hX
[GOAL]
R : Type u
S : Type v
inst✝ : CommRing R
J : Ideal R[X]
j : Ideal R
hj : j ∈ {J | IsMaximal J} ∧ map C j = J
this : IsMaximal j
f : (R ⧸ j)[X]
hf : f ∈ jacobson ⊥
hX : (fun f => coeff f 1) X = (fun f => coeff f 1) 0
⊢ False
[PROOFSTEP]
simp only [coeff_X_one, coeff_zero] at hX
[GOAL]
R : Type u
S : Type v
inst✝ : CommRing R
J : Ideal R[X]
j : Ideal R
hj : j ∈ {J | IsMaximal J} ∧ map C j = J
this : IsMaximal j
f : (R ⧸ j)[X]
hf : f ∈ jacobson ⊥
hX : 1 = 0
⊢ False
[PROOFSTEP]
exact zero_ne_one hX.symm
[GOAL]
R : Type u
S : Type v
inst✝ : CommRing R
J : Ideal R[X]
j : Ideal R
hj : j ∈ {J | IsMaximal J} ∧ map C j = J
this : IsMaximal j
f : (R ⧸ j)[X]
hf : f ∈ jacobson ⊥
r1 : X ≠ 0
⊢ f ∈ ⊥
[PROOFSTEP]
have r2 := eq_C_of_degree_eq_zero (degree_eq_zero_of_isUnit ((mem_jacobson_bot.1 hf) X))
[GOAL]
R : Type u
S : Type v
inst✝ : CommRing R
J : Ideal R[X]
j : Ideal R
hj : j ∈ {J | IsMaximal J} ∧ map C j = J
this : IsMaximal j
f : (R ⧸ j)[X]
hf : f ∈ jacobson ⊥
r1 : X ≠ 0
r2 : f * X + 1 = ↑C (coeff (f * X + 1) 0)
⊢ f ∈ ⊥
[PROOFSTEP]
simp only [coeff_add, mul_coeff_zero, coeff_X_zero, mul_zero, coeff_one_zero, zero_add] at r2
[GOAL]
R : Type u
S : Type v
inst✝ : CommRing R
J : Ideal R[X]
j : Ideal R
hj : j ∈ {J | IsMaximal J} ∧ map C j = J
this : IsMaximal j
f : (R ⧸ j)[X]
hf : f ∈ jacobson ⊥
r1 : X ≠ 0
r2 : f * X + 1 = ↑C 1
⊢ f ∈ ⊥
[PROOFSTEP]
erw [add_left_eq_self] at r2
[GOAL]
R : Type u
S : Type v
inst✝ : CommRing R
J : Ideal R[X]
j : Ideal R
hj : j ∈ {J | IsMaximal J} ∧ map C j = J
this : IsMaximal j
f : (R ⧸ j)[X]
hf : f ∈ jacobson ⊥
r1 : X ≠ 0
r2 : f * X = 0
⊢ f ∈ ⊥
[PROOFSTEP]
simpa using (mul_eq_zero.mp r2).resolve_right r1
[GOAL]
R : Type u
S : Type v
inst✝ : CommRing R
h : jacobson ⊥ = ⊥
⊢ jacobson ⊥ = ⊥
[PROOFSTEP]
refine' eq_bot_iff.2 (le_trans jacobson_bot_polynomial_le_sInf_map_maximal _)
[GOAL]
R : Type u
S : Type v
inst✝ : CommRing R
h : jacobson ⊥ = ⊥
⊢ sInf (map C '' {J | IsMaximal J}) ≤ ⊥
[PROOFSTEP]
refine' fun f hf =>
  (Submodule.mem_bot R[X]).2 <| Polynomial.ext fun n => Trans.trans (?_ : coeff f n = 0) (coeff_zero n).symm
[GOAL]
R : Type u
S : Type v
inst✝ : CommRing R
h : jacobson ⊥ = ⊥
f : R[X]
hf : f ∈ sInf (map C '' {J | IsMaximal J})
n : ℕ
⊢ coeff f n = 0
[PROOFSTEP]
suffices f.coeff n ∈ Ideal.jacobson ⊥ by rwa [h, Submodule.mem_bot] at this
[GOAL]
R : Type u
S : Type v
inst✝ : CommRing R
h : jacobson ⊥ = ⊥
f : R[X]
hf : f ∈ sInf (map C '' {J | IsMaximal J})
n : ℕ
this : coeff f n ∈ jacobson ⊥
⊢ coeff f n = 0
[PROOFSTEP]
rwa [h, Submodule.mem_bot] at this
[GOAL]
R : Type u
S : Type v
inst✝ : CommRing R
h : jacobson ⊥ = ⊥
f : R[X]
hf : f ∈ sInf (map C '' {J | IsMaximal J})
n : ℕ
⊢ coeff f n ∈ jacobson ⊥
[PROOFSTEP]
exact mem_sInf.2 fun j hj => (mem_map_C_iff.1 ((mem_sInf.1 hf) ⟨j, ⟨hj.2, rfl⟩⟩)) n
[GOAL]
R : Type u
S : Type v
inst✝ : CommRing R
I : Ideal R
hi : IsLocal I
x : R
h : I ⊔ span {x} = ⊤
p : R
hpi : p ∈ I
q : R
hq : q ∈ span {x}
hpq : p + q = 1
r : R
hr : q = x * r
⊢ r * x - 1 ∈ I
[PROOFSTEP]
rw [← hpq, mul_comm, ← hr, ← neg_sub, add_sub_cancel]
[GOAL]
R : Type u
S : Type v
inst✝ : CommRing R
I : Ideal R
hi : IsLocal I
x : R
h : I ⊔ span {x} = ⊤
p : R
hpi : p ∈ I
q : R
hq : q ∈ span {x}
hpq : p + q = 1
r : R
hr : q = x * r
⊢ -p ∈ I
[PROOFSTEP]
exact I.neg_mem hpi
[GOAL]
R : Type u
S : Type v
inst✝ : CommRing R
I : Ideal R
hi : IsMaximal (radical I)
this : radical I = jacobson I
x y : R
hxy : x * y ∈ I
x✝ : ∃ y_1, y_1 * y - 1 ∈ I
z : R
hz : z * y - 1 ∈ I
⊢ x ∈ I
[PROOFSTEP]
rw [← mul_one x, ← sub_sub_cancel (z * y) 1, mul_sub, mul_left_comm]
[GOAL]
R : Type u
S : Type v
inst✝ : CommRing R
I : Ideal R
hi : IsMaximal (radical I)
this : radical I = jacobson I
x y : R
hxy : x * y ∈ I
x✝ : ∃ y_1, y_1 * y - 1 ∈ I
z : R
hz : z * y - 1 ∈ I
⊢ z * (x * y) - x * (z * y - 1) ∈ I
[PROOFSTEP]
exact I.sub_mem (I.mul_mem_left _ hxy) (I.mul_mem_left _ hz)


[GOAL]
𝕜 : Type u_1
inst✝⁴ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝³ : SeminormedAddCommGroup E
inst✝² : NormedSpace 𝕜 E
F : Type u_3
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace 𝕜 F
⊢ ‖inclusionInDoubleDual 𝕜 E‖ ≤ 1
[PROOFSTEP]
rw [inclusionInDoubleDual_norm_eq]
[GOAL]
𝕜 : Type u_1
inst✝⁴ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝³ : SeminormedAddCommGroup E
inst✝² : NormedSpace 𝕜 E
F : Type u_3
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace 𝕜 F
⊢ ‖ContinuousLinearMap.id 𝕜 (Dual 𝕜 E)‖ ≤ 1
[PROOFSTEP]
exact ContinuousLinearMap.norm_id_le
[GOAL]
𝕜 : Type u_1
inst✝⁴ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝³ : SeminormedAddCommGroup E
inst✝² : NormedSpace 𝕜 E
F : Type u_3
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace 𝕜 F
x : E
⊢ ‖↑(inclusionInDoubleDual 𝕜 E) x‖ ≤ ‖x‖
[PROOFSTEP]
simpa using ContinuousLinearMap.le_of_op_norm_le _ (inclusionInDoubleDual_norm_le 𝕜 E) x
[GOAL]
𝕜 : Type u_1
inst✝⁴ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝³ : SeminormedAddCommGroup E
inst✝² : NormedSpace 𝕜 E
F : Type u_3
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace 𝕜 F
⊢ LinearMap.SeparatingLeft (dualPairing 𝕜 E)
[PROOFSTEP]
rw [LinearMap.separatingLeft_iff_ker_eq_bot, LinearMap.ker_eq_bot]
[GOAL]
𝕜 : Type u_1
inst✝⁴ : NontriviallyNormedField 𝕜
E : Type u_2
inst✝³ : SeminormedAddCommGroup E
inst✝² : NormedSpace 𝕜 E
F : Type u_3
inst✝¹ : NormedAddCommGroup F
inst✝ : NormedSpace 𝕜 F
⊢ Function.Injective ↑(dualPairing 𝕜 E)
[PROOFSTEP]
exact ContinuousLinearMap.coe_injective
[GOAL]
𝕜 : Type v
inst✝² : IsROrC 𝕜
E : Type u
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x : E
M : ℝ
hMp : 0 ≤ M
hM : ∀ (f : Dual 𝕜 E), ‖↑f x‖ ≤ M * ‖f‖
⊢ ‖x‖ ≤ M
[PROOFSTEP]
classical
by_cases h : x = 0
· simp only [h, hMp, norm_zero]
· obtain ⟨f, hf₁, hfx⟩ : ∃ f : E →L[𝕜] 𝕜, ‖f‖ = 1 ∧ f x = ‖x‖ := exists_dual_vector 𝕜 x h
  calc
    ‖x‖ = ‖(‖x‖ : 𝕜)‖ := IsROrC.norm_coe_norm.symm
    _ = ‖f x‖ := by rw [hfx]
    _ ≤ M * ‖f‖ := (hM f)
    _ = M := by rw [hf₁, mul_one]
[GOAL]
𝕜 : Type v
inst✝² : IsROrC 𝕜
E : Type u
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x : E
M : ℝ
hMp : 0 ≤ M
hM : ∀ (f : Dual 𝕜 E), ‖↑f x‖ ≤ M * ‖f‖
⊢ ‖x‖ ≤ M
[PROOFSTEP]
by_cases h : x = 0
[GOAL]
case pos
𝕜 : Type v
inst✝² : IsROrC 𝕜
E : Type u
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x : E
M : ℝ
hMp : 0 ≤ M
hM : ∀ (f : Dual 𝕜 E), ‖↑f x‖ ≤ M * ‖f‖
h : x = 0
⊢ ‖x‖ ≤ M
[PROOFSTEP]
simp only [h, hMp, norm_zero]
[GOAL]
case neg
𝕜 : Type v
inst✝² : IsROrC 𝕜
E : Type u
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x : E
M : ℝ
hMp : 0 ≤ M
hM : ∀ (f : Dual 𝕜 E), ‖↑f x‖ ≤ M * ‖f‖
h : ¬x = 0
⊢ ‖x‖ ≤ M
[PROOFSTEP]
obtain ⟨f, hf₁, hfx⟩ : ∃ f : E →L[𝕜] 𝕜, ‖f‖ = 1 ∧ f x = ‖x‖ := exists_dual_vector 𝕜 x h
[GOAL]
case neg.intro.intro
𝕜 : Type v
inst✝² : IsROrC 𝕜
E : Type u
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x : E
M : ℝ
hMp : 0 ≤ M
hM : ∀ (f : Dual 𝕜 E), ‖↑f x‖ ≤ M * ‖f‖
h : ¬x = 0
f : E →L[𝕜] 𝕜
hf₁ : ‖f‖ = 1
hfx : ↑f x = ↑‖x‖
⊢ ‖x‖ ≤ M
[PROOFSTEP]
calc
  ‖x‖ = ‖(‖x‖ : 𝕜)‖ := IsROrC.norm_coe_norm.symm
  _ = ‖f x‖ := by rw [hfx]
  _ ≤ M * ‖f‖ := (hM f)
  _ = M := by rw [hf₁, mul_one]
[GOAL]
𝕜 : Type v
inst✝² : IsROrC 𝕜
E : Type u
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x : E
M : ℝ
hMp : 0 ≤ M
hM : ∀ (f : Dual 𝕜 E), ‖↑f x‖ ≤ M * ‖f‖
h : ¬x = 0
f : E →L[𝕜] 𝕜
hf₁ : ‖f‖ = 1
hfx : ↑f x = ↑‖x‖
⊢ ‖↑‖x‖‖ = ‖↑f x‖
[PROOFSTEP]
rw [hfx]
[GOAL]
𝕜 : Type v
inst✝² : IsROrC 𝕜
E : Type u
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x : E
M : ℝ
hMp : 0 ≤ M
hM : ∀ (f : Dual 𝕜 E), ‖↑f x‖ ≤ M * ‖f‖
h : ¬x = 0
f : E →L[𝕜] 𝕜
hf₁ : ‖f‖ = 1
hfx : ↑f x = ↑‖x‖
⊢ M * ‖f‖ = M
[PROOFSTEP]
rw [hf₁, mul_one]
[GOAL]
𝕜 : Type v
inst✝² : IsROrC 𝕜
E : Type u
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x : E
h : ∀ (f : Dual 𝕜 E), ↑f x = 0
f : Dual 𝕜 E
⊢ ‖↑f x‖ ≤ 0 * ‖f‖
[PROOFSTEP]
simp [h f]
[GOAL]
𝕜 : Type v
inst✝² : IsROrC 𝕜
E : Type u
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x : E
hx : x = 0
⊢ ∀ (g : Dual 𝕜 E), ↑g x = 0
[PROOFSTEP]
simp [hx]
[GOAL]
𝕜 : Type v
inst✝² : IsROrC 𝕜
E : Type u
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x y : E
⊢ x = y ↔ ∀ (g : Dual 𝕜 E), ↑g x = ↑g y
[PROOFSTEP]
rw [← sub_eq_zero, eq_zero_iff_forall_dual_eq_zero 𝕜 (x - y)]
[GOAL]
𝕜 : Type v
inst✝² : IsROrC 𝕜
E : Type u
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
x y : E
⊢ (∀ (g : Dual 𝕜 E), ↑g (x - y) = 0) ↔ ∀ (g : Dual 𝕜 E), ↑g x = ↑g y
[PROOFSTEP]
simp [sub_eq_zero]
[GOAL]
𝕜 : Type v
inst✝² : IsROrC 𝕜
E : Type u
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
src✝ : E →L[𝕜] Dual 𝕜 (Dual 𝕜 E) := inclusionInDoubleDual 𝕜 E
⊢ ∀ (x : E), ‖↑↑src✝ x‖ = ‖x‖
[PROOFSTEP]
intro x
[GOAL]
𝕜 : Type v
inst✝² : IsROrC 𝕜
E : Type u
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
src✝ : E →L[𝕜] Dual 𝕜 (Dual 𝕜 E) := inclusionInDoubleDual 𝕜 E
x : E
⊢ ‖↑↑src✝ x‖ = ‖x‖
[PROOFSTEP]
apply le_antisymm
[GOAL]
case a
𝕜 : Type v
inst✝² : IsROrC 𝕜
E : Type u
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
src✝ : E →L[𝕜] Dual 𝕜 (Dual 𝕜 E) := inclusionInDoubleDual 𝕜 E
x : E
⊢ ‖↑↑src✝ x‖ ≤ ‖x‖
[PROOFSTEP]
exact double_dual_bound 𝕜 E x
[GOAL]
case a
𝕜 : Type v
inst✝² : IsROrC 𝕜
E : Type u
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
src✝ : E →L[𝕜] Dual 𝕜 (Dual 𝕜 E) := inclusionInDoubleDual 𝕜 E
x : E
⊢ ‖x‖ ≤ ‖↑↑src✝ x‖
[PROOFSTEP]
rw [ContinuousLinearMap.norm_def]
[GOAL]
case a
𝕜 : Type v
inst✝² : IsROrC 𝕜
E : Type u
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
src✝ : E →L[𝕜] Dual 𝕜 (Dual 𝕜 E) := inclusionInDoubleDual 𝕜 E
x : E
⊢ ‖x‖ ≤ sInf {c | 0 ≤ c ∧ ∀ (x_1 : Dual 𝕜 E), ‖↑(↑↑src✝ x) x_1‖ ≤ c * ‖x_1‖}
[PROOFSTEP]
refine' le_csInf ContinuousLinearMap.bounds_nonempty _
[GOAL]
case a
𝕜 : Type v
inst✝² : IsROrC 𝕜
E : Type u
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
src✝ : E →L[𝕜] Dual 𝕜 (Dual 𝕜 E) := inclusionInDoubleDual 𝕜 E
x : E
⊢ ∀ (b : ℝ), b ∈ {c | 0 ≤ c ∧ ∀ (x_1 : Dual 𝕜 E), ‖↑(↑↑src✝ x) x_1‖ ≤ c * ‖x_1‖} → ‖x‖ ≤ b
[PROOFSTEP]
rintro c ⟨hc1, hc2⟩
[GOAL]
case a.intro
𝕜 : Type v
inst✝² : IsROrC 𝕜
E : Type u
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
src✝ : E →L[𝕜] Dual 𝕜 (Dual 𝕜 E) := inclusionInDoubleDual 𝕜 E
x : E
c : ℝ
hc1 : 0 ≤ c
hc2 : ∀ (x_1 : Dual 𝕜 E), ‖↑(↑↑src✝ x) x_1‖ ≤ c * ‖x_1‖
⊢ ‖x‖ ≤ c
[PROOFSTEP]
exact norm_le_dual_bound 𝕜 x hc1 hc2
[GOAL]
𝕜 : Type u_1
inst✝² : NontriviallyNormedField 𝕜
E : Type u_2
inst✝¹ : SeminormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
s : Set E
⊢ IsClosed (polar 𝕜 s)
[PROOFSTEP]
dsimp only [NormedSpace.polar]
[GOAL]
𝕜 : Type u_1
inst✝² : NontriviallyNormedField 𝕜
E : Type u_2
inst✝¹ : SeminormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
s : Set E
⊢ IsClosed (LinearMap.polar (LinearMap.flip (dualPairing 𝕜 E)) s)
[PROOFSTEP]
simp only [LinearMap.polar_eq_iInter, LinearMap.flip_apply]
[GOAL]
𝕜 : Type u_1
inst✝² : NontriviallyNormedField 𝕜
E : Type u_2
inst✝¹ : SeminormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
s : Set E
⊢ IsClosed (⋂ (x : E) (_ : x ∈ s), {y | ‖↑(↑(dualPairing 𝕜 E) y) x‖ ≤ 1})
[PROOFSTEP]
refine' isClosed_biInter fun z _ => _
[GOAL]
𝕜 : Type u_1
inst✝² : NontriviallyNormedField 𝕜
E : Type u_2
inst✝¹ : SeminormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
s : Set E
z : E
x✝ : z ∈ s
⊢ IsClosed {y | ‖↑(↑(dualPairing 𝕜 E) y) z‖ ≤ 1}
[PROOFSTEP]
exact isClosed_Iic.preimage (ContinuousLinearMap.apply 𝕜 𝕜 z).continuous.norm
[GOAL]
𝕜 : Type u_1
inst✝² : NontriviallyNormedField 𝕜
E : Type u_2
inst✝¹ : SeminormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
s : Set E
⊢ IsClosed
    ((LinearMap.polar (LinearMap.flip (LinearMap.flip (dualPairing 𝕜 E))) ∘ ↑OrderDual.ofDual)
      (LinearMap.polar (LinearMap.flip (dualPairing 𝕜 E)) s))
[PROOFSTEP]
simpa [LinearMap.flip_flip] using (isClosed_polar _ _).preimage (inclusionInDoubleDual 𝕜 E).continuous
[GOAL]
𝕜 : Type u_1
inst✝² : NontriviallyNormedField 𝕜
E : Type u_2
inst✝¹ : SeminormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
s : Set E
x' : Dual 𝕜 E
c : 𝕜
hc : ∀ (z : E), z ∈ s → ‖↑x' z‖ ≤ ‖c‖
⊢ c⁻¹ • x' ∈ polar 𝕜 s
[PROOFSTEP]
by_cases c_zero : c = 0
[GOAL]
case pos
𝕜 : Type u_1
inst✝² : NontriviallyNormedField 𝕜
E : Type u_2
inst✝¹ : SeminormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
s : Set E
x' : Dual 𝕜 E
c : 𝕜
hc : ∀ (z : E), z ∈ s → ‖↑x' z‖ ≤ ‖c‖
c_zero : c = 0
⊢ c⁻¹ • x' ∈ polar 𝕜 s
[PROOFSTEP]
simp only [c_zero, inv_zero, zero_smul]
[GOAL]
case pos
𝕜 : Type u_1
inst✝² : NontriviallyNormedField 𝕜
E : Type u_2
inst✝¹ : SeminormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
s : Set E
x' : Dual 𝕜 E
c : 𝕜
hc : ∀ (z : E), z ∈ s → ‖↑x' z‖ ≤ ‖c‖
c_zero : c = 0
⊢ 0 ∈ polar 𝕜 s
[PROOFSTEP]
exact (dualPairing 𝕜 E).flip.zero_mem_polar _
[GOAL]
case neg
𝕜 : Type u_1
inst✝² : NontriviallyNormedField 𝕜
E : Type u_2
inst✝¹ : SeminormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
s : Set E
x' : Dual 𝕜 E
c : 𝕜
hc : ∀ (z : E), z ∈ s → ‖↑x' z‖ ≤ ‖c‖
c_zero : ¬c = 0
⊢ c⁻¹ • x' ∈ polar 𝕜 s
[PROOFSTEP]
have eq : ∀ z, ‖c⁻¹ • x' z‖ = ‖c⁻¹‖ * ‖x' z‖ := fun z => norm_smul c⁻¹ _
[GOAL]
case neg
𝕜 : Type u_1
inst✝² : NontriviallyNormedField 𝕜
E : Type u_2
inst✝¹ : SeminormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
s : Set E
x' : Dual 𝕜 E
c : 𝕜
hc : ∀ (z : E), z ∈ s → ‖↑x' z‖ ≤ ‖c‖
c_zero : ¬c = 0
eq : ∀ (z : E), ‖c⁻¹ • ↑x' z‖ = ‖c⁻¹‖ * ‖↑x' z‖
⊢ c⁻¹ • x' ∈ polar 𝕜 s
[PROOFSTEP]
have le : ∀ z, z ∈ s → ‖c⁻¹ • x' z‖ ≤ ‖c⁻¹‖ * ‖c‖ := by
  intro z hzs
  rw [eq z]
  apply mul_le_mul (le_of_eq rfl) (hc z hzs) (norm_nonneg _) (norm_nonneg _)
[GOAL]
𝕜 : Type u_1
inst✝² : NontriviallyNormedField 𝕜
E : Type u_2
inst✝¹ : SeminormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
s : Set E
x' : Dual 𝕜 E
c : 𝕜
hc : ∀ (z : E), z ∈ s → ‖↑x' z‖ ≤ ‖c‖
c_zero : ¬c = 0
eq : ∀ (z : E), ‖c⁻¹ • ↑x' z‖ = ‖c⁻¹‖ * ‖↑x' z‖
⊢ ∀ (z : E), z ∈ s → ‖c⁻¹ • ↑x' z‖ ≤ ‖c⁻¹‖ * ‖c‖
[PROOFSTEP]
intro z hzs
[GOAL]
𝕜 : Type u_1
inst✝² : NontriviallyNormedField 𝕜
E : Type u_2
inst✝¹ : SeminormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
s : Set E
x' : Dual 𝕜 E
c : 𝕜
hc : ∀ (z : E), z ∈ s → ‖↑x' z‖ ≤ ‖c‖
c_zero : ¬c = 0
eq : ∀ (z : E), ‖c⁻¹ • ↑x' z‖ = ‖c⁻¹‖ * ‖↑x' z‖
z : E
hzs : z ∈ s
⊢ ‖c⁻¹ • ↑x' z‖ ≤ ‖c⁻¹‖ * ‖c‖
[PROOFSTEP]
rw [eq z]
[GOAL]
𝕜 : Type u_1
inst✝² : NontriviallyNormedField 𝕜
E : Type u_2
inst✝¹ : SeminormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
s : Set E
x' : Dual 𝕜 E
c : 𝕜
hc : ∀ (z : E), z ∈ s → ‖↑x' z‖ ≤ ‖c‖
c_zero : ¬c = 0
eq : ∀ (z : E), ‖c⁻¹ • ↑x' z‖ = ‖c⁻¹‖ * ‖↑x' z‖
z : E
hzs : z ∈ s
⊢ ‖c⁻¹‖ * ‖↑x' z‖ ≤ ‖c⁻¹‖ * ‖c‖
[PROOFSTEP]
apply mul_le_mul (le_of_eq rfl) (hc z hzs) (norm_nonneg _) (norm_nonneg _)
[GOAL]
case neg
𝕜 : Type u_1
inst✝² : NontriviallyNormedField 𝕜
E : Type u_2
inst✝¹ : SeminormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
s : Set E
x' : Dual 𝕜 E
c : 𝕜
hc : ∀ (z : E), z ∈ s → ‖↑x' z‖ ≤ ‖c‖
c_zero : ¬c = 0
eq : ∀ (z : E), ‖c⁻¹ • ↑x' z‖ = ‖c⁻¹‖ * ‖↑x' z‖
le : ∀ (z : E), z ∈ s → ‖c⁻¹ • ↑x' z‖ ≤ ‖c⁻¹‖ * ‖c‖
⊢ c⁻¹ • x' ∈ polar 𝕜 s
[PROOFSTEP]
have cancel : ‖c⁻¹‖ * ‖c‖ = 1 := by simp only [c_zero, norm_eq_zero, Ne.def, not_false_iff, inv_mul_cancel, norm_inv]
[GOAL]
𝕜 : Type u_1
inst✝² : NontriviallyNormedField 𝕜
E : Type u_2
inst✝¹ : SeminormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
s : Set E
x' : Dual 𝕜 E
c : 𝕜
hc : ∀ (z : E), z ∈ s → ‖↑x' z‖ ≤ ‖c‖
c_zero : ¬c = 0
eq : ∀ (z : E), ‖c⁻¹ • ↑x' z‖ = ‖c⁻¹‖ * ‖↑x' z‖
le : ∀ (z : E), z ∈ s → ‖c⁻¹ • ↑x' z‖ ≤ ‖c⁻¹‖ * ‖c‖
⊢ ‖c⁻¹‖ * ‖c‖ = 1
[PROOFSTEP]
simp only [c_zero, norm_eq_zero, Ne.def, not_false_iff, inv_mul_cancel, norm_inv]
[GOAL]
case neg
𝕜 : Type u_1
inst✝² : NontriviallyNormedField 𝕜
E : Type u_2
inst✝¹ : SeminormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
s : Set E
x' : Dual 𝕜 E
c : 𝕜
hc : ∀ (z : E), z ∈ s → ‖↑x' z‖ ≤ ‖c‖
c_zero : ¬c = 0
eq : ∀ (z : E), ‖c⁻¹ • ↑x' z‖ = ‖c⁻¹‖ * ‖↑x' z‖
le : ∀ (z : E), z ∈ s → ‖c⁻¹ • ↑x' z‖ ≤ ‖c⁻¹‖ * ‖c‖
cancel : ‖c⁻¹‖ * ‖c‖ = 1
⊢ c⁻¹ • x' ∈ polar 𝕜 s
[PROOFSTEP]
rwa [cancel] at le
[GOAL]
𝕜 : Type u_1
inst✝² : NontriviallyNormedField 𝕜
E : Type u_2
inst✝¹ : SeminormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
c : 𝕜
hc : 1 < ‖c‖
r : ℝ
hr : 0 < r
⊢ polar 𝕜 (ball 0 r) ⊆ closedBall 0 (‖c‖ / r)
[PROOFSTEP]
intro x' hx'
[GOAL]
𝕜 : Type u_1
inst✝² : NontriviallyNormedField 𝕜
E : Type u_2
inst✝¹ : SeminormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
c : 𝕜
hc : 1 < ‖c‖
r : ℝ
hr : 0 < r
x' : Dual 𝕜 E
hx' : x' ∈ polar 𝕜 (ball 0 r)
⊢ x' ∈ closedBall 0 (‖c‖ / r)
[PROOFSTEP]
rw [mem_polar_iff] at hx'
[GOAL]
𝕜 : Type u_1
inst✝² : NontriviallyNormedField 𝕜
E : Type u_2
inst✝¹ : SeminormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
c : 𝕜
hc : 1 < ‖c‖
r : ℝ
hr : 0 < r
x' : Dual 𝕜 E
hx' : ∀ (z : E), z ∈ ball 0 r → ‖↑x' z‖ ≤ 1
⊢ x' ∈ closedBall 0 (‖c‖ / r)
[PROOFSTEP]
simp only [polar, mem_setOf, mem_closedBall_zero_iff, mem_ball_zero_iff] at *
[GOAL]
𝕜 : Type u_1
inst✝² : NontriviallyNormedField 𝕜
E : Type u_2
inst✝¹ : SeminormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
c : 𝕜
hc : 1 < ‖c‖
r : ℝ
hr : 0 < r
x' : Dual 𝕜 E
hx' : ∀ (z : E), ‖z‖ < r → ‖↑x' z‖ ≤ 1
⊢ ‖x'‖ ≤ ‖c‖ / r
[PROOFSTEP]
have hcr : 0 < ‖c‖ / r := div_pos (zero_lt_one.trans hc) hr
[GOAL]
𝕜 : Type u_1
inst✝² : NontriviallyNormedField 𝕜
E : Type u_2
inst✝¹ : SeminormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
c : 𝕜
hc : 1 < ‖c‖
r : ℝ
hr : 0 < r
x' : Dual 𝕜 E
hx' : ∀ (z : E), ‖z‖ < r → ‖↑x' z‖ ≤ 1
hcr : 0 < ‖c‖ / r
⊢ ‖x'‖ ≤ ‖c‖ / r
[PROOFSTEP]
refine' ContinuousLinearMap.op_norm_le_of_shell hr hcr.le hc fun x h₁ h₂ => _
[GOAL]
𝕜 : Type u_1
inst✝² : NontriviallyNormedField 𝕜
E : Type u_2
inst✝¹ : SeminormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
c : 𝕜
hc : 1 < ‖c‖
r : ℝ
hr : 0 < r
x' : Dual 𝕜 E
hx' : ∀ (z : E), ‖z‖ < r → ‖↑x' z‖ ≤ 1
hcr : 0 < ‖c‖ / r
x : E
h₁ : r / ‖c‖ ≤ ‖x‖
h₂ : ‖x‖ < r
⊢ ‖↑x' x‖ ≤ ‖c‖ / r * ‖x‖
[PROOFSTEP]
calc
  ‖x' x‖ ≤ 1 := hx' _ h₂
  _ ≤ ‖c‖ / r * ‖x‖ := (inv_pos_le_iff_one_le_mul' hcr).1 (by rwa [inv_div])
[GOAL]
𝕜 : Type u_1
inst✝² : NontriviallyNormedField 𝕜
E : Type u_2
inst✝¹ : SeminormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
c : 𝕜
hc : 1 < ‖c‖
r : ℝ
hr : 0 < r
x' : Dual 𝕜 E
hx' : ∀ (z : E), ‖z‖ < r → ‖↑x' z‖ ≤ 1
hcr : 0 < ‖c‖ / r
x : E
h₁ : r / ‖c‖ ≤ ‖x‖
h₂ : ‖x‖ < r
⊢ (‖c‖ / r)⁻¹ ≤ ‖x‖
[PROOFSTEP]
rwa [inv_div]
[GOAL]
𝕜✝ : Type u_1
inst✝⁵ : NontriviallyNormedField 𝕜✝
E✝ : Type u_2
inst✝⁴ : SeminormedAddCommGroup E✝
inst✝³ : NormedSpace 𝕜✝ E✝
𝕜 : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
r : ℝ
hr : 0 < r
⊢ polar 𝕜 (closedBall 0 r) = closedBall 0 r⁻¹
[PROOFSTEP]
refine' Subset.antisymm _ (closedBall_inv_subset_polar_closedBall 𝕜)
[GOAL]
𝕜✝ : Type u_1
inst✝⁵ : NontriviallyNormedField 𝕜✝
E✝ : Type u_2
inst✝⁴ : SeminormedAddCommGroup E✝
inst✝³ : NormedSpace 𝕜✝ E✝
𝕜 : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
r : ℝ
hr : 0 < r
⊢ polar 𝕜 (closedBall 0 r) ⊆ closedBall 0 r⁻¹
[PROOFSTEP]
intro x' h
[GOAL]
𝕜✝ : Type u_1
inst✝⁵ : NontriviallyNormedField 𝕜✝
E✝ : Type u_2
inst✝⁴ : SeminormedAddCommGroup E✝
inst✝³ : NormedSpace 𝕜✝ E✝
𝕜 : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
r : ℝ
hr : 0 < r
x' : Dual 𝕜 E
h : x' ∈ polar 𝕜 (closedBall 0 r)
⊢ x' ∈ closedBall 0 r⁻¹
[PROOFSTEP]
simp only [mem_closedBall_zero_iff]
[GOAL]
𝕜✝ : Type u_1
inst✝⁵ : NontriviallyNormedField 𝕜✝
E✝ : Type u_2
inst✝⁴ : SeminormedAddCommGroup E✝
inst✝³ : NormedSpace 𝕜✝ E✝
𝕜 : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
r : ℝ
hr : 0 < r
x' : Dual 𝕜 E
h : x' ∈ polar 𝕜 (closedBall 0 r)
⊢ ‖x'‖ ≤ r⁻¹
[PROOFSTEP]
refine' ContinuousLinearMap.op_norm_le_of_ball hr (inv_nonneg.mpr hr.le) fun z _ => _
[GOAL]
𝕜✝ : Type u_1
inst✝⁵ : NontriviallyNormedField 𝕜✝
E✝ : Type u_2
inst✝⁴ : SeminormedAddCommGroup E✝
inst✝³ : NormedSpace 𝕜✝ E✝
𝕜 : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : NormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
r : ℝ
hr : 0 < r
x' : Dual 𝕜 E
h : x' ∈ polar 𝕜 (closedBall 0 r)
z : E
x✝ : z ∈ ball 0 r
⊢ ‖↑x' z‖ ≤ r⁻¹ * ‖z‖
[PROOFSTEP]
simpa only [one_div] using LinearMap.bound_of_ball_bound' hr 1 x'.toLinearMap h z
[GOAL]
𝕜 : Type u_1
inst✝² : NontriviallyNormedField 𝕜
E : Type u_2
inst✝¹ : SeminormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
s : Set E
s_nhd : s ∈ 𝓝 0
⊢ Metric.Bounded (polar 𝕜 s)
[PROOFSTEP]
obtain ⟨a, ha⟩ : ∃ a : 𝕜, 1 < ‖a‖ := NormedField.exists_one_lt_norm 𝕜
[GOAL]
case intro
𝕜 : Type u_1
inst✝² : NontriviallyNormedField 𝕜
E : Type u_2
inst✝¹ : SeminormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
s : Set E
s_nhd : s ∈ 𝓝 0
a : 𝕜
ha : 1 < ‖a‖
⊢ Metric.Bounded (polar 𝕜 s)
[PROOFSTEP]
obtain ⟨r, r_pos, r_ball⟩ : ∃ r : ℝ, 0 < r ∧ ball 0 r ⊆ s := Metric.mem_nhds_iff.1 s_nhd
[GOAL]
case intro.intro.intro
𝕜 : Type u_1
inst✝² : NontriviallyNormedField 𝕜
E : Type u_2
inst✝¹ : SeminormedAddCommGroup E
inst✝ : NormedSpace 𝕜 E
s : Set E
s_nhd : s ∈ 𝓝 0
a : 𝕜
ha : 1 < ‖a‖
r : ℝ
r_pos : 0 < r
r_ball : ball 0 r ⊆ s
⊢ Metric.Bounded (polar 𝕜 s)
[PROOFSTEP]
exact
  bounded_closedBall.mono
    (((dualPairing 𝕜 E).flip.polar_antitone r_ball).trans <| polar_ball_subset_closedBall_div ha r_pos)