Theory Groebner_PM

(* Author: Alexander Maletzky *)

theory Groebner_PM
  imports Polynomials.MPoly_PM Reduced_GB
begin

text ‹We prove results that hold specifically for Gr\"obner bases in polynomial rings, where the
  polynomials really have @{emph ‹indeterminates›}.›

context pm_powerprod
begin

lemmas finite_reduced_GB_Polys =
  punit.finite_reduced_GB_dgrad_p_set[simplified, OF dickson_grading_varnum, where m=0, simplified dgrad_p_set_varnum]
lemmas reduced_GB_is_reduced_GB_Polys =
  punit.reduced_GB_is_reduced_GB_dgrad_p_set[simplified, OF dickson_grading_varnum, where m=0, simplified dgrad_p_set_varnum]
lemmas reduced_GB_is_GB_Polys =
  punit.reduced_GB_is_GB_dgrad_p_set[simplified, OF dickson_grading_varnum, where m=0, simplified dgrad_p_set_varnum]
lemmas reduced_GB_is_auto_reduced_Polys =
  punit.reduced_GB_is_auto_reduced_dgrad_p_set[simplified, OF dickson_grading_varnum, where m=0, simplified dgrad_p_set_varnum]
lemmas reduced_GB_is_monic_set_Polys =
  punit.reduced_GB_is_monic_set_dgrad_p_set[simplified, OF dickson_grading_varnum, where m=0, simplified dgrad_p_set_varnum]
lemmas reduced_GB_nonzero_Polys =
  punit.reduced_GB_nonzero_dgrad_p_set[simplified, OF dickson_grading_varnum, where m=0, simplified dgrad_p_set_varnum]
lemmas reduced_GB_ideal_Polys =
  punit.reduced_GB_pmdl_dgrad_p_set[simplified, OF dickson_grading_varnum, where m=0, simplified dgrad_p_set_varnum]
lemmas reduced_GB_unique_Polys =
  punit.reduced_GB_unique_dgrad_p_set[simplified, OF dickson_grading_varnum, where m=0, simplified dgrad_p_set_varnum]
lemmas reduced_GB_Polys =
  punit.reduced_GB_dgrad_p_set[simplified, OF dickson_grading_varnum, where m=0, simplified dgrad_p_set_varnum]
lemmas ideal_eq_UNIV_iff_reduced_GB_eq_one_Polys =
  ideal_eq_UNIV_iff_reduced_GB_eq_one_dgrad_p_set[simplified, OF dickson_grading_varnum, where m=0, simplified dgrad_p_set_varnum]

subsection ‹Univariate Polynomials›

lemma (in -) adds_univariate_linear:
  assumes "finite X" and "card X  1" and "s  .[X]" and "t  .[X]"
  obtains "s adds t" | "t adds s"
proof (cases "s adds t")
  case True
  thus ?thesis ..
next
  case False
  then obtain x where 1: "lookup t x < lookup s x" by (auto simp: adds_poly_mapping le_fun_def not_le)
  hence "x  keys s" by (simp add: in_keys_iff)
  also from assms(3) have "  X" by (rule PPsD)
  finally have "x  X" .
  have "t adds s" unfolding adds_poly_mapping le_fun_def
  proof
    fix y
    show "lookup t y  lookup s y"
    proof (cases "y  keys t")
      case True
      also from assms(4) have "keys t  X" by (rule PPsD)
      finally have "y  X" .
      with assms(1, 2) x  X have "x = y" by (simp add: card_le_Suc0_iff_eq)
      with 1 show ?thesis by simp
    next
      case False
      thus ?thesis by (simp add: in_keys_iff)
    qed
  qed
  thus ?thesis ..
qed

context
  fixes X :: "'x set"
  assumes fin_X: "finite X" and card_X: "card X  1"
begin

lemma ord_iff_adds_univariate:
  assumes "s  .[X]" and "t  .[X]"
  shows "s  t  s adds t"
proof
  assume "s  t"
  from fin_X card_X assms show "s adds t"
  proof (rule adds_univariate_linear)
    assume "t adds s"
    hence "t  s" by (rule ord_adds)
    with s  t have "s = t"
      by simp
    thus ?thesis by simp
  qed
qed (rule ord_adds)

lemma adds_iff_deg_le_univariate:
  assumes "s  .[X]" and "t  .[X]"
  shows "s adds t  deg_pm s  deg_pm t"
proof
  assume *: "deg_pm s  deg_pm t"
  from fin_X card_X assms show "s adds t"
  proof (rule adds_univariate_linear)
    assume "t adds s"
    hence "t = s" using * by (rule adds_deg_pm_antisym)
    thus ?thesis by simp
  qed
qed (rule deg_pm_mono)

corollary ord_iff_deg_le_univariate: "s  .[X]  t  .[X]  s  t  deg_pm s  deg_pm t"
  by (simp only: ord_iff_adds_univariate adds_iff_deg_le_univariate)

lemma poly_deg_univariate:
  assumes "p  P[X]"
  shows "poly_deg p = deg_pm (lpp p)"
proof (cases "p = 0")
  case True
  thus ?thesis by simp
next
  case False
  hence lp_in: "lpp p  keys p" by (rule punit.lt_in_keys)
  also from assms have "  .[X]" by (rule PolysD)
  finally have "lpp p  .[X]" .
  show ?thesis
  proof (intro antisym poly_deg_leI)
    fix t
    assume "t  keys p"
    hence "t  lpp p" by (rule punit.lt_max_keys)
    moreover from t  keys p keys p  .[X] have "t  .[X]" ..
    ultimately show "deg_pm t  deg_pm (lpp p)" using lpp p  .[X]
      by (simp only: ord_iff_deg_le_univariate)
  next
    from lp_in show "deg_pm (lpp p)  poly_deg p" by (rule poly_deg_max_keys)
  qed
qed

lemma reduced_GB_univariate_cases:
  assumes "F  P[X]"
  obtains g where "g  P[X]" and "g  0" and "lcf g = 1" and "punit.reduced_GB F = {g}" |
    "punit.reduced_GB F = {}"
proof (cases "punit.reduced_GB F = {}")
  case True
  thus ?thesis ..
next
  case False
  let ?G = "punit.reduced_GB F"
  from fin_X assms have ar: "punit.is_auto_reduced ?G" and "0  ?G" and "?G  P[X]"
    and m: "punit.is_monic_set ?G"
    by (rule reduced_GB_is_auto_reduced_Polys, rule reduced_GB_nonzero_Polys, rule reduced_GB_Polys,
        rule reduced_GB_is_monic_set_Polys)
  from False obtain g where "g  ?G" by blast
  with 0  ?G ?G  P[X] have "g  0" and "g  P[X]" by blast+
  from this(1) have lp_g: "lpp g  keys g" by (rule punit.lt_in_keys)
  also from g  P[X] have "  .[X]" by (rule PolysD)
  finally have "lpp g  .[X]" .
  note g  P[X] g  0
  moreover from m g  ?G g  0 have "lcf g = 1" by (rule punit.is_monic_setD)
  moreover have "?G = {g}"
  proof
    show "?G  {g}"
    proof
      fix g'
      assume "g'  ?G"
      with 0  ?G ?G  P[X] have "g'  0" and "g'  P[X]" by blast+
      from this(1) have lp_g': "lpp g'  keys g'" by (rule punit.lt_in_keys)
      also from g'  P[X] have "  .[X]" by (rule PolysD)
      finally have "lpp g'  .[X]" .
      have "g' = g"
      proof (rule ccontr)
        assume "g'  g"
        with g  ?G g'  ?G have g: "g  ?G - {g'}" and g': "g'  ?G - {g}" by blast+
        from fin_X card_X lpp g  .[X] lpp g'  .[X] show False
        proof (rule adds_univariate_linear)
          assume *: "lpp g adds lpp g'"
          from ar g'  ?G have "¬ punit.is_red (?G - {g'}) g'" by (rule punit.is_auto_reducedD)
          moreover from g g  0 lp_g' * have "punit.is_red (?G - {g'}) g'"
            by (rule punit.is_red_addsI[simplified])
          ultimately show ?thesis ..
        next
          assume *: "lpp g' adds lpp g"
          from ar g  ?G have "¬ punit.is_red (?G - {g}) g" by (rule punit.is_auto_reducedD)
          moreover from g' g'  0 lp_g * have "punit.is_red (?G - {g}) g"
            by (rule punit.is_red_addsI[simplified])
          ultimately show ?thesis ..
        qed
      qed
      thus "g'  {g}" by simp
    qed
  next
    from g  ?G show "{g}  ?G" by simp
  qed
  ultimately show ?thesis ..
qed

corollary deg_reduced_GB_univariate_le:
  assumes "F  P[X]" and "f  ideal F" and "f  0" and "g  punit.reduced_GB F"
  shows "poly_deg g  poly_deg f"
  using assms(1)
proof (rule reduced_GB_univariate_cases)
  let ?G = "punit.reduced_GB F"
  fix g'
  assume "g'  P[X]" and "g'  0" and G: "?G = {g'}"
  from fin_X assms(1) have gb: "punit.is_Groebner_basis ?G" and "ideal ?G = ideal F"
    and "?G  P[X]"
    by (rule reduced_GB_is_GB_Polys, rule reduced_GB_ideal_Polys, rule reduced_GB_Polys)
  from assms(2) this(2) have "f  ideal ?G" by simp
  with gb obtain g'' where "g''  ?G" and "lpp g'' adds lpp f"
    using assms(3) by (rule punit.GB_adds_lt[simplified])
  with assms(4) have "lpp g adds lpp f" by (simp add: G)
  hence "deg_pm (lpp g)  deg_pm (lpp f)" by (rule deg_pm_mono)
  moreover from assms(4) ?G  P[X] have "g  P[X]" ..
  ultimately have "poly_deg g  deg_pm (lpp f)" by (simp only: poly_deg_univariate)
  also from punit.lt_in_keys have "  poly_deg f" by (rule poly_deg_max_keys) fact
  finally show ?thesis .
next
  assume "punit.reduced_GB F = {}"
  with assms(4) show ?thesis by simp
qed

end

subsection ‹Homogeneity›

lemma is_reduced_GB_homogeneous:
  assumes "f. f  F  homogeneous f" and "punit.is_reduced_GB G" and "ideal G = ideal F"
    and "g  G"
  shows "homogeneous g"
proof (rule homogeneousI)
  fix s t
  have 1: "deg_pm u = deg_pm (lpp g)" if "u  keys g" for u
  proof -
    from assms(4) have "g  ideal G" by (rule ideal.span_base)
    hence "g  ideal F" by (simp only: assms(3))
    from that have "u  Keys (hom_components g)" by (simp only: Keys_hom_components)
    then obtain q where q: "q  hom_components g" and "u  keys q" by (rule in_KeysE)
    from assms(1) g  ideal F q have "q  ideal F" by (rule homogeneous_ideal')
    from assms(2) have "punit.is_Groebner_basis G" by (rule punit.reduced_GB_D1)
    moreover from q  ideal F have "q  ideal G" by (simp only: assms(3))
    moreover from q have "q  0" by (rule hom_components_nonzero)
    ultimately obtain g' where "g'  G" and "g'  0" and adds: "lpp g' adds lpp q"
      by (rule punit.GB_adds_lt[simplified])
    from q  0 have "lpp q  keys q" by (rule punit.lt_in_keys)
    also from q have "  Keys (hom_components g)" by (rule keys_subset_Keys)
    finally have "lpp q  keys g" by (simp only: Keys_hom_components)
    with _ g'  0 have red: "punit.is_red {g'} g"
      using adds by (rule punit.is_red_addsI[simplified]) simp
    from assms(2) have "punit.is_auto_reduced G" by (rule punit.reduced_GB_D2)
    hence "¬ punit.is_red (G - {g}) g" using assms(4) by (rule punit.is_auto_reducedD)
    with red have "¬ {g'}  G - {g}" using punit.is_red_subset by blast
    with g'  G have "g' = g" by simp
    from lpp q  keys g have "lpp q  lpp g" by (rule punit.lt_max_keys)
    moreover from adds have "lpp g  lpp q"
      unfolding g' = g by (rule punit.ord_adds_term[simplified])
    ultimately have eq: "lpp q = lpp g"
      by simp
    from q have "homogeneous q" by (rule hom_components_homogeneous)
    hence "deg_pm u = deg_pm (lpp q)"
      using u  keys q lpp q  keys q by (rule homogeneousD)
    thus ?thesis by (simp only: eq)
  qed
  assume "s  keys g"
  hence 2: "deg_pm s = deg_pm (lpp g)" by (rule 1)
  assume "t  keys g"
  hence "deg_pm t = deg_pm (lpp g)" by (rule 1)
  with 2 show "deg_pm s = deg_pm t" by simp
qed

lemma lp_dehomogenize:
  assumes "is_hom_ord x" and "homogeneous p"
  shows "lpp (dehomogenize x p) = except (lpp p) {x}"
proof (cases "p = 0")
  case True
  thus ?thesis by simp
next
  case False
  hence "lpp p  keys p" by (rule punit.lt_in_keys)
  with assms(2) have "except (lpp p) {x}  keys (dehomogenize x p)"
    by (rule keys_dehomogenizeI)
  thus ?thesis
  proof (rule punit.lt_eqI_keys)
    fix t
    assume "t  keys (dehomogenize x p)"
    then obtain s where "s  keys p" and t: "t = except s {x}" by (rule keys_dehomogenizeE)
    from this(1) have "s  lpp p" by (rule punit.lt_max_keys)
    moreover from assms(2) s  keys p lpp p  keys p have "deg_pm s = deg_pm (lpp p)"
      by (rule homogeneousD)
    ultimately show "t  except (lpp p) {x}" using assms(1) by (simp add: t is_hom_ordD)
  qed
qed

lemma isGB_dehomogenize:
  assumes "is_hom_ord x" and "finite X" and "G  P[X]" and "punit.is_Groebner_basis G"
    and "g. g  G  homogeneous g"
  shows "punit.is_Groebner_basis (dehomogenize x ` G)"
  using dickson_grading_varnum
proof (rule punit.isGB_I_adds_lt[simplified])
  from assms(2) show "finite (X - {x})" by simp
next
  have "dehomogenize x ` G  P[X - {x}]"
  proof
    fix g
    assume "g  dehomogenize x ` G"
    then obtain g' where "g'  G" and g: "g = dehomogenize x g'" ..
    from this(1) assms(3) have "g'  P[X]" ..
    hence "indets g'  X" by (rule PolysD)
    have "indets g  indets g' - {x}" by (simp only: g indets_dehomogenize)
    also from indets g'  X subset_refl have "  X - {x}" by (rule Diff_mono)
    finally show "g  P[X - {x}]" by (rule PolysI_alt)
  qed
  thus "dehomogenize x ` G  punit.dgrad_p_set (varnum (X - {x})) 0"
    by (simp only: dgrad_p_set_varnum)
next
  fix p
  assume "p  ideal (dehomogenize x ` G)"
  then obtain G0 q where "G0  dehomogenize x ` G" and "finite G0" and p: "p = (gG0. q g * g)"
    by (rule ideal.spanE)
  from this(1) obtain G' where "G'  G" and G0: "G0 = dehomogenize x ` G'"
    and inj: "inj_on (dehomogenize x) G'" by (rule subset_imageE_inj)
  define p' where "p' = (gG'. q (dehomogenize x g) * g)"
  have "p'  ideal G'" unfolding p'_def by (rule ideal.sum_in_spanI)
  also from G'  G have "  ideal G" by (rule ideal.span_mono)
  finally have "p'  ideal G" .
  with assms(5) have "homogenize x p'  ideal G" (is "?p  _") by (rule homogeneous_ideal_homogenize)

  assume "p  punit.dgrad_p_set (varnum (X - {x})) 0"
  hence "p  P[X - {x}]" by (simp only: dgrad_p_set_varnum)
  hence "indets p  X - {x}" by (rule PolysD)
  hence "x  indets p" by blast
  have "p = dehomogenize x p" by (rule sym) (simp add: x  indets p)
  also from inj have " = dehomogenize x (gG'. q (dehomogenize x g) * dehomogenize x g)"
    by (simp add: p G0 sum.reindex)
  also have " = dehomogenize x ?p"
    by (simp add: dehomogenize_sum dehomogenize_times p'_def)
  finally have p: "p = dehomogenize x ?p" .
  moreover assume "p  0"
  ultimately have "?p  0" by (auto simp del: dehomogenize_homogenize)
  with assms(4) ?p  ideal G obtain g where "g  G" and "g  0" and adds: "lpp g adds lpp ?p"
    by (rule punit.GB_adds_lt[simplified])
  from this(1) have "homogeneous g" by (rule assms(5))
  show "gdehomogenize x ` G. g  0  lpp g adds lpp p"
  proof (intro bexI conjI notI)
    assume "dehomogenize x g = 0"
    hence "g = 0" using homogeneous g by (rule dehomogenize_zeroD)
    with g  0 show False ..
  next
    from assms(1) homogeneous g have "lpp (dehomogenize x g) = except (lpp g) {x}"
      by (rule lp_dehomogenize)
    also from adds have " adds except (lpp ?p) {x}"
      by (simp add: adds_poly_mapping le_fun_def lookup_except)
    also from assms(1) homogeneous_homogenize have " = lpp (dehomogenize x ?p)"
      by (rule lp_dehomogenize[symmetric])
    finally show "lpp (dehomogenize x g) adds lpp p" by (simp only: p)
  next
    from g  G show "dehomogenize x g  dehomogenize x ` G" by (rule imageI)
  qed
qed

end (* pm_powerprod *)

context extended_ord_pm_powerprod
begin

lemma extended_ord_lp:
  assumes "None  indets p"
  shows "restrict_indets_pp (extended_ord.lpp p) = lpp (restrict_indets p)"
proof (cases "p = 0")
  case True
  thus ?thesis by simp
next
  case False
  hence "extended_ord.lpp p  keys p" by (rule extended_ord.punit.lt_in_keys)
  hence "restrict_indets_pp (extended_ord.lpp p)  restrict_indets_pp ` keys p" by (rule imageI)
  also from assms have eq: " = keys (restrict_indets p)" by (rule keys_restrict_indets[symmetric])
  finally show ?thesis
  proof (rule punit.lt_eqI_keys[symmetric])
    fix t
    assume "t  keys (restrict_indets p)"
    then obtain s where "s  keys p" and t: "t = restrict_indets_pp s" unfolding eq[symmetric] ..
    from this(1) have "extended_ord s (extended_ord.lpp p)" by (rule extended_ord.punit.lt_max_keys)
    thus "t  restrict_indets_pp (extended_ord.lpp p)" by (auto simp: t extended_ord_def)
  qed
qed

lemma restrict_indets_reduced_GB:
  assumes "finite X" and "F  P[X]"
  shows "punit.is_Groebner_basis (restrict_indets ` extended_ord.punit.reduced_GB (homogenize None ` extend_indets ` F))"
          (is ?thesis1)
    and "ideal (restrict_indets ` extended_ord.punit.reduced_GB (homogenize None ` extend_indets ` F)) = ideal F"
          (is ?thesis2)
    and "restrict_indets ` extended_ord.punit.reduced_GB (homogenize None ` extend_indets ` F)  P[X]"
          (is ?thesis3)
proof -
  let ?F = "homogenize None ` extend_indets ` F"
  let ?G = "extended_ord.punit.reduced_GB ?F"
  from assms(1) have "finite (insert None (Some ` X))" by simp
  moreover have "?F  P[insert None (Some ` X)]"
  proof
    fix hf
    assume "hf  ?F"
    then obtain f where "f  F" and hf: "hf = homogenize None (extend_indets f)" by auto
    from this(1) assms(2) have "f  P[X]" ..
    hence "indets f  X" by (rule PolysD)
    hence "Some ` indets f  Some ` X" by (rule image_mono)
    with indets_extend_indets[of f] have "indets (extend_indets f)  Some ` X" by blast
    hence "insert None (indets (extend_indets f))  insert None (Some ` X)" by blast
    with indets_homogenize_subset have "indets hf  insert None (Some ` X)"
      unfolding hf by (rule subset_trans)
    thus "hf  P[insert None (Some ` X)]" by (rule PolysI_alt)
  qed
  ultimately have G_sub: "?G  P[insert None (Some ` X)]"
    and ideal_G: "ideal ?G = ideal ?F"
    and GB_G: "extended_ord.punit.is_reduced_GB ?G"
    by (rule extended_ord.reduced_GB_Polys, rule extended_ord.reduced_GB_ideal_Polys,
        rule extended_ord.reduced_GB_is_reduced_GB_Polys)

  show ?thesis3
  proof
    fix g
    assume "g  restrict_indets ` ?G"
    then obtain g' where "g'  ?G" and g: "g = restrict_indets g'" ..
    from this(1) G_sub have "g'  P[insert None (Some ` X)]" ..
    hence "indets g'  insert None (Some ` X)" by (rule PolysD)
    have "indets g  the ` (indets g' - {None})" by (simp only: g indets_restrict_indets_subset)
    also from indets g'  insert None (Some ` X) have "  X" by auto
    finally show "g  P[X]" by (rule PolysI_alt)
  qed

  from dickson_grading_varnum show ?thesis1
  proof (rule punit.isGB_I_adds_lt[simplified])
    from ?thesis3 show "restrict_indets ` ?G  punit.dgrad_p_set (varnum X) 0"
      by (simp only: dgrad_p_set_varnum)
  next
    fix p :: "('a 0 nat) 0 'b"
    assume "p  0"
    assume "p  ideal (restrict_indets ` ?G)"
    hence "extend_indets p  extend_indets ` ideal (restrict_indets ` ?G)" by (rule imageI)
    also have "  ideal (extend_indets ` restrict_indets ` ?G)" by (fact extend_indets_ideal_subset)
    also have " = ideal (dehomogenize None ` ?G)"
      by (simp only: image_comp extend_indets_comp_restrict_indets)
    finally have p_in_ideal: "extend_indets p  ideal (dehomogenize None ` ?G)" .
    assume "p  punit.dgrad_p_set (varnum X) 0"
    hence "p  P[X]" by (simp only: dgrad_p_set_varnum)
    have "extended_ord.punit.is_Groebner_basis (dehomogenize None ` ?G)"
      using extended_ord_is_hom_ord finite (insert None (Some ` X)) G_sub
    proof (rule extended_ord.isGB_dehomogenize)
      from GB_G show "extended_ord.punit.is_Groebner_basis ?G"
        by (rule extended_ord.punit.reduced_GB_D1)
    next
      fix g
      assume "g  ?G"
      with _ GB_G ideal_G show "homogeneous g"
      proof (rule extended_ord.is_reduced_GB_homogeneous)
        fix hf
        assume "hf  ?F"
        then obtain f where "hf = homogenize None f" ..
        thus "homogeneous hf" by (simp only: homogeneous_homogenize)
      qed
    qed
    moreover note p_in_ideal
    moreover from p  0 have "extend_indets p  0" by simp
    ultimately obtain g where g_in: "g  dehomogenize None ` ?G" and "g  0"
      and adds: "extended_ord.lpp g adds extended_ord.lpp (extend_indets p)"
      by (rule extended_ord.punit.GB_adds_lt[simplified])
    have "None  indets g"
    proof
      assume "None  indets g"
      moreover from g_in obtain g0 where "g = dehomogenize None g0" ..
      ultimately show False using indets_dehomogenize[of None g0] by blast
    qed
    show "grestrict_indets ` ?G. g  0  lpp g adds lpp p"
    proof (intro bexI conjI notI)
      have "lpp (restrict_indets g) = restrict_indets_pp (extended_ord.lpp g)"
        by (rule sym, intro extended_ord_lp None  indets g)
      also from adds have " adds restrict_indets_pp (extended_ord.lpp (extend_indets p))"
        by (simp add: adds_poly_mapping le_fun_def lookup_restrict_indets_pp)
      also have " = lpp (restrict_indets (extend_indets p))"
      proof (intro extended_ord_lp notI)
        assume "None  indets (extend_indets p)"
        thus False by (simp add: indets_extend_indets)
      qed
      also have " = lpp p" by simp
      finally show "lpp (restrict_indets g) adds lpp p" .
    next
      from g_in have "restrict_indets g  restrict_indets ` dehomogenize None ` ?G" by (rule imageI)
      also have " = restrict_indets ` ?G" by (simp only: image_comp restrict_indets_comp_dehomogenize)
      finally show "restrict_indets g  restrict_indets ` ?G" .
    next
      assume "restrict_indets g = 0"
      with None  indets g extend_restrict_indets have "g = 0" by fastforce
      with g  0 show False ..
    qed
  qed (fact assms(1))

  from ideal_G show ?thesis2 by (rule ideal_restrict_indets)
qed

end

end (* theory *)