module public import Groebner.Groebner public import Groebner.Ideal variable {σ R : Type*} [CommSemiring R] {m : MonomialOrder σ} variable {G : Set (MvPolynomial σ R)} {I : Ideal (MvPolynomial σ R)} variable (hG : m.IsGroebnerBasis G I) @[expose] public section namespace MonomialOrder open MvPolynomial MonomialOrder IsRemainder IsGroebnerBasis set_option linter.unusedVariables false in def IsGroebnerBasis.IsMinimal (hG : m.IsGroebnerBasis G I) := (∀ p ∈ G, m.Monic p) ∧ (∀ p ∈ G, ∀ q ∈ G, q ≠ p → ¬ m.degree q ≤ m.degree p) def IsGroebnerBasis.IsMinimal.isMinimal_def (hG : m.IsGroebnerBasis G I) : hG.IsMinimal ↔ (∀ p ∈ G, m.Monic p) ∧ G.Pairwise (¬ m.degree · ≤ m.degree ·) := by rw [IsMinimal, Set.Pairwise] tauto def IsGroebnerBasis.IsMinimal.monic {hG : m.IsGroebnerBasis G I} (hG' : hG.IsMinimal) {p} (h : p ∈ G) : m.Monic p := hG'.1 _ h def IsGroebnerBasis.IsMinimal.pairwise {hG : m.IsGroebnerBasis G I} (hG' : hG.IsMinimal) : G.Pairwise (¬ m.degree · ≤ m.degree ·) := (isMinimal_def .. |>.mp hG').2 set_option linter.unusedVariables false in def IsGroebnerBasis.IsReduced (hG : m.IsGroebnerBasis G I) := (∀ p ∈ G, m.Monic p) ∧ ∀ p ∈ G, m.IsRemainder p (G \ {p}) p -- lemma degree_eq_iff_of_isRemainder {p r : MvPolynomial σ R} -- (hG : m.IsRemainder p G r) -- (hG' : ∀ g ∈ G, IsUnit (m.leadingCoeff g)) : -- m.degree p = m.degree r ↔ -- ∀ g ∈ G, ¬ m.degree g ≤ m.degree p := by -- unfold IsRemainder at hG -- sorry -- lemma leadingTerm_eq_iff_of_isRemainder {p r : MvPolynomial σ R} -- (hG : m.IsRemainder p G r) -- (hG' : ∀ g ∈ G, IsUnit (m.leadingCoeff g)) : -- m.leadingTerm p = m.leadingTerm r ↔ -- ∀ g ∈ G, ¬ m.degree g ≤ m.degree p := by -- sorry -- lemma isGroebnerBasis_of_isRemainder_of_isGroebnerBasis -- {R : Type*} [CommRing R] {m : MonomialOrder σ} -- {G : Set (MvPolynomial σ R)} {I : Ideal (MvPolynomial σ R)} -- (hG : m.IsGroebnerBasis G I) (hG' : ∀ g ∈ G, IsUnit (m.leadingCoeff g)) -- (r : G → MvPolynomial σ R) (hr : ∀ g : G, m.IsRemainder ↑g (G \ {↑g}) (r g)) : -- m.IsGroebnerBasis (Set.range r) I := by -- have rmemI (g : G) : r g ∈ I := by -- rw [m.mem_ideal_iff _ (hr g)] -- · exact Set.mem_of_subset_of_mem hG.1 g.2 -- rw [Set.diff_singleton_subset_iff, Set.subset_insert_iff] -- simp [hG.1] -- constructor -- · intro r' -- rw [Set.mem_range] -- rintro ⟨g, hg⟩ -- exact hg ▸ rmemI g -- refine le_antisymm ?_ ?_ -- on_goal -1 => -- rw [Ideal.span_le] -- intro _ -- simp only [Set.mem_image, Set.mem_range] -- rintro ⟨_, ⟨g, hg⟩, hg'⟩ -- subst hg hg' -- apply Submodule.mem_span_of_mem (Set.mem_image_of_mem m.leadingTerm <| rmemI g) -- rw [hG.2, Ideal.span_le] -- intro _ -- rw [Set.mem_image] -- rintro ⟨g, hgI, hLTg⟩ -- subst hLTg -- -- rw [monomial_notMem_span_leadingTerm] -- sorry -- `hG` can be generalized more. lemma IsGroebnerBasis.isGroebnerBasis_minimal (hG : m.IsGroebnerBasis G I) {G' : Set (MvPolynomial σ R)} (h : G' ⊆ I) (hG' : ∀ g ∈ G', IsUnit (m.leadingCoeff g)) (h' : {a | Minimal (· ∈ m.degree '' (G \ {0})) a} ⊆ m.degree '' G') : m.IsGroebnerBasis G' I := by rw [isGroebnerBasis_iff, m.span_leadingTerm_eq_span_monomial hG'] exists h have := hG.span_leadingTerm_image apply (le_of_eq_of_le · <| m.span_leadingTerm_le_span_monomial ..) at this rw [Ideal.span_le] at this apply le_trans this simp_rw [← Set.image_image (monomial · (1 : R)) m.degree] rw [ideal_span_monomial_image_eq_ideal_span_monomial_image_minimal] apply Ideal.span_mono exact Set.image_mono h' lemma IsGroebnerBasis.isGroebnerBasis_monomial (s : Set (σ →₀ ℕ)) : m.IsGroebnerBasis ((MvPolynomial.monomial · (1 : R)) '' s) (Ideal.span ((MvPolynomial.monomial · 1) '' s)) := by classical wlog! nontrivial : Nontrivial R generalizing · exact IsGroebnerBasis.of_subsingleton .. refine ⟨Ideal.subset_span, ?_⟩ rw [le_antisymm_iff, Ideal.span_le, Ideal.span_le] constructor case right => apply (subset_trans · Ideal.subset_span) apply Set.image_mono exact Ideal.subset_span rw [m.span_leadingTerm_eq_span_monomial (by simp), Set.image_image] simp [-Set.image_subset_iff, m.degree_monomial] intro p simp [mem_ideal_span_monomial_image, leadingTerm] aesop lemma IsGroebnerBasis.isGroebnerBasis_monomial_minimal {R : Type*} [CommSemiring R] (s : Set (σ →₀ ℕ)) : m.IsGroebnerBasis ((MvPolynomial.monomial · (1 : R)) '' {x | Minimal (· ∈ s) x}) (Ideal.span ((MvPolynomial.monomial · 1) '' s)) := by classical wlog! nontrivial : Nontrivial R generalizing · exact IsGroebnerBasis.of_subsingleton .. constructor · apply (subset_trans · Ideal.subset_span) exact Set.image_mono <| setOf_minimal_subset s simpa [Set.image_image, ← MvPolynomial.ideal_span_monomial_image_eq_ideal_span_monomial_image_minimal] using isGroebnerBasis_monomial (m := m) (s := s) (R := R) |>.2 lemma IsGroebnerBasis.smul {ι : Type*} (f : ι → R) (f' : ι → MvPolynomial σ R) (hf : ∀ i : ι, IsUnit (f i)) (hG : m.IsGroebnerBasis (Set.range f') I) : m.IsGroebnerBasis (Set.range (fun i ↦ (f i) • (f' i))) I := by -- the proof can be generalized classical simp_rw [smul_eq_C_mul] constructor · intro p simp_rw [Set.mem_range] rintro ⟨q, rfl⟩ exact Ideal.mul_mem_left I _ (hG.1 <| by simp) rw [hG.2] unfold Ideal.span rw [Submodule.span_eq_iSup_of_singleton_spans, Submodule.span_eq_iSup_of_singleton_spans] have hunit (i) : IsUnit (C (σ := σ) (f i)) := RingHom.isUnit_map C (hf i) simp_rw [iSup_image, iSup_range] congr ext i : 1 convert Submodule.span_singleton_smul_eq (hunit i) (m.leadingTerm (f' i)) |>.symm using 3 simp [leadingTerm, C_mul_monomial, leadingCoeff] suffices m.degree (C (f i) * (f' i)) = m.degree (f' i) by simp [this] wlog! hg : f' i ≠ 0 · simp [hg] rw [m.degree_mul_of_isRegular_left, m.degree_C, zero_add] · simp [leadingCoeff, hf i |>.isRegular] · exact hg lemma IsGroebnerBasis.smul_iff {ι : Type*} (f : ι → R) (f' : ι → MvPolynomial σ R) (hf : ∀ i : ι, IsUnit (f i)) : m.IsGroebnerBasis (Set.range (fun i ↦ (f i) • (f' i))) I ↔ m.IsGroebnerBasis (Set.range f') I := by classical refine ⟨?_, IsGroebnerBasis.smul f f' hf⟩ convert IsGroebnerBasis.smul (fun i ↦ ↑(hf i).unit⁻¹) (fun i ↦ (f i) • (f' i)) (by simp) (I := I) simp [smul_smul] lemma IsGroebnerBasis.inv (hG : m.IsGroebnerBasis G I) (hG' : ∀ g ∈ G, IsUnit (m.leadingCoeff g)) : m.IsGroebnerBasis (Set.range fun (g : G) ↦ (hG' _ g.prop).unit⁻¹ • g.val) I := smul (hG := by simp [hG]) (hf := by simp) lemma IsGroebnerBasis.span_image_leadingTerm (hG : m.IsGroebnerBasis G I) (hG' : ∀ g ∈ G, IsUnit (m.leadingCoeff g)) : m.IsGroebnerBasis (m.leadingTerm '' G) (Ideal.span (m.leadingTerm '' I)) := by classical rw [hG.2, Set.image_eq_range, ← IsGroebnerBasis.smul_iff (f := fun (g : G) ↦ ↑(hG' g.1 g.2).unit⁻¹) (hf := by simp), ← Set.image_eq_range, m.span_leadingTerm_eq_span_monomial hG'] simp [leadingTerm, smul_monomial, ← Set.image_eq_range (fun g ↦ monomial (m.degree g) (1 : R)) G, ← Set.image_image (monomial · (1 : R)), IsGroebnerBasis.isGroebnerBasis_monomial (σ := σ) (m := m)] open MvPolynomial MonomialOrder MonomialOrder.IsGroebnerBasis namespace IsGroebnerBasis variable {hG} -- todo: move lemma IsRemainder.self_iff (p : MvPolynomial σ R) (G : Set (MvPolynomial σ R)) : m.IsRemainder p G p ↔ ∀ a ∈ p.support, ∀ q ∈ G, q ≠ 0 → ¬ m.degree q ≤ a := and_iff_right ⟨0, by simp⟩ lemma IsRemainder.self_tfae (p : MvPolynomial σ R) (G : Set (MvPolynomial σ R)) : [m.IsRemainder p G p, ∀ B' ⊆ G, m.IsRemainder p B' p, ∀ q ∈ G, m.IsRemainder p {q} p, ∀ a ∈ p.support, ∀ q ∈ G, q ≠ 0 → ¬ m.degree q ≤ a].TFAE := by classical apply List.tfae_of_forall (∀ a ∈ p.support, ∀ q ∈ G, q ≠ 0 → ¬ m.degree q ≤ a) intro h h fin_cases h · exact IsRemainder.self_iff .. · simp only [IsRemainder.self_iff] aesop · simp only [IsRemainder.self_iff] aesop rfl lemma IsRemainder.self {p r : MvPolynomial σ R} (h : m.IsRemainder p G r) : m.IsRemainder r G r := ⟨⟨0, by simp⟩, h.2⟩ lemma IsReduced.isReduced_def : hG.IsReduced ↔ (∀ p ∈ G, m.Monic p) ∧ ∀ p ∈ G, ∀ a ∈ p.support, ∀ q ∈ G, q ≠ p → ¬ m.degree q ≤ a := by simp? [IsReduced, IsRemainder.self_iff] says simp only [IsReduced, IsRemainder.self_iff, mem_support_iff, ne_eq, Set.mem_diff, Set.mem_singleton_iff, and_imp, and_congr_right_iff] rintro h1 wlog! h : Nontrivial R · simp [Subsingleton.eq_zero] have (g) (hg : g ∈ G) : g ≠ 0 := (h1 g hg).ne_zero aesop -- lemma IsReduced.isReduced_def' : -- hG.IsReduced ↔ -- (∀ p ∈ G, m.Monic p) ∧ -- ∀ p ∈ G, ∀ a ∈ p.support, ∀ q ∈ I, q ≠ p → ¬ m.degree q ≤ a := by lemma IsReduced.isMinimal : hG.IsReduced → hG.IsMinimal := by rw [IsReduced.isReduced_def, IsMinimal] intro h refine ⟨h.1, ?_⟩ intro p hp q hq wlog! nontrivial : Nontrivial R · simp [Subsingleton.eq_zero] exact h.2 p hp (m.degree p) (by simp [h.1 p hp |>.ne_zero]) q hq @[simp] lemma IsReduced.of_subsingleton [Subsingleton (MvPolynomial σ R)] {s : Set (MvPolynomial σ R)} {I : Ideal (MvPolynomial σ R)} : (IsGroebnerBasis.of_subsingleton (m := m) (s := s) (I := I)).IsReduced := by simp [IsReduced, Subsingleton.eq_zero (α := MvPolynomial σ R), Monic, ← (MvPolynomial.C_injective σ R).eq_iff] @[simp] lemma IsMinimal.of_subsingleton [Subsingleton (MvPolynomial σ R)] {s : Set (MvPolynomial σ R)} {I : Ideal (MvPolynomial σ R)} : (IsGroebnerBasis.of_subsingleton (m := m) (s := s) (I := I)).IsMinimal := IsReduced.isMinimal IsReduced.of_subsingleton lemma IsReduced.isReduced_monomial {s : Set (σ →₀ ℕ)} {I : Ideal (MvPolynomial σ R)} (h : m.IsGroebnerBasis ((MvPolynomial.monomial · (1 : R)) '' {x | Minimal (· ∈ s) x}) I) : h.IsReduced := by classical rw [IsReduced.isReduced_def] constructor · simp simp_rw [Set.mem_image, Set.mem_setOf] rintro p ⟨p', ⟨hp', rfl⟩⟩ a ha q ⟨q', ⟨hq', rfl⟩⟩ hqp simp [monomial_eq_monomial_iff] at hqp have : Nontrivial R := nontrivial_of_ne _ _ hqp.2 simp at ha subst ha simp [degree_monomial] by_contra! hq'p' exact hqp.1 <| le_antisymm hq'p' <| hp'.le_of_le (hq'.prop) hq'p' -- lemma isMinimal_monomial_iff_isReduced_monomial {s : Set (σ →₀ ℕ)} {I : Ideal (MvPolynomial σ R)} -- (hs : m.IsGroebnerBasis ((MvPolynomial.monomial · (1 : R)) '' s) I) : -- hs.IsMinimal ↔ hs.IsReduced := by -- rw [IsMinimal, isReduced_def] -- apply Iff.and (Iff.refl _) -- simp_rw [Set.mem_image] -- -- easy -- sorry lemma IsMinimal.image_leadingTerm_eq_image_monomial_one (hG' : hG.IsMinimal) : m.leadingTerm '' G = (fun p ↦ monomial (m.degree p) 1) '' G := by simp_rw [Set.image_eq_range] congr ext x : 1 simp [leadingTerm, hG'.1] lemma IsMinimal.isReduced_leadingTerm (hG' : hG.IsMinimal) : IsGroebnerBasis.span_image_leadingTerm hG (by simp_intro .. [hG'.1]) |>.IsReduced := by classical wlog! nontrivial : Nontrivial R · simp rw [IsReduced.isReduced_def] constructor · simpa using hG'.1 have := hG'.2 simp_rw [Set.mem_image] rintro _ ⟨p, ⟨hp, rfl⟩⟩ simp_rw [support_leadingTerm' (hG'.1 p hp).ne_zero, Finset.mem_singleton] rintro _ rfl _ ⟨q, ⟨hq, rfl⟩⟩ hqp simp [degree_leadingTerm, this _ hp _ hq (by aesop)] -- lemσisReduced_span_monomial_iff {R : Type*} [CommSemiring R] {s : Set (σ →₀ ℕ)} -- {I : Ideal (MvPolynomial σ R)} -- (h : m.IsGroebnerBasis ((MvPolynomial.monomial · (1 : R)) '' {x | Minimal (· ∈ s) x}) I) : -- h.IsReduced := by -- classical -- rw [isReduced_def] -- constructor -- · simp -- simp_rw [Set.mem_image, Set.mem_setOf] -- rintro p ⟨p', ⟨hp', rfl⟩⟩ a ha q ⟨q', ⟨hq', rfl⟩⟩ hqp -- simp [monomial_eq_monomial_iff] at hqp -- have : Nontrivial R := nontrivial_of_ne _ _ hqp.2 -- simp at ha -- subst ha -- simp [degree_monomial] -- by_contra! hq'p' -- exact hqp.1 <| le_antisymm hq'p' <| hp'.le_of_le (hq'.prop) hq'p' -- lemma _root_.Set.eq_iff_of_image_eq {α β : Type*} {f : α → β} {s t : Set α} -- (hf : f '' s = f '' t) : s = t ↔ ∀ a ∈ s, ∀ b ∈ t, f s = f t lemma IsMinimal.isGroebnerBasis_of_isMinimal_leadingTerm (hG : m.IsGroebnerBasis (m.leadingTerm '' G) (Ideal.span <| m.leadingTerm '' I)) (hGsubset : G ⊆ I) : m.IsGroebnerBasis G I := by classical refine ⟨hGsubset, ?_⟩ have eq := hG.2 rw [Set.image_image] at eq apply le_antisymm · simp only [leadingTerm_leadingTerm] at eq rw [← eq] apply Ideal.span_mono rintro x ⟨p, hp, rfl⟩ refine ⟨m.leadingTerm p, ?_, leadingTerm_leadingTerm _⟩ apply Ideal.subset_span exact ⟨p, hp, rfl⟩ · apply Ideal.span_mono apply Set.image_mono exact hGsubset lemma IsMinimal.injOn_degree (hG' : hG.IsMinimal) : G.InjOn m.degree := by rw [Set.injOn_iff_pairwise_ne] exact hG'.pairwise.imp fun _ _ ↦ ne_of_not_le lemma IsMinimal.minimal_degree (hG' : hG.IsMinimal) {g} (h : g ∈ G) : Minimal (· ∈ m.degree '' G) (m.degree g) := by by_contra! rw [not_minimal_iff_exists_lt <| Set.mem_image_of_mem _ h] at this obtain ⟨_, hqp, ⟨q, hqG, rfl⟩⟩ := this exact hG'.2 _ h _ hqG (by aesop) hqp.le -- lemma IsMinimal.minimal_degree' (hG' : hG.IsMinimal) {g} (h : g ∈ G) : -- Minimal (· ∈ m.degree '' ((I : Set (MvPolynomial σ R)) \ {0})) (m.degree g) := by -- by_contra! -- rw [not_minimal_iff_exists_lt] at this -- obtain ⟨_, hqp, ⟨q, hqG, rfl⟩⟩ := this -- exact hG'.2 _ h _ hqG (by aesop) hqp.le variable (hG) in lemma IsMinimal.isMinimal_iff_monic_and_minimal_degree_and_injOn_leadingTerm : hG.IsMinimal ↔ (∀ g ∈ G, m.Monic g) ∧ (∀ g ∈ G, Minimal (· ∈ m.degree '' G) (m.degree g)) ∧ G.InjOn m.degree := by constructor · exact fun hG' ↦ ⟨hG'.1, fun _ ↦ hG'.minimal_degree, hG'.injOn_degree⟩ intro h rw [isMinimal_def] refine ⟨h.1, fun p hp q hq hpq ↦ ?_⟩ by_contra! exact h.2.2.ne hp hq hpq <| h.2.1 q hq |>.eq_of_le (Set.mem_image_of_mem _ hp) this lemma IsMinimal.degree_image_eq_setOf_minimal (hG' : hG.IsMinimal) : m.degree '' G = {a | Minimal (· ∈ m.degree '' G) a} := by ext constructor · rintro ⟨p, hpG, rfl⟩ exact hG'.minimal_degree hpG intro h exact h.prop -- lemma IsMinimal.isGroebnerBasis_and_isMinimal_iff_monic_and_minimal_degree_and_injOn_leadingTerm -- {R : Type*} [CommRing R] [Nontrivial R] {G : Set <| MvPolynomial σ R} -- (I : Ideal <| MvPolynomial σ R) (hG : m.IsGroebnerBasis G I) -- (h : ∀ g ∈ G, IsUnit (m.leadingCoeff g)) : -- hG.IsMinimal ↔ -- (∀ g ∈ G, m.Monic g) ∧ -- m.degree '' G = {x | Minimal (· ∈ m.degree '' (I \ {(0 : MvPolynomial σ R)})) x} ∧ -- G.InjOn m.degree := by -- rw [isMinimal_iff_monic_and_minimal_degree_and_injOn_leadingTerm] -- constructor -- · intro hG' -- refine ⟨hG'.1, ?_, hG'.2.2⟩ -- have := hG.ideal_eq_span h -- have := (isGroebnerBasis_iff_subset_and_degree_le_eq_and_degree_le (hG := h) ..).mp hG -- sorry -- · intro hG' -- refine ⟨hG'.1, ?_, hG'.2.2⟩ -- simp_rw [hG'.2.1, Set.mem_setOf, minimal_minimal] -- intro g hg -- exact Set.ext_iff.mp hG'.2.1 (m.degree g) |>.mp <| Set.mem_image_of_mem _ hg lemma IsMinimal.degree_image_eq_of_isMinimal [Nontrivial R] (hG' : hG.IsMinimal) {G₁ : Set (MvPolynomial σ R)} {hG₁ : m.IsGroebnerBasis G₁ I} (hG₁' : hG₁.IsMinimal) : m.degree '' G = m.degree '' G₁ := by rw [hG'.degree_image_eq_setOf_minimal, hG₁'.degree_image_eq_setOf_minimal, Set.ext_iff] simp_rw [Set.mem_setOf, ← ideal_span_monomial_image_eq_ideal_span_monomial_image_iff (R := R), Set.image_image] rw [ ← m.span_leadingTerm_eq_span_monomial (fun _ h ↦ by simp [hG'.monic h |>.leadingCoeff_eq_one]), ← m.span_leadingTerm_eq_span_monomial (fun _ h ↦ by simp [hG₁'.monic h |>.leadingCoeff_eq_one]), ← hG.span_leadingTerm_image, ← hG₁.span_leadingTerm_image ] lemma IsMinimal.isMinimal_of_isMinimal_leadingTerm {hG : m.IsGroebnerBasis (m.leadingTerm '' G) (Ideal.span <| m.leadingTerm '' I)} (hG' : hG.IsMinimal) (hGsubset : G ⊆ I) (hLT : G.InjOn m.degree) : (isGroebnerBasis_of_isMinimal_leadingTerm hG hGsubset).IsMinimal := by rw [IsMinimal.isMinimal_iff_monic_and_minimal_degree_and_injOn_leadingTerm] at ⊢ hG' aesop lemma leadingCoeff_add_of_lt_right {f g : MvPolynomial σ R} (h : m.degree f ≺[m] m.degree g) : m.leadingCoeff (f + g) = m.leadingCoeff g := add_comm f g ▸ leadingCoeff_add_of_lt h -- this requires `R` to be nontrivial, or the reduced GB can be `∅` or `{0}`. lemma IsReduced.unique {R : Type*} [CommRing R] [Nontrivial R] {G₁ G₂ : Set (MvPolynomial σ R)} {I : Ideal (MvPolynomial σ R)} {hG₁ : m.IsGroebnerBasis G₁ I} (hG₁' : hG₁.IsReduced) {hG₂ : m.IsGroebnerBasis G₂ I} (hG₂' : hG₂.IsReduced) : G₁ = G₂ := by classical have : m.leadingTerm '' G₁ = m.leadingTerm '' G₂ := by rw [hG₁'.isMinimal.image_leadingTerm_eq_image_monomial_one, hG₂'.isMinimal.image_leadingTerm_eq_image_monomial_one, ← Set.image_image (monomial · (1 : R)) m.degree, ← Set.image_image (monomial · (1 : R)) m.degree] congr 1 exact hG₁'.isMinimal.degree_image_eq_of_isMinimal hG₂'.isMinimal /- We suppose there exists `p₁ ∈ G₁` and `p₂ ∈ G₂` s.t. `m.degree p₁ = m.degree p₂` and `p₁ ≠ p₂`, and prove contradiction about remainder of `p₁ - p₂` that it is unique but can be both `0` and `p₁ - p₂`. This contradiction is easy to obtain in informal proof. -/ ext p₁ wlog hp₁ : p₁ ∈ G₁ ∧ p₁ ∉ G₂ generalizing G₁ G₂ with h · specialize h hG₂' hG₁' this.symm aesop obtain ⟨hp₁, hp₂'⟩ := hp₁ exfalso obtain ⟨p₂, ⟨hp₂, hp₁₂⟩⟩ := Set.mem_image .. |>.mp <| this ▸ (Set.mem_image_of_mem _ hp₁) rw [isReduced_def] at hG₁' hG₂' simp [leadingTerm, monomial_eq_monomial_iff, (hG₂'.1 p₂ hp₂).ne_zero] at hp₁₂ suffices rem_self : m.IsRemainder (p₁ - p₂) G₁ (p₁ - p₂) by have := I.sub_mem (Set.mem_of_subset_of_mem hG₁.1 hp₁) (Set.mem_of_subset_of_mem hG₂.1 hp₂) rw [← remainder_eq_zero_iff_mem_ideal hG₁ rem_self, sub_eq_zero] at this exact hp₂' <| this ▸ hp₂ rw [IsRemainder.self_iff] rintro a ha q hq - replace ha' := Finset.mem_union.mp <| Finset.mem_of_subset (support_sub ..) ha by_cases hqp : m.degree q = m.degree p₁ · apply not_imp_not.mpr (m.toSyn_monotone (a := m.degree q) (b := a)) push_neg apply lt_of_le_of_ne · rcases ha' with ha | ha · exact hqp ▸ m.le_degree_of_mem_support ha · exact hqp ▸ hp₁₂.1 ▸ m.le_degree_of_mem_support ha contrapose! ha rw [m.toSyn.apply_eq_iff_eq] at ha simp_rw [leadingCoeff, hp₁₂.1, ← hqp] at hp₁₂ simp [ha, hp₁₂.2] have hqnep : q ≠ p₁ := by contrapose! hqp; simp [hqp] rcases ha' with ha | ha · exact hG₁'.2 _ hp₁ _ ha _ hq hqnep obtain ⟨q', hq'⟩ := Set.mem_image .. |>.mp <| this ▸ (Set.mem_image_of_mem _ hq) simp [leadingTerm, monomial_eq_monomial_iff, (hG₁'.1 q hq).ne_zero] at hq' rw [← hq'.2.1] apply hG₂'.2 _ hp₂ _ ha _ hq'.1 contrapose! hqp simp [← hq'.2.1, ← hp₁₂.1, hqp] lemma MonomialOrder.degree_le_mul_left {σ R : Type*} [CommRing R] [IsDomain R] (m : MonomialOrder σ) (p q : MvPolynomial σ R) (hq : q ≠ 0) : m.degree p ≤ m.degree (p * q) := by by_cases hp : p = 0 · rw [hp] simp · rw [m.degree_mul hp hq] exact le_self_add lemma IsMinimal.withBotDegree_eq_of_isRemainder {G : Set (MvPolynomial σ R)} {I : Ideal (MvPolynomial σ R)} {hG : m.IsGroebnerBasis G I} (hG' : hG.IsMinimal) {g} (hg : g ∈ G) {r : MvPolynomial σ R} (hr : m.IsRemainder g (G \ {g}) r) : m.withBotDegree r = m.withBotDegree g := by rw [eq_comm] by_contra! h obtain ⟨b, ⟨hbG, hbg⟩, hb⟩ := hr.exists_withBotDegree_le_withBotDegree h rw [IsMinimal.isMinimal_def] at hG' rw [m.withBotDegree_le_withBotDegree_iff'] at hb exact hG'.2 hbG hg hbg hb.1 lemma IsMinimal.degree_eq_of_isRemainder {G : Set (MvPolynomial σ R)} {I : Ideal (MvPolynomial σ R)} {hG : m.IsGroebnerBasis G I} (hG' : hG.IsMinimal) {g} (hg : g ∈ G) {r : MvPolynomial σ R} (hr : m.IsRemainder g (G \ {g}) r) : m.degree r = m.degree g := m.withBotDegree_eq_withBotDegree_iff .. |>.mp (hG'.withBotDegree_eq_of_isRemainder hg hr) |>.1 lemma IsMinimal.leadingTerm_eq_of_isRemainder {R} [CommRing R] {G : Set (MvPolynomial σ R)} {I : Ideal (MvPolynomial σ R)} {hG : m.IsGroebnerBasis G I} (hG' : hG.IsMinimal) {g} (hg : g ∈ G) (r : MvPolynomial σ R) (hr : m.IsRemainder g (G \ {g}) r) : m.leadingTerm r = m.leadingTerm g := hr.withBotDegree_eq_withBotDegree_iff_leadingTerm_eq_leadingTerm.mp <| hG'.withBotDegree_eq_of_isRemainder hg hr lemma IsMinimal.isGroebnerBasis_image_isRemainder {R} [CommRing R] {G : Set (MvPolynomial σ R)} {I : Ideal (MvPolynomial σ R)} {hG : m.IsGroebnerBasis G I} (hG' : hG.IsMinimal) (f : G → MvPolynomial σ R) (hf : ∀ g, m.IsRemainder g.val (G \ {g.val}) (f g)) : m.IsGroebnerBasis (Set.range f) I := by rw [IsMinimal] at hG' classical rcases hG with ⟨hG1, hG2⟩ refine ⟨?_, ?_⟩ · rintro _ ⟨g, rfl⟩ have := (hf g).1 obtain ⟨coef, h_eq, -⟩ := this have : f g = ↑g - (Finsupp.linearCombination (MvPolynomial σ R) fun b ↦ ↑b) coef := by simp_rw [h_eq] -- todo: why `rw [add_sub_cancel_left]` doesn't work? exact (add_sub_cancel_left ..).symm simp [this] apply Ideal.sub_mem · apply hG1 g.2 · dsimp apply Submodule.sum_mem intro c _ apply Ideal.mul_mem_left apply hG1 exact c.2.1 · rw [hG2] apply congr_arg Ideal.span ext x have lt_eq : ∀ (g : G), m.leadingTerm (f g) = m.leadingTerm g.val := by intro g by_contra h_ne let diff := ↑g - f g have fg_eq : f g = ↑g - diff := by exact Eq.symm (sub_sub_self (↑g) (f g)) have h_deg_diff_lt : m.toSyn (m.degree diff) < m.toSyn (m.degree g.val) := by have := isRemainder_iff_degree (m := m) g (G \ {↑g}) (f g) <| by simp rintro b hbG - simp [(hG'.1 _ hbG).leadingCoeff_eq_one] obtain ⟨c, h_eq, b_deg⟩ := (this.mp <| hf g).left have h_diff_eq : diff = (Finsupp.linearCombination (MvPolynomial σ R) fun b ↦ ↑b) c := by exact sub_eq_iff_eq_add.mpr h_eq have h_all_lt : ∀ b ∈ c.support, m.toSyn (m.degree (b.val * c b)) < m.toSyn (m.degree g.val) := by intro b hb have h_le := b_deg b apply lt_of_le_of_ne h_le intro h_eq_deg have h_div : m.degree b.val ≤ m.degree g.val := by have h_eq_raw : m.degree (b.val * c b) = m.degree g.val := by exact m.toSyn.injective h_eq_deg rw [← h_eq_raw] have cbn0 : c b ≠ 0 := by exact Finsupp.mem_support_iff.mp hb have h_b_monic : m.Monic b.val := hG'.1 b.val b.2.1 have lc1 : m.leadingCoeff b.val = 1 := by rw [Monic] at h_b_monic exact h_b_monic have lc2 : m.leadingCoeff (c b) ≠ 0 := by rw [leadingCoeff] simp [cbn0] have lc : m.leadingCoeff b.val * m.leadingCoeff (c b) ≠ 0 := by simp [lc1, lc2] have : m.degree (b.val * c b) = m.degree b.val + m.degree (c b) := by exact degree_mul_of_mul_leadingCoeff_ne_zero lc rw [this] simp exact hG'.2 g.val g.2 b.val b.2.1 b.2.2 h_div rw [h_diff_eq] apply lt_of_le_of_lt m.degree_sum_le have : c ≠ 0 := by intro h_c_zero rw [h_c_zero, map_zero] at h_diff_eq rw [h_diff_eq, sub_zero] at fg_eq rw [fg_eq] at h_ne exact h_ne rfl simp [mul_comm (c _)] rwa [← Finset.sup'_eq_sup, Finset.sup'_lt_iff] exact Finsupp.support_nonempty_iff.mpr this have h_degree : m.degree (f g) = m.degree g.val := by rw [fg_eq] rw [sub_eq_neg_add] apply m.degree_add_eq_right_of_lt rw [m.degree_neg] exact h_deg_diff_lt apply h_ne rw [leadingTerm] rw [leadingTerm] rw [h_degree] have : m.leadingCoeff (f g) = m.leadingCoeff g.val := by rw [fg_eq] rw [sub_eq_add_neg] have : m.degree (-diff) = m.degree diff := by rw [m.degree_neg] rw [←this] at h_deg_diff_lt exact leadingCoeff_add_of_lt h_deg_diff_lt rw [this] constructor · simp only [Set.mem_image, Set.mem_range] intro h₁ rcases h₁ with ⟨x₁, hx₁⟩ obtain ⟨g_val, hg_in_G, rfl⟩ := hx₁ use f ⟨x₁, g_val⟩ constructor · use ⟨x₁, g_val⟩ · by_contra h_neq exact h_neq (lt_eq ⟨x₁, g_val⟩) · rintro ⟨_, ⟨g, rfl⟩, rfl⟩ use g.val, g.2 rw [lt_eq g] lemma IsReduced.isReduced_image_isRemainder_of_IsMinimal {R} [CommRing R] {G : Set (MvPolynomial σ R)} {I : Ideal (MvPolynomial σ R)} {hG : m.IsGroebnerBasis G I} (hG' : hG.IsMinimal) (f : G → MvPolynomial σ R) (hf : ∀ g, m.IsRemainder g.val (G \ {g.val}) (f g)) : hG'.isGroebnerBasis_image_isRemainder f hf |>.IsReduced := by rw [isReduced_def] have lt_eq : ∀ (g : G), m.leadingTerm (f g) = m.leadingTerm g.val := by intro g by_contra h_ne let diff := ↑g - f g have fg_eq : f g = ↑g - diff := by exact Eq.symm (sub_sub_self (↑g) (f g)) have h_deg_diff_lt : m.toSyn (m.degree diff) < m.toSyn (m.degree g.val) := by have := isRemainder_iff_degree (m := m) g (G \ {↑g}) (f g) <| by simp rintro b hbG - simp [(hG'.1 _ hbG).leadingCoeff_eq_one] obtain ⟨c, h_eq, b_deg⟩ := (this.mp <| hf g).left have h_diff_eq : diff = (Finsupp.linearCombination (MvPolynomial σ R) fun b ↦ ↑b) c := by exact sub_eq_iff_eq_add.mpr h_eq have h_all_lt : ∀ b ∈ c.support, m.toSyn (m.degree (b.val * c b)) < m.toSyn (m.degree g.val) := by intro b hb have h_le := b_deg b apply lt_of_le_of_ne h_le intro h_eq_deg have h_div : m.degree b.val ≤ m.degree g.val := by have h_eq_raw : m.degree (b.val * c b) = m.degree g.val := by exact m.toSyn.injective h_eq_deg rw [← h_eq_raw] have cbn0 : c b ≠ 0 := by exact Finsupp.mem_support_iff.mp hb have h_b_monic : m.Monic b.val := hG'.1 b.val b.2.1 have lc1 : m.leadingCoeff b.val = 1 := by rw [Monic] at h_b_monic exact h_b_monic have lc2 : m.leadingCoeff (c b) ≠ 0 := by rw [leadingCoeff] simp [cbn0] have lc : m.leadingCoeff b.val * m.leadingCoeff (c b) ≠ 0 := by simp [lc1, lc2] have : m.degree (b.val * c b) = m.degree b.val + m.degree (c b) := by exact degree_mul_of_mul_leadingCoeff_ne_zero lc rw [this] simp exact hG'.2 g.val g.2 b.val b.2.1 b.2.2 h_div rw [h_diff_eq] apply lt_of_le_of_lt m.degree_sum_le have : c ≠ 0 := by intro h_c_zero rw [h_c_zero, map_zero] at h_diff_eq rw [h_diff_eq, sub_zero] at fg_eq rw [fg_eq] at h_ne exact h_ne rfl simp [mul_comm (c _)] rwa [← Finset.sup'_eq_sup, Finset.sup'_lt_iff] exact Finsupp.support_nonempty_iff.mpr this have h_degree : m.degree (f g) = m.degree g.val := by rw [fg_eq] rw [sub_eq_neg_add] apply m.degree_add_eq_right_of_lt rw [m.degree_neg] exact h_deg_diff_lt apply h_ne rw [leadingTerm] rw [leadingTerm] rw [h_degree] have : m.leadingCoeff (f g) = m.leadingCoeff g.val := by rw [fg_eq] rw [sub_eq_add_neg] have : m.degree (-diff) = m.degree diff := by rw [m.degree_neg] rw [←this] at h_deg_diff_lt exact leadingCoeff_add_of_lt h_deg_diff_lt rw [this] constructor · intro p hp obtain ⟨g, rfl⟩ := hp have h : m.leadingTerm (f g) = m.leadingTerm ↑g := by exact lt_eq g unfold Monic rw [← m.leadingCoeff_leadingTerm (f g)] rw [h] have g_monic : m.Monic g.val := by exact hG'.1 g g.2 unfold Monic at g_monic rw [m.leadingCoeff_leadingTerm] exact g_monic · intro p hp q hq r hr neq obtain ⟨g, rfl⟩ := hp obtain ⟨g', rfl⟩ := hr · have h_ne : g' ≠ g := by rintro rfl exact neq rfl have h : m.leadingTerm (f g') = m.leadingTerm ↑g' := by exact lt_eq g' have deg_r_eq_g' : m.degree (f g') = m.degree g'.val := by simp [← degree_leadingTerm, h] rw [deg_r_eq_g'] apply (hf g).2 q hq g' · rw [Set.mem_diff, Set.mem_singleton_iff] constructor · exact g'.2 · exact Subtype.coe_ne_coe.mpr h_ne · intro h_val_eq have g'_monic : m.Monic g'.val := hG'.1 g' g'.2 rw [h_val_eq] at g'_monic simp_rw [Monic] at g'_monic simp at g'_monic have h_fg_zero : f g = 0 := by apply MvPolynomial.ext intro m rw [← mul_one (coeff m (f g))] rw [← g'_monic, mul_zero] rw [coeff_zero] rw [h_fg_zero] at hq rw [MvPolynomial.support_zero] at hq exact (List.mem_nil_iff q).mp hq lemma IsReduced.exists_of_isGroebnerBasis {R} [CommRing R] {G : Set (MvPolynomial σ R)} {I : Ideal (MvPolynomial σ R)} (hG : m.IsGroebnerBasis G I) (hG' : ∀ g ∈ G, IsUnit (m.leadingCoeff g)) : ∃ (B : Set (MvPolynomial σ R)) (h : m.IsGroebnerBasis B I), h.IsReduced := by classical wlog! nontrivial : Nontrivial R · by_cases! hG : G = ∅ · simp · use {0} simp -- monicized basis let monicized := Set.range fun (g : G) ↦ (hG' _ g.prop).unit⁻¹ • g.val have monicized_isGB : m.IsGroebnerBasis monicized I := hG.inv hG' have monicized_monic : ∀ g ∈ monicized, m.Monic g := by unfold monicized simp? says simp only [Set.mem_range, Subtype.exists, forall_exists_index] rintro _ _ hmemG rfl simp [Monic, Units.smul_def, smul_eq_C_mul] convert m.leadingCoeff_mul_of_right_mem_nonZeroDivisors _ _ · simp [m.leadingCoeff_C] · simp exact (hG' _ hmemG).mem_nonZeroDivisors -- minimalized basis obtain ⟨minimal, minimal_subset_monic, injOn_degree, degree_minimal_eq⟩ := Set.SurjOn.exists_subset_injOn_image_eq (s := monicized) (t := {x | Minimal (· ∈ (m.degree '' monicized)) x}) (f := m.degree) (fun _ ↦ Minimal.prop) have minimal_isGB := monicized_isGB.isGroebnerBasis_minimal (subset_trans minimal_subset_monic monicized_isGB.subset) (by simp [monicized_monic · <| minimal_subset_monic ·]) <| subset_of_eq <| by rw [degree_minimal_eq, sdiff_eq_left.mpr] rw [Set.disjoint_singleton_right] by_contra! h simpa [Monic] using monicized_monic _ h have minimal_isMinimal : IsMinimal (G := minimal) (I := I) _ := IsMinimal.isMinimal_iff_monic_and_minimal_degree_and_injOn_leadingTerm minimal_isGB |>.mpr ⟨(monicized_monic · <| minimal_subset_monic ·), ?min, injOn_degree⟩ case min => intro g h simpa only [degree_minimal_eq, Set.mem_setOf, minimal_minimal] using Set.ext_iff.mp degree_minimal_eq (m.degree g) |>.mp (Set.mem_image_of_mem _ h) -- reduced basis have reduced := IsReduced.isReduced_image_isRemainder_of_IsMinimal minimal_isMinimal (fun g ↦ Exists.choose <| exists_isRemainder (m := m) g.val (B := minimal \ {g.val}) (hB := by simp_intro .. [minimal_isMinimal.1])) (hf := by simp [Exists.choose_spec]) exact ⟨_, _, reduced⟩ lemma IsReduced.exists_of_isGroebnerBasis₀ {R} [CommRing R] {G : Set (MvPolynomial σ R)} {I : Ideal (MvPolynomial σ R)} (hG : m.IsGroebnerBasis G I) (hG' : ∀ g ∈ G, IsUnit (m.leadingCoeff g) ∨ g = 0) : ∃ (B : Set (MvPolynomial σ R)) (h : m.IsGroebnerBasis B I), h.IsReduced := by apply exists_of_isGroebnerBasis (isGroebnerBasis_sdiff_singleton_zero .. |>.mpr hG) simp_intro .. [or_iff_not_imp_right.mp (hG' _ _)] lemma IsReduced.exists_of_isGroebnerBasis' {k} [Field k] {I : Ideal (MvPolynomial σ k)} : ∃ (B : Set (MvPolynomial σ k)) (h : m.IsGroebnerBasis B I), h.IsReduced := IsReduced.exists_of_isGroebnerBasis₀ (isGroebnerBasis_self (m := m) I) (by simp [em']) theorem IsReduced.uniqueExists_of_isGroebnerBasis {R} [Nontrivial R] [CommRing R] {G : Set (MvPolynomial σ R)} {I : Ideal (MvPolynomial σ R)} (hG : m.IsGroebnerBasis G I) (hG' : ∀ g ∈ G, IsUnit (m.leadingCoeff g)) : ∃! (B : Set (MvPolynomial σ R)), ∃ (h : m.IsGroebnerBasis B I), h.IsReduced := by obtain ⟨B, h, h'⟩ := IsReduced.exists_of_isGroebnerBasis hG hG' refine ⟨B, ⟨h, h'⟩, ?_⟩ intro s simp only [forall_exists_index] intro hs hs' exact hs'.unique h' theorem IsReduced.uniqueExists_of_isGroebnerBasis₀ {R} [Nontrivial R] [CommRing R] {G : Set (MvPolynomial σ R)} {I : Ideal (MvPolynomial σ R)} (hG : m.IsGroebnerBasis G I) (hG' : ∀ g ∈ G, IsUnit (m.leadingCoeff g) ∨ g = 0) : ∃! (B : Set (MvPolynomial σ R)), ∃ (h : m.IsGroebnerBasis B I), h.IsReduced := by apply IsReduced.uniqueExists_of_isGroebnerBasis ((isGroebnerBasis_sdiff_singleton_zero ..).mpr hG) simp_intro .. [or_iff_not_imp_right.mp (hG' _ _)] theorem IsReduced.uniqueExists {k} [Field k] (I : Ideal (MvPolynomial σ k)) : ∃! (B : Set (MvPolynomial σ k)), ∃ (h : m.IsGroebnerBasis B I), h.IsReduced := IsReduced.uniqueExists_of_isGroebnerBasis₀ (isGroebnerBasis_self (m := m) I) (by simp [em']) -- lemma _root_.MonomialOrder.Embedding.isReduced_iff_isReduced_rename {σ' σ} -- {m' : MonomialOrder σ'} {m : MonomialOrder σ} -- (e : Embedding m' m) (p : MvPolynomial σ' R) {G : Set (MvPolynomial σ' R)} -- (I : MvPolynomial σ' R) (hG : IsGroebnerBasis) : -- m'.IsRemainder p B r ↔ -- m.IsRemainder (p.rename e) (rename e '' B) (r.rename e) := -- ⟨e.isRemainder_rename_of_isRemainder, -- lemma -- rcases Finset.mem_union.mp <| support_add (p := p) (q := q) ha with ha' | ha' -- · left -- exists ha' -- rw [leadingTerm, leadingTerm] at h -- rw [m.le_degree] -- sorry -- lemma minimalFor_iff_minimal {ι α} (P : ι → Prop) (f : ι → α) (i : ι) [LE α] : -- MinimalFor P f i ↔ P i ∧ Minimal P (f i) -- todo: generalize to ring? lemma isGroebnerBasis_minimalFor {k} [Field k] (I : Ideal (MvPolynomial σ k)) : m.IsGroebnerBasis ({g | m.Monic g ∧ MinimalFor (fun p ↦ p ∈ (I : Set (MvPolynomial σ k)) \ {0}) (m.degree ·) g ∧ ∀ p ∈ I, p ≠ 0 → m.degree p ≠ m.degree g → ∀ a ∈ g.support, ¬ m.degree p ≤ a}) I := by rw [IsGroebnerBasis.isGroebnerBasis_iff_minimal] split_ands · intro p hp simp at hp exact hp.2.1.prop.1 intro a ha simp [-MvPolynomial.mem_support_iff] at ⊢ ha obtain ⟨p, hp, rfl⟩ := ha.prop obtain ⟨r, hr⟩ := IsRemainder.exists_isRemainder' (m := m) ((I : Set (MvPolynomial σ k)) \ {q | m.degree q = m.degree p}) p use (m.leadingCoeff r)⁻¹ • r have hr0 : r ≠ 0 := by by_contra! rfl rw [← isRemainder_sdiff_singleton_zero_iff_isRemainder] at hr have ⟨q, hq⟩ := IsRemainder.exists_degree_le_degree_of_zero hp.2 hr simp at hq obtain hqp := le_antisymm (ha.le_of_le ⟨q, ⟨hq.1.1.1, hq.1.2⟩, rfl⟩ hq.2) hq.2 simp [hqp] at hq have hrp : m.degree r = m.degree p := by by_contra! rw [← isRemainder_sdiff_singleton_zero_iff_isRemainder] at hr have := hr.exists_withBotDegree_le_withBotDegree (by simpa [m.withBotDegree_eq_withBotDegree_iff, hr0, hp] using this.symm) simp [m.withBotDegree_le_withBotDegree_iff'] at this obtain ⟨q, hq⟩ := this simp [le_antisymm hq.2.1 <| ha.le_of_le ⟨q, ⟨hq.1.1.1, hq.1.2⟩, rfl⟩ hq.2.1] at hq split_ands · -- todo `m.leadingCoeff_smul` rw [Monic, smul_eq_C_mul, m.leadingCoeff_mul', m.leadingCoeff_C, inv_mul_cancel₀ <| leadingCoeff_eq_zero_iff.not.mpr hr0] · simp [smul_eq_C_mul] exact Ideal.mul_mem_left _ _ (hr.mem_ideal_iff (I := I) Set.diff_subset |>.mpr hp.1) · simp [hr0] · simp intro q hqI hq rw [smul_eq_C_mul, m.degree_mul _ hr0, m.degree_C, zero_add, hrp] · exact ha.le_of_le ⟨q, ⟨hqI, hq⟩, rfl⟩ simp [hr0] · intro q hq hq0 rw [m.degree_smul_of_mem_nonZeroDivisors (by simp [hr0]), MvPolynomial.support_smul_eq (by simp [hr0]), hrp] intro hqr a ha apply hr.2 a ha _ (by simp [hq, hqr]) hq0 · simp [hr0] rw [m.degree_smul_of_mem_nonZeroDivisors (by simp [hr0]), hrp] lemma IsReduced.isReduced_minimalFor {k} [Field k] (I : Ideal (MvPolynomial σ k)) : (isGroebnerBasis_minimalFor (m := m) I).IsReduced := by classical rw [IsReduced.isReduced_def] split_ands · exact fun _ ↦ And.left intro p hp a hap q hq hqp simp [-mem_support_iff] at hqp hq hp apply hp.2.2 _ hq.2.1.prop.1 hq.2.1.prop.2 _ _ hap by_contra! hqp' have : m.leadingTerm q = m.leadingTerm p := by simp [m.leadingTerm_eq_leadingTerm_iff, hq.1, hp.1, hqp'] apply support_sub_of_leadingTerm_eq_leadingTerm at this have qsubp : q - p ≠ 0 := by simp [sub_eq_zero, hqp] rcases this (m.degree (q - p)) <| m.degree_mem_support qsubp with h | h · apply not_not_intro <| le_refl (m.degree (q - p)) apply hq.2.2 (q - p) (Ideal.sub_mem I hq.2.1.prop.1 hp.2.1.prop.1) qsubp _ _ h.1 rw [← m.toSyn.apply_eq_iff_eq] exact ne_of_lt h.2 · apply not_not_intro <| le_refl (m.degree (q - p)) apply hp.2.2 (q - p) (Ideal.sub_mem I hq.2.1.prop.1 hp.2.1.prop.1) qsubp _ _ h.1 rw [← m.toSyn.apply_eq_iff_eq] exact ne_of_lt h.2 theorem IsReduced.isReduced_iff_minimalFor {k} [Field k] (G : Set (MvPolynomial σ k)) (I : Ideal (MvPolynomial σ k)) : (∃ h : m.IsGroebnerBasis G I, h.IsReduced) ↔ (∀ g, g ∈ G ↔ m.Monic g ∧ MinimalFor (fun p ↦ p ∈ (I : Set (MvPolynomial σ k)) \ {0}) (m.degree ·) g ∧ ∀ p ∈ I, p ≠ 0 → m.degree p ≠ m.degree g → ∀ a ∈ g.support, ¬ m.degree p ≤ a) := by simp (singlePass := true) only [ ← Set.mem_setOf (p := fun g ↦ m.Monic g ∧ MinimalFor (fun p ↦ p ∈ (I : Set (MvPolynomial σ k)) \ {0}) (m.degree ·) g ∧ ∀ p ∈ I, p ≠ 0 → m.degree p ≠ m.degree g → ∀ a ∈ g.support, ¬ m.degree p ≤ a), ← Set.ext_iff ] have hrgb' := IsReduced.isReduced_minimalFor (m := m) I constructor · intro ⟨hgb, hrgb⟩ exact IsReduced.unique hrgb hrgb' · rintro rfl exact ⟨_, hrgb'⟩ -- wlog h : ∃ (h : m.IsGroebnerBasis G I), h.IsReduced generalizing G -- · simp only [h] -- obtain ⟨G', hG', hG''⟩ := IsReduced.uniqueExists (m := m) I -- replace := this G' hG' |>.mp hG' -- simp (singlePass := true) only [← Set.mem_setOf (p := fun g ↦ m.Monic g ∧ -- MinimalFor (fun p ↦ p ∈ I) (m.degree ·) g ∧ -- ∀ p ∈ I, p ≠ 0 → m.degree p ≠ m.degree g → ∀ a ∈ g.support, ¬ m.degree p ≤ a)] at ⊢ this -- simp only [← this, ← Set.ext_iff, false_iff] -- contrapose! h with rfl -- exact hG' -- simp only [h, true_iff] -- intro g -- obtain ⟨hG, hG'⟩ := h -- wlog hg : g ∈ G generalizing G hG hG' -- · obtain ⟨G', hG', hG''⟩ := IsReduced.uniqueExists (m := m) I -- specialize this G' hG'.choose hG'.choose_spec -- simp (singlePass := true) only [← Set.mem_setOf (p := fun g ↦ m.Monic g ∧ -- MinimalFor (fun p ↦ p ∈ I) (m.degree ·) g ∧ -- ∀ p ∈ I, p ≠ 0 → m.degree p ≠ m.degree g → ∀ a ∈ g.support, ¬ m.degree p ≤ a)] at ⊢ this -- rw [← this] -- sorry -- sorry -- constructor -- · intro hg -- exists hG'.1 g hg -- rw [MinimalFor] -- sorry -- sorry -- constructor -- · intro ⟨hGB, hR⟩ g -- constructor -- · intro h -- refine ⟨hR.1 _ h, ?_, ?_⟩ -- sorry -- rw [IsGroebnerBasis.isGroebnerBasis_iff_subset_and_degree_le_eq_and_degree_le'] at hGB -- sorry -- theorem IsReduced.def_minimal' : (∃ h : m.IsGroebnerBasis G I, h.IsReduced) ↔ -- ((∀ g ∈ G, m.Monic g) ∧ -- m.degree '' G = -- { x | Minimal (· ∈ m.degree '' ((I : Set (MvPolynomial σ R)) \ {0})) x}) := sorry lemma _root_.Filter.union_mem_of_mem {α} {a b : Set α} {f : Filter α} (ha : a ∈ f) (hb : b ∈ f) : a ∪ b ∈ f := by convert Filter.union_mem_sup ha hb simp -- lemma _root_.Filter.inter_mem_of_mem {α} {a b : Set α} {f : Filter α} (ha : a ∈ f) (hb : b ∈ f) : -- a ∩ b ∈ f := by -- convert Filter.inter_mem ha hb -- simp lemma _root_.Filter.biUnion_mem_of_mem {α ι} {f : Filter α} {s : Set ι} {t : ι → Set α} (hs : s.Nonempty) (hs' : s.Finite) (h : ∀ i ∈ s, t i ∈ f) : ⋃ i ∈ s, t i ∈ f := by classical rw [← hs'.coe_toFinset] at ⊢ h hs generalize hs'.toFinset = s at ⊢ h hs rw [Finset.coe_nonempty] at hs induction s using Finset.induction_on with | empty => simp at hs | insert a' s' _ h' => by_cases! hs' : s' = ∅ · subst hs' simpa using h simp at h simpa using Filter.union_mem_of_mem h.1 (h' h.2 hs') lemma _root_.Filter.sUnion_mem_of_mem {α} {f : Filter α} {s : Set (Set α)} (hs : s.Nonempty) (hs' : s.Finite) (h : ∀ a ∈ s, a ∈ f) : Set.sUnion s ∈ f := by classical rw [← hs'.coe_toFinset] at ⊢ h hs generalize hs'.toFinset = s at ⊢ h hs rw [Finset.coe_nonempty] at hs induction s using Finset.induction_on with | empty => simp at hs | insert a' s' _ h' => by_cases! hs' : s' = ∅ · subst hs' simpa using h simp at h simp [Filter.union_mem_of_mem h.1 (h' h.2 hs')] -- todo: the wraning is a bug? lemma _root_.Filter.iUnion_mem_of_mem {α ι} {f : Filter α} [Fintype ι] [nomempty : Nonempty ι] {s : ι → Set α} (h : ∀ i : ι, s i ∈ f) : Set.iUnion s ∈ f := by classical have finite := Set.univ_finite_iff_nonempty_fintype (α := ι) |>.mpr <| .intro inferInstance rw [← Set.sUnion_range] apply f.sUnion_mem_of_mem · simp [Set.range_nonempty] · simp [Set.finite_range] simp [h] -- lemma _root_.Filter.iUnion_mem_of_mem {α ι} {f : Filter α} [Fintype ι] [nomempty : Nonempty ι] -- {s : ι → Set α} (h : ∀ i : ι, s i ∈ f) : Set.iUnion s ∈ f := by -- classical -- revert nomempty s h -- apply Fintype.induction_subsingleton_or_nontrivial ι -- (P := fun ι ↦ ∀ [inst : Nonempty ι] {s : ι → Set α}, (∀ (i : ι), s i ∈ f) → Set.iUnion s ∈ f) -- · intro ι _ _ nonempty s h -- -- todo: some related lemmas -- rw [show s = fun _ ↦ s (Classical.choice nonempty) by ext; congr!, Set.iUnion_const] -- exact h _ -- · intro ι' _ nontrivial ι nonempty f h -- have := Classical.choice nonempty -- specialize l -- simp -- sorry -- lemma IsReduced. theorem IsReduced.subset_limsup {k} [Field k] {I : Ideal (MvPolynomial σ k)} {α} {σ' : α → Type*} {m' : (a : α) → MonomialOrder (σ' a)} {f : Filter α} {e : (a : α) → (m' a).Embedding m} (hI : Set.univ = f.liminf (fun x ↦ Set.range (e x))) {G' : (a : α) → Set (MvPolynomial (σ' a) k)} (hG' : ∀ a, (m' a).IsGroebnerBasis (G' a) (I.comap <| rename (e a))) (hG'' : ∀ a, (hG' a).IsReduced) {G : Set (MvPolynomial σ k)} {hG₀ : m.IsGroebnerBasis G I} (hG : hG₀.IsReduced) : G ⊆ f.liminf fun a ↦ rename (e a) '' G' a := by classical have hG''' a : ∃ h : IsGroebnerBasis (G' a) (Ideal.comap (rename ⇑(e a)) I), h.IsReduced := ⟨_, hG'' a⟩ simp_rw [isReduced_iff_minimalFor] at ⊢ hG''' intro g simp [Filter.liminf_eq_iSup_iInf, eq_comm (a := Set.univ), Set.iUnion_eq_univ_iff, -MvPolynomial.mem_support_iff] at ⊢ hI intro h rw [IsReduced.isReduced_iff_minimalFor .. |>.mp ⟨_, hG⟩] at h refine ⟨Set.sInter (g.vars.image (hI · |>.choose)), ?_, ?_⟩ · simp intro a ha obtain ⟨h, -⟩ := (hI _).choose_spec exact h intro a ha obtain ⟨g' , rfl⟩ := MvPolynomial.exists_rename_eq_of_vars_subset_range g _ (e a).coe_injective <| by intro i hi simp at ha specialize ha i hi simpa using (hI i).choose_spec.2 _ ha refine ⟨g', ?_, rfl⟩ rw [hG''' a g'] simp [-MvPolynomial.mem_support_iff] at h ⊢ split_ands · simpa using h.1 · simpa using h.2.1.1.1 · simpa using h.2.1.1.2 · intro p hp simpa using @h.2.1.2 ((rename ⇑(e a)) p) (by simpa using hp) intro p hp have := h.2.2 _ hp nth_rw 3 [(e a).degree_rename] at this simpa [-MvPolynomial.mem_support_iff, support_rename_of_injective (e a).coe_injective, Finsupp.mapDomain_le_mapDomain_iff_le (e a).coe_injective] using this theorem IsReduced.isReduced_liminf {k} [Field k] {I : Ideal (MvPolynomial σ k)} {α} {σ' : α → Type*} {m' : (a : α) → MonomialOrder (σ' a)} {f : Filter α} [f.NeBot] {e : (a : α) → (m' a).Embedding m} (hI : Set.univ = f.liminf (fun x ↦ Set.range (e x))) {G' : (a : α) → Set (MvPolynomial (σ' a) k)} (hG' : ∀ a, (m' a).IsGroebnerBasis (G' a) (I.comap <| rename (e a))) (hG'' : ∀ a, (hG' a).IsReduced) : ∃ h : m.IsGroebnerBasis (f.liminf fun a ↦ rename (e a) '' G' a) I, h.IsReduced := by classical refine ⟨IsGroebnerBasis.of_subset (IsReduced.uniqueExists I).choose_spec.1.choose ?_ ?_, ?_⟩ · apply IsReduced.subset_limsup hI hG' hG'' exact (IsReduced.uniqueExists I).choose_spec.1.choose_spec · intro g simp [Filter.liminf_eq_iSup_iInf] intro s hs hs' obtain ⟨a, ha⟩ := Filter.NeBot.nonempty_of_mem ‹_› hs obtain ⟨g', hg', rfl⟩ := hs' a ha simpa using (hG' a).subset hg' simp_rw [isReduced_def, ← forall_and] simp [Filter.liminf_eq_iSup_iInf, eq_comm (a := Set.univ), Set.iUnion_eq_univ_iff, -MvPolynomial.mem_support_iff] at ⊢ hI intro g s hs hs' constructor · obtain ⟨a, ha⟩ := Filter.NeBot.nonempty_of_mem ‹_› hs obtain ⟨g', hg', hg'eq⟩ := hs' a ha specialize hG'' a simpa [← hg'eq] using hG''.1 g' hg' intro b hb p t ht ht' pneg obtain ⟨u, hu⟩ := Filter.NeBot.nonempty_of_mem ‹_› (Filter.inter_mem hs ht) have := Set.mem_of_mem_inter_left hu obtain ⟨g', hg', rfl⟩ := hs' u (Set.mem_of_mem_inter_left hu) obtain ⟨p', hp', rfl⟩ := ht' u (Set.mem_of_mem_inter_right hu) specialize hG'' u rw [isReduced_def] at hG'' rw [support_rename_of_injective (e u).coe_injective, Finset.mem_image] at hb obtain ⟨b', hb', rfl⟩ := hb simpa [(e u).degree_rename, Finsupp.mapDomain_le_mapDomain_iff_le (e u).coe_injective] using hG''.2 g' hg' b' hb' p' hp' <| by simpa [rename_injective _ (e u).coe_injective |>.eq_iff] using pneg theorem IsReduced.isReduced_liminf_nat {k} [Field k] {I : Ideal (MvPolynomial σ k)} {init : Nat} {e : ℕ ≃ σ} {G' : (n : ℕ) → Set (MvPolynomial (Fin (n + init)) k)} (hG' : ∀ n, (m.ofInjective <| e.injective.comp Fin.val_injective).IsGroebnerBasis (G' n) (I.comap <| rename (e ∘ @Fin.val (n + init)))) (hG'' : ∀ n, (hG' n).IsReduced) : ∃ h : m.IsGroebnerBasis (Filter.cofinite.liminf fun i ↦ rename (e ∘ @Fin.val (i + init)) '' G' i) I, h.IsReduced := by convert IsReduced.isReduced_liminf (f := Filter.cofinite) ?_ hG' hG'' (e := (Embedding.ofInjective m <| e.injective.comp <| @Fin.val_injective <| · + init)) simp [Embedding.coe_ofInjective, Set.eq_univ_iff_forall, eq_comm (a := Set.univ), Nat.cofinite_eq_atTop, Filter.liminf_eq_iSup_iInf_of_nat] intro j use e.symm j + 1 intro i h use ⟨e.symm j, by linarith⟩ simp end MonomialOrder.IsGroebnerBasis