theory Syzygy imports Groebner_Bases More_MPoly_Type_Class begin
text‹In this theory we first introduce the general concept of @{emph ‹syzygies›} in modules, and
then provide a method for computing Gr\"obner bases of syzygy modules of lists of multivariate
vector-polynomials. Since syzygies in this context are themselves represented by vector-polynomials,
this method can be applied repeatedly to compute bases of syzygy modules of syzygies, and so on.›
instance nat :: comm_powerprod ..
subsection‹Syzygy Modules Generated by Sets›
context module begin
definition rep :: "('b ==>0 'a) ==> 'b" where"rep r = (∑v∈keys r. lookup r v *s v)"
definition represents :: "'b set ==> ('b ==>0 'a) ==> 'b ==> bool" where"represents B r x ⟷ (keys r ⊆ B ∧ local.rep r = x)"
definition syzygy_module :: "'b set ==> ('b ==>0 'a) set" where"syzygy_module B = {s. local.represents B s 0}"
lemma rep_plus: "rep (r + s) = rep r + rep s" proof - from finite_keys finite_keys have fin: "finite (keys r ∪ keys s)"by (rule finite_UnI) from fin have eq1: "(∑v∈keys r ∪ keys s. lookup r v *s v) = (∑v∈keys r. lookup r v *s v)" proof (rule sum.mono_neutral_right) show"∀v∈keys r ∪ keys s - keys r. lookup r v *s v = 0"by (simp add: in_keys_iff) qed simp from fin have eq2: "(∑v∈keys r ∪ keys s. lookup s v *s v) = (∑v∈keys s. lookup s v *s v)" proof (rule sum.mono_neutral_right) show"∀v∈keys r ∪ keys s - keys s. lookup s v *s v = 0"by (simp add: in_keys_iff) qed simp have"rep (r + s) = (∑v∈keys (r + s). lookup (r + s) v *s v)"by (simp only: rep_def) alsohave"... = (∑v∈keys r ∪ keys s. lookup (r + s) v *s v)" proof (rule sum.mono_neutral_left) show"∀i∈keys r ∪ keys s - keys (r + s). lookup (r + s) i *s i = 0"by (simp add: in_keys_iff) qed (auto simp: Poly_Mapping.keys_add) alsohave"... = (∑v∈keys r ∪ keys s. lookup r v *s v) + (∑v∈keys r ∪ keys s. lookup s v *s v)" by (simp add: lookup_add scale_left_distrib sum.distrib) alsohave"... = rep r + rep s"by (simp only: eq1 eq2 rep_def) finallyshow ?thesis . qed
lemma rep_minus: "rep (r - s) = rep r - rep s" proof - from finite_keys finite_keys have fin: "finite (keys r ∪ keys s)"by (rule finite_UnI) from fin have eq1: "(∑v∈keys r ∪ keys s. lookup r v *s v) = (∑v∈keys r. lookup r v *s v)" proof (rule sum.mono_neutral_right) show"∀v∈keys r ∪ keys s - keys r. lookup r v *s v = 0"by (simp add: in_keys_iff) qed simp from fin have eq2: "(∑v∈keys r ∪ keys s. lookup s v *s v) = (∑v∈keys s. lookup s v *s v)" proof (rule sum.mono_neutral_right) show"∀v∈keys r ∪ keys s - keys s. lookup s v *s v = 0"by (simp add: in_keys_iff) qed simp have"rep (r - s) = (∑v∈keys (r - s). lookup (r - s) v *s v)"by (simp only: rep_def) alsofrom fin keys_minus have"... = (∑v∈keys r ∪ keys s. lookup (r - s) v *s v)" proof (rule sum.mono_neutral_left) show"∀i∈keys r ∪ keys s - keys (r - s). lookup (r - s) i *s i = 0"by (simp add: in_keys_iff) qed alsohave"... = (∑v∈keys r ∪ keys s. lookup r v *s v) - (∑v∈keys r ∪ keys s. lookup s v *s v)" by (simp add: lookup_minus scale_left_diff_distrib sum_subtractf) alsohave"... = rep r - rep s"by (simp only: eq1 eq2 rep_def) finallyshow ?thesis . qed
lemma rep_smult: "rep (monomial c 0 * r) = c *s rep r" proof - have l: "lookup (monomial c 0 * r) v = c * (lookup r v)"for v unfolding mult_map_scale_conv_mult[symmetric] by (rule map_lookup, simp) have sub: "keys (monomial c 0 * r) ⊆ keys r" by (metis l lookup_not_eq_zero_eq_in_keys mult_zero_right subsetI)
have"rep (monomial c 0 * r) = (∑v∈keys (monomial c 0 * r). lookup (monomial c 0 * r) v *s v)" by (simp only: rep_def) alsofrom finite_keys sub have"... = (∑v∈keys r. lookup (monomial c 0 * r) v *s v)" proof (rule sum.mono_neutral_left) show"∀v∈keys r - keys (monomial c 0 * r). lookup (monomial c 0 * r) v *s v = 0"by (simp add: in_keys_iff) qed alsohave"... = c *s (∑v∈keys r. lookup r v *s v)"by (simp add: l scale_sum_right) alsohave"... = c *s rep r"by (simp add: rep_def) finallyshow ?thesis . qed
lemma rep_in_span: "rep r ∈ span (keys r)" unfolding rep_def by (fact sum_in_spanI)
lemma spanE_rep: assumes"x ∈ span B" obtains r where"keys r ⊆ B"and"x = rep r" proof - from assms obtain A q where"finite A"and"A ⊆ B"and x: "x = (∑a∈A. q a *s a)"by (rule spanE)
define r where"r = Abs_poly_mapping (λk. q k when k ∈ A)" have1: "lookup r = (λk. q k when k ∈ A)"unfolding r_def by (rule Abs_poly_mapping_inverse, simp add: ‹finite A›) have2: "keys r ⊆ A"by (auto simp: in_keys_iff 1) show ?thesis proof have"x = (∑a∈A. lookup r a *s a)"unfolding x by (rule sum.cong, simp_all add: 1) alsofrom‹finite A›2have"... = (∑a∈keys r. lookup r a *s a)" proof (rule sum.mono_neutral_right) show"∀a∈A - keys r. lookup r a *s a = 0"by (simp add: in_keys_iff) qed finallyshow"x = rep r"by (simp only: rep_def) next from2‹A ⊆ B›show"keys r ⊆ B"by (rule subset_trans) qed qed
lemma representsI: assumes"keys r ⊆ B"and"rep r = x" shows"represents B r x" unfolding represents_def using assms by blast
lemma representsD1: assumes"represents B r x" shows"keys r ⊆ B" using assms unfolding represents_def by blast
lemma representsD2: assumes"represents B r x" shows"x = rep r" using assms unfolding represents_def by blast
lemma represents_mono: assumes"represents B r x"and"B ⊆ A" shows"represents A r x" proof (rule representsI) from assms(1) have"keys r ⊆ B"by (rule representsD1) thus"keys r ⊆ A"using assms(2) by (rule subset_trans) next from assms(1) have"x = rep r"by (rule representsD2) thus"rep r = x"by (rule HOL.sym) qed
lemma represents_zero: "represents B 0 0" by (rule representsI, simp_all)
lemma represents_plus: assumes"represents A r x"and"represents B s y" shows"represents (A ∪ B) (r + s) (x + y)" proof - from assms(1) have r: "keys r ⊆ A"and x: "x = rep r"by (rule representsD1, rule representsD2) from assms(2) have s: "keys s ⊆ B"and y: "y = rep s"by (rule representsD1, rule representsD2) show ?thesis proof (rule representsI) from r s have"keys r ∪ keys s ⊆ A ∪ B"by blast thus"keys (r + s) ⊆ A ∪ B" by (meson Poly_Mapping.keys_add subset_trans) qed (simp add: rep_plus x y) qed
lemma represents_uminus: assumes"represents B r x" shows"represents B (- r) (- x)" proof - from assms have r: "keys r ⊆ B"and x: "x = rep r"by (rule representsD1, rule representsD2) show ?thesis proof (rule representsI) from r show"keys (- r) ⊆ B"by (simp only: keys_uminus) qed (simp add: x) qed
lemma represents_minus: assumes"represents A r x"and"represents B s y" shows"represents (A ∪ B) (r - s) (x - y)" proof - from assms(1) have r: "keys r ⊆ A"and x: "x = rep r"by (rule representsD1, rule representsD2) from assms(2) have s: "keys s ⊆ B"and y: "y = rep s"by (rule representsD1, rule representsD2) show ?thesis proof (rule representsI) from r s have"keys r ∪ keys s ⊆ A ∪ B"by blast with keys_minus show"keys (r - s) ⊆ A ∪ B"by (rule subset_trans) qed (simp only: rep_minus x y) qed
lemma represents_scale: assumes"represents B r x" shows"represents B (monomial c 0 * r) (c *s x)" proof - from assms have r: "keys r ⊆ B"and x: "x = rep r"by (rule representsD1, rule representsD2) show ?thesis proof (rule representsI) have l: "lookup (monomial c 0 * r) v = c * (lookup r v)"for v unfolding mult_map_scale_conv_mult[symmetric] by (rule map_lookup, simp) have sub: "keys (monomial c 0 * r) ⊆ keys r" by (metis l lookup_not_eq_zero_eq_in_keys mult_zero_right subsetI) thus"keys (monomial c 0 * r) ⊆ B"using r by (rule subset_trans) qed (simp only: rep_smult x) qed
lemma represents_in_span: assumes"represents B r x" shows"x ∈ span B" proof - from assms have r: "keys r ⊆ B"and x: "x = rep r"by (rule representsD1, rule representsD2) have"x ∈ span (keys r)"unfolding x by (fact rep_in_span) alsofrom r have"... ⊆ span B"by (rule span_mono) finallyshow ?thesis . qed
lemma syzygy_module_iff: "s ∈ syzygy_module B ⟷ represents B s 0" by (simp add: syzygy_module_def)
lemma syzygy_moduleI: assumes"represents B s 0" shows"s ∈ syzygy_module B" unfolding syzygy_module_iff using assms .
lemma syzygy_moduleD: assumes"s ∈ syzygy_module B" shows"represents B s 0" using assms unfolding syzygy_module_iff .
lemma zero_in_syzygy_module: "0 ∈ syzygy_module B" using represents_zero by (rule syzygy_moduleI)
lemma syzygy_module_closed_plus: assumes"s1 ∈ syzygy_module B"and"s2 ∈ syzygy_module B" shows"s1 + s2 ∈ syzygy_module B" proof - from assms(1) have"represents B s1 0"by (rule syzygy_moduleD) moreoverfrom assms(2) have"represents B s2 0"by (rule syzygy_moduleD) ultimatelyhave"represents (B ∪ B) (s1 + s2) (0 + 0)"by (rule represents_plus) hence"represents B (s1 + s2) 0"by simp thus ?thesis by (rule syzygy_moduleI) qed
lemma syzygy_module_closed_minus: assumes"s1 ∈ syzygy_module B"and"s2 ∈ syzygy_module B" shows"s1 - s2 ∈ syzygy_module B" proof - from assms(1) have"represents B s1 0"by (rule syzygy_moduleD) moreoverfrom assms(2) have"represents B s2 0"by (rule syzygy_moduleD) ultimatelyhave"represents (B ∪ B) (s1 - s2) (0 - 0)"by (rule represents_minus) hence"represents B (s1 - s2) 0"by simp thus ?thesis by (rule syzygy_moduleI) qed
lemma syzygy_module_closed_times_monomial: assumes"s ∈ syzygy_module B" shows"monomial c 0 * s ∈ syzygy_module B" proof - from assms(1) have"represents B s 0"by (rule syzygy_moduleD) hence"represents B (monomial c 0 * s) (c *s 0)"by (rule represents_scale) hence"represents B (monomial c 0 * s) 0"by simp thus ?thesis by (rule syzygy_moduleI) qed
end(* module *)
context term_powerprod begin
lemma keys_rep_subset: assumes"u ∈ keys (pmdl.rep r)" obtains t v where"t ∈ Keys (Poly_Mapping.range r)"and"v ∈ Keys (keys r)"and"u = t ⊕ v" proof - note assms alsohave"keys (pmdl.rep r) ⊆ (∪v∈keys r. keys (lookup r v ⊙ v))" by (simp add: pmdl.rep_def keys_sum_subset) finallyobtain v0 where"v0 ∈ keys r"and"u ∈ keys (lookup r v0 ⊙ v0)" .. from this(2) obtain t v where"t ∈ keys (lookup r v0)"and"v ∈ keys v0"and"u = t ⊕ v" by (rule in_keys_mult_scalarE) show ?thesis proof from‹v0 ∈ keys r›have"lookup r v0 ∈ Poly_Mapping.range r"by (rule in_keys_lookup_in_range) with‹t ∈ keys (lookup r v0)›show"t ∈ Keys (Poly_Mapping.range r)"by (rule in_KeysI) next from‹v ∈ keys v0›‹v0 ∈ keys r›show"v ∈ Keys (keys r)"by (rule in_KeysI) qed fact qed
lemma rep_mult_scalar: "pmdl.rep (punit.monom_mult c 0 r) = c ⊙ pmdl.rep r" unfolding punit.mult_scalar_monomial[symmetric] punit_mult_scalar by (fact pmdl.rep_smult)
lemma represents_mult_scalar: assumes"pmdl.represents B r x" shows"pmdl.represents B (punit.monom_mult c 0 r) (c ⊙ x)" unfolding punit.mult_scalar_monomial[symmetric] punit_mult_scalar using assms by (rule pmdl.represents_scale)
lemma syzygy_module_closed_map_scale: "s ∈ pmdl.syzygy_module B ==> c ⋅ s ∈ pmdl.syzygy_module B" unfolding map_scale_eq_times by (rule pmdl.syzygy_module_closed_times_monomial)
lemma phull_syzygy_module: "phull (pmdl.syzygy_module B) = pmdl.syzygy_module B" unfolding phull.span_eq_iff apply (rule phull.subspaceI)
subgoal by (fact pmdl.zero_in_syzygy_module)
subgoal by (fact pmdl.syzygy_module_closed_plus)
subgoal by (fact syzygy_module_closed_map_scale) done
end(* term_powerprod *)
subsection‹Polynomial Mappings on List-Indices›
definition pm_of_idx_pm :: "('a list) ==> (nat ==>0 'b) ==> 'a ==>0 'b::zero" where"pm_of_idx_pm xs f = Abs_poly_mapping (λx. lookup f (Min {i. i < length xs ∧xs ! i = x}) when x ∈ set xs)"
definition idx_pm_of_pm :: "('a list) ==> ('a ==>0 'b) ==> nat ==>0 'b::zero" where"idx_pm_of_pm xs f = Abs_poly_mapping (λi. lookup f (xs ! i) when i < length xs)"
lemma lookup_pm_of_idx_pm: "lookup (pm_of_idx_pm xs f) = (λx. lookup f (Min {i. i < length xs ∧ xs ! i = x}) when x ∈ set xs)" unfolding pm_of_idx_pm_def by (rule Abs_poly_mapping_inverse, simp)
lemma lookup_pm_of_idx_pm_distinct: assumes"distinct xs"and"i < length xs" shows"lookup (pm_of_idx_pm xs f) (xs ! i) = lookup f i" proof - from assms have"{j. j < length xs ∧ xs ! j = xs ! i} = {i}" using distinct_Ex1 nth_mem by fastforce moreoverfrom assms(2) have"xs ! i ∈ set xs"by (rule nth_mem) ultimatelyshow ?thesis by (simp add: lookup_pm_of_idx_pm) qed
lemma keys_pm_of_idx_pm_subset: "keys (pm_of_idx_pm xs f) ⊆ set xs" proof fix t assume"t ∈ keys (pm_of_idx_pm xs f)" hence"lookup (pm_of_idx_pm xs f) t ≠ 0"by (simp add: in_keys_iff) thus"t ∈ set xs"by (simp add: lookup_pm_of_idx_pm) qed
lemma range_pm_of_idx_pm_subset: "Poly_Mapping.range (pm_of_idx_pm xs f) ⊆ lookup f ` {0..<length xs} - {0}" proof fix c assume"c ∈ Poly_Mapping.range (pm_of_idx_pm xs f)" thenobtain t where t: "t ∈ keys (pm_of_idx_pm xs f)"and c: "c = lookup (pm_of_idx_pm xs f) t" by (metis DiffE imageE insertCI not_in_keys_iff_lookup_eq_zero range.rep_eq) from t keys_pm_of_idx_pm_subset have"t ∈ set xs" .. hence c1: "c = lookup f (Min {i. i < length xs ∧ xs ! i = t})"by (simp add: lookup_pm_of_idx_pm c) show"c ∈ lookup f ` {0..<length xs} - {0}" proof (intro DiffI image_eqI) from‹t ∈ set xs›obtain i where"i < length xs"and"t = xs ! i"by (metis in_set_conv_nth) have"finite {i. i < length xs ∧ xs ! i = t}"by simp moreoverfrom‹i < length xs›‹t = xs ! i›have"{i. i < length xs ∧ xs ! i = t} ≠ {}"by auto ultimatelyhave"Min {i. i < length xs ∧ xs ! i = t} ∈ {i. i < length xs ∧ xs ! i = t}" by (rule Min_in) thus"Min {i. i < length xs ∧ xs ! i = t} ∈ {0..<length xs}"by simp next from t show"c ∉ {0}"by (simp add: c in_keys_iff) qed (fact c1) qed
corollary range_pm_of_idx_pm_subset': "Poly_Mapping.range (pm_of_idx_pm xs f) ⊆ Poly_Mapping.range f" using range_pm_of_idx_pm_subset proof (rule subset_trans) show"lookup f ` {0..<length xs} - {0} ⊆ Poly_Mapping.range f"by (transfer, auto) qed
lemma pm_of_idx_pm_monom_mult: "pm_of_idx_pm xs (punit.monom_mult c 0 f) = punit.monom_mult c 0 (pm_of_idx_pm xs f)" by (rule poly_mapping_eqI, simp add: lookup_pm_of_idx_pm punit.lookup_monom_mult_zero when_def)
lemma pm_of_idx_pm_monomial: assumes"distinct xs" shows"pm_of_idx_pm xs (monomial c i) = (monomial c (xs ! i) when i < length xs)" proof - from assms have *: "{i. i < length xs ∧ xs ! i = xs ! j} = {j}"if"j < length xs"for j using distinct_Ex1 nth_mem that by fastforce show ?thesis proof (cases "i < length xs") case True have"pm_of_idx_pm xs (monomial c i) = monomial c (xs ! i)" proof (rule poly_mapping_eqI) fix k show"lookup (pm_of_idx_pm xs (monomial c i)) k = lookup (monomial c (xs ! i)) k" proof (cases "xs ! i = k") case True with‹i < length xs›have"k ∈ set xs"by auto thus ?thesis by (simp add: lookup_pm_of_idx_pm lookup_single *[OF ‹i < length xs›] True[symmetric]) next case False have"lookup (pm_of_idx_pm xs (monomial c i)) k = 0" proof (cases "k ∈ set xs") case True thenobtain j where"j < length xs"and"k = xs ! j"by (metis in_set_conv_nth) with False have"i ≠ Min {i. i < length xs ∧ xs ! i = k}" by (auto simp: ‹k = xs ! j› *[OF ‹j < length xs›]) thus ?thesis by (simp add: lookup_pm_of_idx_pm True lookup_single) next case False thus ?thesis by (simp add: lookup_pm_of_idx_pm) qed with False show ?thesis by (simp add: lookup_single) qed qed with True show ?thesis by simp next case False have"pm_of_idx_pm xs (monomial c i) = 0" proof (rule poly_mapping_eqI, simp add: lookup_pm_of_idx_pm when_def, rule) fix k assume"k ∈ set xs" thenobtain j where"j < length xs"and"k = xs ! j"by (metis in_set_conv_nth) with False have"i ≠ Min {i. i < length xs ∧ xs ! i = k}" by (auto simp: ‹k = xs ! j› *[OF ‹j < length xs›]) thus"lookup (monomial c i) (Min {i. i < length xs ∧ xs ! i = k}) = 0" by (simp add: lookup_single) qed with False show ?thesis by simp qed qed
lemma pm_of_idx_pm_take: assumes"keys f ⊆ {0..<j}" shows"pm_of_idx_pm (take j xs) f = pm_of_idx_pm xs f" proof (rule poly_mapping_eqI) fix i let ?xs = "take j xs" let ?A = "{k. k < length xs ∧ xs ! k = i}" let ?B = "{k. k < length xs ∧ k < j ∧ xs ! k = i}" have A_fin: "finite ?A"and B_fin: "finite ?B"by fastforce+ have A_ne: "i ∈ set xs ==> ?A ≠ {}"by (simp add: in_set_conv_nth) have B_ne: "i ∈ set ?xs ==> ?B ≠ {}"by (auto simp add: in_set_conv_nth)
define m1 where"m1 = Min ?A"
define m2 where"m2 = Min ?B" have m1: "m1 ∈ ?A"if"i ∈ set xs" unfolding m1_def by (rule Min_in, fact A_fin, rule A_ne, fact that) have m2: "m2 ∈ ?B"if"i ∈ set ?xs" unfolding m2_def by (rule Min_in, fact B_fin, rule B_ne, fact that) show"lookup (pm_of_idx_pm (take j xs) f) i = lookup (pm_of_idx_pm xs f) i" proof (cases "i ∈ set ?xs") case True hence"i ∈ set xs"using set_take_subset .. hence"m1 ∈ ?A"by (rule m1) hence"m1 < length xs"and"xs ! m1 = i"by simp_all from True have"m2 ∈ ?B"by (rule m2) hence"m2 < length xs"and"m2 < j"and"xs ! m2 = i"by simp_all hence"m2 ∈ ?A"by simp with A_fin have"m1 ≤ m2"unfolding m1_def by (rule Min_le) with‹m2 < j›have"m1 < j"by simp with‹m1 < length xs›‹xs ! m1 = i›have"m1 ∈ ?B"by simp with B_fin have"m2 ≤ m1"unfolding m2_def by (rule Min_le) with‹m1 ≤ m2›have"m1 = m2"by (rule le_antisym) with True ‹i ∈ set xs›show ?thesis by (simp add: lookup_pm_of_idx_pm m1_def m2_def cong: conj_cong) next case False thus ?thesis proof (simp add: lookup_pm_of_idx_pm when_def m1_def[symmetric], intro impI) assume"i ∈ set xs" hence"m1 ∈ ?A"by (rule m1) hence"m1 < length xs"and"xs ! m1 = i"by simp_all have"m1 ∉ keys f" proof assume"m1 ∈ keys f" hence"m1 ∈ {0..<j}"using assms .. hence"m1 < j"by simp with‹m1 < length xs›have"m1 < length ?xs"by simp hence"?xs ! m1 ∈ set ?xs"by (rule nth_mem) with‹m1 < j›have"i ∈ set ?xs"by (simp add: ‹xs ! m1 = i›) with False show False .. qed thus"lookup f m1 = 0"by (simp add: in_keys_iff) qed qed qed
lemma lookup_idx_pm_of_pm: "lookup (idx_pm_of_pm xs f) = (λi. lookup f (xs ! i) when i < length xs)" unfolding idx_pm_of_pm_def by (rule Abs_poly_mapping_inverse, simp)
lemma pm_of_idx_pm_of_pm: assumes"keys f ⊆ set xs" shows"pm_of_idx_pm xs (idx_pm_of_pm xs f) = f" proof (rule poly_mapping_eqI, simp add: lookup_pm_of_idx_pm when_def, intro conjI impI) fix k assume"k ∈ set xs"
define i where"i = Min {i. i < length xs ∧ xs ! i = k}" have"finite {i. i < length xs ∧ xs ! i = k}"by simp moreoverfrom‹k ∈ set xs›have"{i. i < length xs ∧ xs ! i = k} ≠ {}" by (simp add: in_set_conv_nth) ultimatelyhave"i ∈ {i. i < length xs ∧ xs ! i = k}"unfolding i_def by (rule Min_in) hence"i < length xs"and"xs ! i = k"by simp_all thus"lookup (idx_pm_of_pm xs f) i = lookup f k"by (simp add: lookup_idx_pm_of_pm) next fix k assume"k ∉ set xs" with assms show"lookup f k = 0"by (auto simp: in_keys_iff) qed
lemma idx_pm_of_pm_of_idx_pm: assumes"distinct xs"and"keys f ⊆ {0..<length xs}" shows"idx_pm_of_pm xs (pm_of_idx_pm xs f) = f" proof (rule poly_mapping_eqI) fix i show"lookup (idx_pm_of_pm xs (pm_of_idx_pm xs f)) i = lookup f i" proof (cases "i < length xs") case True with assms(1) show ?thesis by (simp add: lookup_idx_pm_of_pm lookup_pm_of_idx_pm_distinct) next case False hence"i ∉ {0..<length xs}"by simp with assms(2) have"i ∉ keys f"by blast with False show ?thesis by (simp add: in_keys_iff lookup_idx_pm_of_pm) qed qed
subsection‹POT Orders›
context ordered_term begin
definition is_pot_ord :: bool where"is_pot_ord ⟷ (∀u v. component_of_term u < component_of_term v ⟶ u ≺t v)"
lemma is_pot_ordI: assumes"∧u v. component_of_term u < component_of_term v ==> u ≺t v" shows"is_pot_ord" unfolding is_pot_ord_def using assms by blast
lemma is_pot_ordD: assumes"is_pot_ord"and"component_of_term u < component_of_term v" shows"u ≺t v" using assms unfolding is_pot_ord_def by blast
lemma is_pot_ordD2: assumes"is_pot_ord"and"u ⪯t v" shows"component_of_term u ≤ component_of_term v" proof (rule ccontr) assume"¬ component_of_term u ≤ component_of_term v" hence"component_of_term v < component_of_term u"by simp with assms(1) have"v ≺t u"by (rule is_pot_ordD) with assms(2) show False by simp qed
lemma is_pot_ord: assumes"is_pot_ord" shows"u ⪯t v ⟷ (component_of_term u < component_of_term v ∨ (component_of_term u = component_of_term v ∧ pp_of_term u ⪯ pp_of_term v))" (is"?l ⟷ ?r") proof assume ?l with assms have"component_of_term u ≤ component_of_term v"by (rule is_pot_ordD2) hence"component_of_term u < component_of_term v ∨ component_of_term u = component_of_term v" by (simp add: order_class.le_less) thus ?r proof assume"component_of_term u < component_of_term v" thus ?r .. next assume1: "component_of_term u = component_of_term v" moreoverhave"pp_of_term u ⪯ pp_of_term v" proof (rule ccontr) assume"¬ pp_of_term u ⪯ pp_of_term v" hence2: "pp_of_term v ⪯ pp_of_term u"and3: "pp_of_term u ≠ pp_of_term v"by simp_all from1have"component_of_term v ≤ component_of_term u"by simp with2have"v ⪯t u"by (rule ord_termI) with‹?l›have"u = v"by simp with3show False by simp qed ultimatelyshow ?r by simp qed next assume ?r thus ?l proof assume"component_of_term u < component_of_term v" with assms have"u ≺t v"by (rule is_pot_ordD) thus ?l by simp next assume"component_of_term u = component_of_term v ∧ pp_of_term u ⪯ pp_of_term v" hence"pp_of_term u ⪯ pp_of_term v"and"component_of_term u ≤ component_of_term v"by simp_all thus ?l by (rule ord_termI) qed qed
definition map_component :: "('k ==> 'k) ==> 't ==> 't" where"map_component f v = term_of_pair (pp_of_term v, f (component_of_term v))"
lemma pair_of_map_component [term_simps]: "pair_of_term (map_component f v) = (pp_of_term v, f (component_of_term v))" by (simp add: map_component_def pair_term)
lemma pp_of_map_component [term_simps]: "pp_of_term (map_component f v) = pp_of_term v" by (simp add: pp_of_term_def pair_of_map_component)
lemma component_of_map_component [term_simps]: "component_of_term (map_component f v) = f (component_of_term v)" by (simp add: component_of_term_def pair_of_map_component)
lemma map_component_term_of_pair [term_simps]: "map_component f (term_of_pair (t, k)) = term_of_pair (t, f k)" by (simp add: map_component_def term_simps)
lemma map_component_comp: "map_component f (map_component g x) = map_component (λk. f (g k)) x" by (simp add: map_component_def term_simps)
lemma map_component_id [term_simps]: "map_component (λk. k) x = x" by (simp add: map_component_def term_simps)
lemma map_component_inj: assumes"inj f"and"map_component f u = map_component f v" shows"u = v" proof - from assms(2) have"term_of_pair (pp_of_term u, f (component_of_term u)) = term_of_pair (pp_of_term v, f (component_of_term v))" by (simp only: map_component_def) hence"(pp_of_term u, f (component_of_term u)) = (pp_of_term v, f (component_of_term v))" by (rule term_of_pair_injective) hence1: "pp_of_term u = pp_of_term v"and"f (component_of_term u) = f (component_of_term v)"by simp_all from assms(1) this(2) have"component_of_term u = component_of_term v"by (rule injD) with1show ?thesis by (metis term_of_pair_pair) qed
end(* ordered_term *)
subsection‹Gr\"obner Bases of Syzygy Modules›
locale gd_inf_term =
gd_term pair_of_term term_of_pair ord ord_strict ord_term ord_term_strict for pair_of_term::"'t ==> ('a::graded_dickson_powerprod × nat)" and term_of_pair::"('a × nat) ==> 't" and ord::"'a ==> 'a ==> bool" (infixl‹⪯›50) and ord_strict (infixl‹≺›50) and ord_term::"'t ==> 't ==> bool" (infixl‹⪯t›50) and ord_term_strict::"'t ==> 't ==> bool" (infixl‹≺t›50) begin
text‹In order to compute a Gr\"obner basis of the syzygy module of a list ‹bs› of polynomials, one
first needs to ``lift'' ‹bs› to a new list ‹bs'› by adding further components, compute a Gr\"obner
basis ‹gs› of ‹bs'›, and then filter out those elements of ‹gs› whose only non-zero components are
those that were newly added to ‹bs›.
Function ‹init_syzygy_list› takes care of constructing ‹bs'›, and function ‹filter_syzygy_basis›
does the filtering. Function ‹proj_orig_basis›, finally, projects the Gr\"obner basis ‹gs› of ‹bs'›
to a Gr\"obner basis of the original list ‹bs›.›
definition lift_poly_syz :: "nat ==> ('t ==>0 'b) ==> nat ==> ('t ==>0 'b::semiring_1)" where"lift_poly_syz n b i = Abs_poly_mapping (λx. if pair_of_term x = (0, i) then 1 else if n ≤ component_of_term x then lookup b (map_component (λk. k - n) x) else 0)"
definition proj_poly_syz :: "nat ==> ('t ==>0 'b) ==> ('t ==>0 'b::semiring_1)" where"proj_poly_syz n b = Poly_Mapping.map_key (λx. map_component (λk. k + n) x) b"
definition cofactor_list_syz :: "nat ==> ('t ==>0 'b) ==> ('a ==>0 'b::semiring_1) list" where"cofactor_list_syz n b = map (λi. proj_poly i b) [0..<n]"
lemma keys_lift_poly_syz_aux: "{x. (if pair_of_term x = (0, i) then 1 else if n ≤ component_of_term x then lookup b (map_component (λk. k - n) x) else 0) ≠ 0} ⊆ insert (term_of_pair (0, i)) (map_component (λk. k + n) ` keys b)"
(is"?l ⊆ ?r") for b::"'t ==>0 'b::semiring_1" proof fix x::'t assume"x ∈ ?l" hence"(if pair_of_term x = (0, i) then 1 else if n ≤ component_of_term x then lookup b (map_component (λk. k - n) x) else 0) ≠ 0" by simp hence"pair_of_term x = (0, i) ∨ (n ≤ component_of_term x ∧ lookup b (map_component (λk. k - n) x) ≠ 0)" by (simp split: if_split_asm) thus"x ∈ ?r" proof assume"pair_of_term x = (0, i)" hence"(0, i) = pair_of_term x"by (rule sym) hence"x = term_of_pair (0, i)"by (simp add: term_pair) thus ?thesis by simp next assume"n ≤ component_of_term x ∧ lookup b (map_component (λk. k - n) x) ≠ 0" hence"n ≤ component_of_term x"and2: "map_component (λk. k - n) x ∈ keys b" by (auto simp: in_keys_iff) from this(1) have3: "map_component (λk. k - n + n) x = x"by (simp add: map_component_def term_simps) from2have"map_component (λk. k + n) (map_component (λk. k - n) x) ∈ map_component (λk. k + n) ` keys b" by (rule imageI) with3have"x ∈ map_component (λk. k + n) ` keys b"by (simp add: map_component_comp) thus ?thesis by simp qed qed
lemma lookup_lift_poly_syz: "lookup (lift_poly_syz n b i) = (λx. if pair_of_term x = (0, i) then 1 else if n ≤ component_of_term x then lookup b (map_component (λk. k - n) x) else 0)" unfolding lift_poly_syz_def proof (rule Abs_poly_mapping_inverse) from finite_keys have"finite (map_component (λk. k + n) ` keys b)" .. hence"finite (insert (term_of_pair (0, i)) (map_component (λk. k + n) ` keys b))"by (rule finite.insertI) with keys_lift_poly_syz_aux have"finite {x. (if pair_of_term x = (0, i) then 1 else if n ≤ component_of_term x then lookup b (map_component (λk. k - n) x) else 0) ≠ 0}" by (rule finite_subset) thus"(λx. if pair_of_term x = (0, i) then 1 else if n ≤ component_of_term x then lookup b (map_component (λk. k - n) x) else 0) ∈ {f. finite {x. f x ≠ 0}}"by simp qed
corollary lookup_lift_poly_syz_alt: "lookup (lift_poly_syz n b i) (term_of_pair (t, j)) = (if (t, j) = (0, i) then 1 else if n ≤ j then lookup b (term_of_pair (t, j - n)) else 0)" by (simp only: lookup_lift_poly_syz term_simps)
lemma keys_lift_poly_syz: "keys (lift_poly_syz n b i) = insert (term_of_pair (0, i)) (map_component (λk. k + n) ` keys b)" proof have"keys (lift_poly_syz n b i) ⊆ {x. (if pair_of_term x = (0, i) then 1 else if n ≤ component_of_term x then lookup b (map_component (λk. k - n) x) else 0) ≠ 0}"
(is"_ ⊆ ?A") proof fix x assume"x ∈ keys (lift_poly_syz n b i)" hence"lookup (lift_poly_syz n b i) x ≠ 0"by (simp add: in_keys_iff) thus"x ∈ ?A"by (simp add: lookup_lift_poly_syz) qed alsonote keys_lift_poly_syz_aux finallyshow"keys (lift_poly_syz n b i) ⊆ insert (term_of_pair (0, i)) (map_component (λk. k + n) ` keys b)" . next show"insert (term_of_pair (0, i)) (map_component (λk. k + n) ` keys b) ⊆ keys (lift_poly_syz n b i)" proof (simp, rule) have"lookup (lift_poly_syz n b i) (term_of_pair (0, i)) ≠ 0"by (simp add: lookup_lift_poly_syz_alt) thus"term_of_pair (0, i) ∈ keys (lift_poly_syz n b i)"by (simp add: in_keys_iff) next show"map_component (λk. k + n) ` keys b ⊆ keys (lift_poly_syz n b i)" proof (rule, elim imageE, simp) fix x assume"x ∈ keys b" hence"lookup (lift_poly_syz n b i) (map_component (λk. k + n) x) ≠ 0" by (simp add: in_keys_iff lookup_lift_poly_syz_alt map_component_def term_simps) thus"map_component (λk. k + n) x ∈ keys (lift_poly_syz n b i)"by (simp add: in_keys_iff) qed qed qed
subsubsection‹@{const proj_poly_syz}›
lemma inj_map_component_plus: "inj (map_component (λk. k + n))" proof (rule injI) fix x y have"inj (λk::nat. k + n)"by (simp add: inj_def) moreoverassume"map_component (λk. k + n) x = map_component (λk. k + n) y" ultimatelyshow"x = y"by (rule map_component_inj) qed
lemma lookup_proj_poly_syz: "lookup (proj_poly_syz n p) x = lookup p (map_component (λk. k + n) x)" by (simp add: proj_poly_syz_def map_key.rep_eq[OF inj_map_component_plus])
lemma lookup_proj_poly_syz_alt: "lookup (proj_poly_syz n p) (term_of_pair (t, i)) = lookup p (term_of_pair (t, i + n))" by (simp add: lookup_proj_poly_syz map_component_term_of_pair)
lemma keys_proj_poly_syz: "keys (proj_poly_syz n p) = map_component (λk. k + n) -` keys p" by (simp add: proj_poly_syz_def keys_map_key[OF inj_map_component_plus])
lemma proj_poly_syz_zero [simp]: "proj_poly_syz n 0 = 0" by (rule poly_mapping_eqI, simp add: lookup_proj_poly_syz)
lemma proj_poly_syz_plus: "proj_poly_syz n (p + q) = proj_poly_syz n p + proj_poly_syz n q" by (simp add: proj_poly_syz_def map_key_plus[OF inj_map_component_plus])
lemma proj_poly_syz_sum: "proj_poly_syz n (sum f A) = (∑a∈A. proj_poly_syz n (f a))" by (rule fun_sum_commute, simp_all add: proj_poly_syz_plus)
lemma proj_poly_syz_sum_list: "proj_poly_syz n (sum_list xs) = sum_list (map (proj_poly_syz n) xs)" by (rule fun_sum_list_commute, simp_all add: proj_poly_syz_plus)
lemma proj_poly_syz_monom_mult: "proj_poly_syz n (monom_mult c t p) = monom_mult c t (proj_poly_syz n p)" by (rule poly_mapping_eqI,
simp add: lookup_proj_poly_syz lookup_monom_mult term_simps adds_pp_def sminus_def)
lemma proj_poly_syz_mult_scalar: "proj_poly_syz n (mult_scalar q p) = mult_scalar q (proj_poly_syz n p)" by (rule fun_mult_scalar_commute, simp_all add: proj_poly_syz_plus proj_poly_syz_monom_mult)
lemma proj_poly_syz_lift_poly_syz: assumes"i < n" shows"proj_poly_syz n (lift_poly_syz n p i) = p" proof (rule poly_mapping_eqI, simp add: lookup_proj_poly_syz lookup_lift_poly_syz term_simps map_component_comp,
rule, elim conjE) fix x::'t assume"component_of_term x + n = i" hence"n ≤ i"by simp with assms show"lookup p x = 1"by simp qed
lemma proj_poly_syz_eq_zero_iff: "proj_poly_syz n p = 0 ⟷ (component_of_term ` keys p ⊆ {0..<n})" unfolding keys_eq_empty[symmetric] keys_proj_poly_syz proof assume"map_component (λk. k + n) -` keys p = {}" (is"?A = {}") show"component_of_term ` keys p ⊆ {0..<n}" proof (rule, rule ccontr) fix i assume"i ∈ component_of_term ` keys p" thenobtain x where x: "x ∈ keys p"and i: "i = component_of_term x" .. assume"i ∉ {0..<n}" hence"i - n + n = i"by simp hence1: "map_component (λk. k - n + n) x = x"by (simp add: map_component_def i term_simps) have"map_component (λk. k - n) x ∈ ?A"by (rule vimageI2, simp add: map_component_comp x 1) thus False by (simp add: ‹?A = {}›) qed next assume a: "component_of_term ` keys p ⊆ {0..<n}" show"map_component (λk. k + n) -` keys p = {}" (is"?A = {}") proof (rule ccontr) assume"?A ≠ {}" thenobtain x where"x ∈ ?A"by blast hence"map_component (λk. k + n) x ∈ keys p"by (rule vimageD) with a have"component_of_term (map_component (λk. k + n) x) ∈ {0..<n}"by blast thus False by (simp add: term_simps) qed qed
lemma component_of_lt_ge: assumes"is_pot_ord"and"proj_poly_syz n p ≠ 0" shows"n ≤ component_of_term (lt p)" proof - from assms(2) have"¬ component_of_term ` keys p ⊆ {0..<n}"by (simp add: proj_poly_syz_eq_zero_iff) thenobtain i where"i ∈ component_of_term ` keys p"and"i ∉ {0..<n}"by fastforce from this(1) obtain x where"x ∈ keys p"and i: "i = component_of_term x" .. from this(1) have"x ⪯t lt p"by (rule lt_max_keys) with assms(1) have"component_of_term x ≤ component_of_term (lt p)"by (rule is_pot_ordD2) with‹i ∉ {0..<n}›show ?thesis by (simp add: i) qed
lemma lt_proj_poly_syz: assumes"is_pot_ord"and"proj_poly_syz n p ≠ 0" shows"lt (proj_poly_syz n p) = map_component (λk. k - n) (lt p)" (is"_ = ?l") proof - from component_of_lt_ge[OF assms] have"component_of_term (lt p) - n + n = component_of_term (lt p)"by simp hence eq: "map_component (λk. k - n + n) (lt p) = lt p"by (simp add: map_component_def term_simps) show ?thesis proof (rule lt_eqI) have"lookup (proj_poly_syz n p) ?l = lc p" by (simp add: lc_def lookup_proj_poly_syz term_simps map_component_comp eq) alsohave"... ≠ 0" proof (rule lc_not_0, rule) assume"p = 0" hence"proj_poly_syz n p = 0"by simp with assms(2) show False .. qed finallyshow"lookup (proj_poly_syz n p) ?l ≠ 0" . next fix x assume"lookup (proj_poly_syz n p) x ≠ 0" hence"map_component (λk. k + n) x ∈ keys p"by (simp add: in_keys_iff lookup_proj_poly_syz) hence"map_component (λk. k + n) x ⪯t lt p"by (rule lt_max_keys) with assms(1) show"x ⪯t ?l"by (auto simp add: is_pot_ord term_simps) qed qed
lemma proj_proj_poly_syz: "proj_poly k (proj_poly_syz n p) = proj_poly (k + n) p" by (rule poly_mapping_eqI, simp add: lookup_proj_poly lookup_proj_poly_syz_alt)
lemma poly_mapping_eqI_proj_syz: assumes"proj_poly_syz n p = proj_poly_syz n q" and"∧k. k < n ==> proj_poly k p = proj_poly k q" shows"p = q" proof (rule poly_mapping_eqI_proj) fix k show"proj_poly k p = proj_poly k q" proof (cases "k < n") case True thus ?thesis by (rule assms(2)) next case False have"proj_poly (k - n + n) p = proj_poly (k - n + n) q" by (simp only: proj_proj_poly_syz[symmetric] assms(1)) with False show ?thesis by simp qed qed
subsubsection‹@{const cofactor_list_syz}›
lemma length_cofactor_list_syz [simp]: "length (cofactor_list_syz n p) = n" by (simp add: cofactor_list_syz_def)
lemma cofactor_list_syz_nth: assumes"i < n" shows"(cofactor_list_syz n p) ! i = proj_poly i p" by (simp add: cofactor_list_syz_def map_idx_nth assms)
lemma cofactor_list_syz_zero [simp]: "cofactor_list_syz n 0 = replicate n 0" by (rule nth_equalityI, simp_all add: cofactor_list_syz_nth proj_zero)
lemma cofactor_list_syz_plus: "cofactor_list_syz n (p + q) = map2 (+) (cofactor_list_syz n p) (cofactor_list_syz n q)" by (rule nth_equalityI, simp_all add: cofactor_list_syz_nth proj_plus)
lemma proj_lift_poly_syz: assumes"j < n" shows"proj_poly j (lift_poly_syz n p i) = (1 when j = i)" proof (simp add: when_def, intro conjI impI) assume"j = i" with assms have"¬ n ≤ i"by simp show"proj_poly i (lift_poly_syz n p i) = 1" by (rule poly_mapping_eqI, simp add: lookup_proj_poly lookup_lift_poly_syz_alt ‹¬ n ≤ i› lookup_one) next assume"j ≠ i" from assms have"¬ n ≤ j"by simp show"proj_poly j (lift_poly_syz n p i) = 0" by (rule poly_mapping_eqI, simp add: lookup_proj_poly lookup_lift_poly_syz_alt ‹¬ n ≤ j›‹j ≠ i›) qed
subsubsection‹@{const proj_orig_basis}›
lemma length_proj_orig_basis [simp]: "length (proj_orig_basis n bs) = length bs" by (simp add: proj_orig_basis_def)
lemma proj_orig_basis_nth: assumes"i < length bs" shows"(proj_orig_basis n bs) ! i = proj_poly_syz n (bs ! i)" by (simp add: proj_orig_basis_def assms)
lemma set_proj_orig_basis: "set (proj_orig_basis n bs) = proj_poly_syz n ` set bs" by (simp add: proj_orig_basis_def)
text‹The following lemma could be generalized from @{const proj_poly_syz} to arbitrary module homomorphisms,
i.\,e. functions respecting ‹0›, addition and scalar multiplication.› lemma pmdl_proj_orig_basis': "pmdl (set (proj_orig_basis n bs)) = proj_poly_syz n ` pmdl (set bs)" (is"?A = ?B") proof show"?A ⊆ ?B" proof fix p assume"p ∈ pmdl (set (proj_orig_basis n bs))" thus"p ∈ proj_poly_syz n ` pmdl (set bs)" proof (induct rule: pmdl_induct) case module_0 have"0 = proj_poly_syz n 0"by simp alsofrom pmdl.span_zero have"... ∈ proj_poly_syz n ` pmdl (set bs)"by (rule imageI) finallyshow ?case . next case (module_plus p b c t) from module_plus(2) obtain q where"q ∈ pmdl (set bs)"and p: "p = proj_poly_syz n q" .. from module_plus(3) obtain a where"a ∈ set bs"and b: "b = proj_poly_syz n a" unfolding set_proj_orig_basis .. have"p + monom_mult c t b = proj_poly_syz n (q + monom_mult c t a)" by (simp add: p b proj_poly_syz_monom_mult proj_poly_syz_plus) alsohave"... ∈ proj_poly_syz n ` pmdl (set bs)" proof (rule imageI, rule pmdl.span_add) show"monom_mult c t a ∈ pmdl (set bs)" by (rule pmdl_closed_monom_mult, rule pmdl.span_base, fact) qed fact finallyshow ?case . qed qed next show"?B ⊆ ?A" proof fix p assume"p ∈ proj_poly_syz n ` pmdl (set bs)" thenobtain q where"q ∈ pmdl (set bs)"and p: "p = proj_poly_syz n q" .. from this(1) show"p ∈ pmdl (set (proj_orig_basis n bs))"unfolding p proof (induct rule: pmdl_induct) case module_0 have"proj_poly_syz n 0 = 0"by simp alsohave"... ∈ pmdl (set (proj_orig_basis n bs))"by (fact pmdl.span_zero) finallyshow ?case . next case (module_plus q b c t) have"proj_poly_syz n (q + monom_mult c t b) = proj_poly_syz n q + monom_mult c t (proj_poly_syz n b)" by (simp add: proj_poly_syz_plus proj_poly_syz_monom_mult) alsohave"... ∈ pmdl (set (proj_orig_basis n bs))" proof (rule pmdl.span_add) show"monom_mult c t (proj_poly_syz n b) ∈ pmdl (set (proj_orig_basis n bs))" proof (rule pmdl_closed_monom_mult, rule pmdl.span_base) show"proj_poly_syz n b ∈ set (proj_orig_basis n bs)" by (simp add: set_proj_orig_basis, rule imageI, fact) qed qed fact finallyshow ?case . qed qed qed
subsubsection‹@{const filter_syzygy_basis}›
lemma filter_syzygy_basis_alt: "filter_syzygy_basis n bs = [b←bs. proj_poly_syz n b = 0]" by (simp add: filter_syzygy_basis_def proj_poly_syz_eq_zero_iff)
lemma set_filter_syzygy_basis: "set (filter_syzygy_basis n bs) = {b∈set bs. proj_poly_syz n b = 0}" by (simp add: filter_syzygy_basis_alt)
lemma syzygy_module_listE: assumes"s ∈ syzygy_module_list bs" obtains s' where"s' ∈ pmdl.syzygy_module (set bs)"and"s = atomize_poly (idx_pm_of_pm bs s')" using assms unfolding syzygy_module_list_def by (elim imageE, simp)
lemma monom_mult_atomize: "monom_mult c t (atomize_poly p) = atomize_poly (MPoly_Type_Class.punit.monom_mult (monomial c t) 0 p)" by (rule poly_mapping_eqI_proj, simp add: proj_monom_mult proj_atomize_poly
MPoly_Type_Class.punit.lookup_monom_mult times_monomial_left)
lemma punit_monom_mult_monomial_idx_pm_of_pm: "MPoly_Type_Class.punit.monom_mult (monomial c t) (0::nat) (idx_pm_of_pm bs s) = idx_pm_of_pm bs (MPoly_Type_Class.punit.monom_mult (monomial c t) (0::'t ==>0 'b::ring_1) s)" by (rule poly_mapping_eqI, simp add: MPoly_Type_Class.punit.lookup_monom_mult lookup_idx_pm_of_pm when_def)
lemma syzygy_module_list_closed_monom_mult: assumes"s ∈ syzygy_module_list bs" shows"monom_mult c t s ∈ syzygy_module_list bs" proof - from assms obtain s' where s': "s' ∈ pmdl.syzygy_module (set bs)" and s: "s = atomize_poly (idx_pm_of_pm bs s')"by (rule syzygy_module_listE) show ?thesis unfolding s proof (rule syzygy_module_listI) from s' show"(monomial c t) ⋅ s' ∈ pmdl.syzygy_module (set bs)" by (rule syzygy_module_closed_map_scale) next show"monom_mult c t (atomize_poly (idx_pm_of_pm bs s')) = atomize_poly (idx_pm_of_pm bs ((monomial c t) ⋅ s'))" by (simp add: monom_mult_atomize punit_monom_mult_monomial_idx_pm_of_pm
MPoly_Type_Class.punit.map_scale_eq_monom_mult) qed qed
lemma pmdl_syzygy_module_list [simp]: "pmdl (syzygy_module_list bs) = syzygy_module_list bs" proof (rule pmdl_idI) show"0 ∈ syzygy_module_list bs" by (rule syzygy_module_listI, fact pmdl.zero_in_syzygy_module, simp add: atomize_zero) next fix s1 s2 assume"s1 ∈ syzygy_module_list bs" thenobtain s1' where s1': "s1' ∈ pmdl.syzygy_module (set bs)" and s1: "s1 = atomize_poly (idx_pm_of_pm bs s1')"by (rule syzygy_module_listE) assume"s2 ∈ syzygy_module_list bs" thenobtain s2' where s2': "s2' ∈ pmdl.syzygy_module (set bs)" and s2: "s2 = atomize_poly (idx_pm_of_pm bs s2')"by (rule syzygy_module_listE) show"s1 + s2 ∈ syzygy_module_list bs" proof (rule syzygy_module_listI) from s1' s2' show"s1' + s2' ∈ pmdl.syzygy_module (set bs)" by (rule pmdl.syzygy_module_closed_plus) next show"s1 + s2 = atomize_poly (idx_pm_of_pm bs (s1' + s2'))" by (simp add: idx_pm_of_pm_plus atomize_plus s1 s2) qed qed (fact syzygy_module_list_closed_monom_mult)
text‹The following lemma also holds without the distinctness constraint on ‹bs›, but then the
proof becomes more difficult.› lemma syzygy_module_listI': assumes"distinct bs"and"sum_list (map2 mult_scalar (cofactor_list_syz (length bs) s) bs) = 0" and"component_of_term ` keys s ⊆ {0..<length bs}" shows"s ∈ syzygy_module_list bs" proof (rule syzygy_module_listI) show"pm_of_idx_pm bs (vectorize_poly s) ∈ pmdl.syzygy_module (set bs)" proof (rule pmdl.syzygy_moduleI, rule pmdl.representsI) have"(∑v∈keys (pm_of_idx_pm bs (vectorize_poly s)). mult_scalar (lookup (pm_of_idx_pm bs (vectorize_poly s)) v) v) = (∑b∈set bs. mult_scalar (lookup (pm_of_idx_pm bs (vectorize_poly s)) b) b)" by (rule sum.mono_neutral_left, fact finite_set, fact keys_pm_of_idx_pm_subset, simp add: in_keys_iff) alsohave"... = sum_list (map (λb. mult_scalar (lookup (pm_of_idx_pm bs (vectorize_poly s)) b) b) bs)" by (simp only: sum_code distinct_remdups_id[OF assms(1)]) alsohave"... = sum_list (map2 mult_scalar (cofactor_list_syz (length bs) s) bs)" proof (rule arg_cong[of _ _ sum_list], rule nth_equalityI, simp_all) fix i assume"i < length bs" with assms(1) have"lookup (pm_of_idx_pm bs (vectorize_poly s)) (bs ! i) = cofactor_list_syz (length bs) s ! i" by (simp add: lookup_pm_of_idx_pm_distinct[OF assms(1)] cofactor_list_syz_nth lookup_vectorize_poly) thus"mult_scalar (lookup (pm_of_idx_pm bs (vectorize_poly s)) (bs ! i)) (bs ! i) = mult_scalar (cofactor_list_syz (length bs) s ! i) (bs ! i)"by (simp only:) qed alsohave"... = 0"by (fact assms(2)) finallyshow"pmdl.rep (pm_of_idx_pm bs (vectorize_poly s)) = 0"by (simp only: pmdl.rep_def) qed (fact keys_pm_of_idx_pm_subset) next from assms(3) have"keys (vectorize_poly s) ⊆ {0..<length bs}"by (simp add: keys_vectorize_poly) with assms(1) have"idx_pm_of_pm bs (pm_of_idx_pm bs (vectorize_poly s)) = vectorize_poly s" by (rule idx_pm_of_pm_of_idx_pm) thus"s = atomize_poly (idx_pm_of_pm bs (pm_of_idx_pm bs (vectorize_poly s)))" by (simp add: atomize_vectorize_poly) qed
lemma component_of_syzygy_module_list: assumes"s ∈ syzygy_module_list bs" shows"component_of_term ` keys s ⊆ {0..<length bs}" proof - from assms obtain s' where s: "s = atomize_poly (idx_pm_of_pm bs s')" by (rule syzygy_module_listE) have"component_of_term ` keys s ⊆ (∪x∈{0..<length bs}. {x})" by (simp only: s keys_atomize_poly image_UN, rule UN_mono, fact keys_idx_pm_of_pm_subset, auto simp: term_simps) alsohave"... = {0..<length bs}"by simp finallyshow ?thesis . qed
lemma map2_mult_scalar_proj_poly_syz: "map2 mult_scalar xs (map (proj_poly_syz n) ys) = map (proj_poly_syz n ∘ (λ(x, y). mult_scalar x y)) (zip xs ys)" by (rule nth_equalityI, simp_all add: proj_poly_syz_mult_scalar)
lemma map2_times_proj: "map2 (*) xs (map (proj_poly k) ys) = map (proj_poly k ∘ (λ(x, y). x ⊙ y)) (zip xs ys)" by (rule nth_equalityI, simp_all add: proj_mult_scalar)
text‹Probably the following lemma also holds without the distinctness constraint on ‹bs›.› lemma syzygy_module_list_subset: assumes"distinct bs" shows"syzygy_module_list bs ⊆ pmdl (set (init_syzygy_list bs))" proof let ?as = "init_syzygy_list bs" fix s assume"s ∈ syzygy_module_list bs" thenobtain s' where s': "s' ∈ pmdl.syzygy_module (set bs)" and s: "s = atomize_poly (idx_pm_of_pm bs s')"by (rule syzygy_module_listE) from s' have"pmdl.represents (set bs) s' 0"by (rule pmdl.syzygy_moduleD) hence"keys s' ⊆ set bs"and1: "0 = pmdl.rep s'" by (rule pmdl.representsD1, rule pmdl.representsD2) have"s = sum_list (map2 mult_scalar (cofactor_list_syz (length bs) s) (init_syzygy_list bs))"
(is"_ = ?r") proof (rule poly_mapping_eqI_proj_syz) have"proj_poly_syz (length bs) ?r = sum_list (map2 mult_scalar (cofactor_list_syz (length bs) s) (map (proj_poly_syz (length bs)) (init_syzygy_list bs)))" by (simp add: proj_poly_syz_sum_list map2_mult_scalar_proj_poly_syz) alsohave"... = sum_list (map2 mult_scalar (cofactor_list_syz (length bs) s) bs)" by (simp add: proj_orig_basis_def[symmetric]) alsohave"... = sum_list (map (λb. mult_scalar (lookup s' b) b) bs)" proof (rule arg_cong[of _ _ sum_list], rule nth_equalityI, simp_all) fix i assume"i < length bs" with assms(1) have"lookup s' (bs ! i) = cofactor_list_syz (length bs) s ! i" by (simp add: s cofactor_list_syz_nth lookup_idx_pm_of_pm proj_atomize_poly) thus"mult_scalar (cofactor_list_syz (length bs) s ! i) (bs ! i) = mult_scalar (lookup s' (bs ! i)) (bs ! i)"by (simp only:) qed alsohave"... = (∑b∈set bs. mult_scalar (lookup s' b) b)" by (simp only: sum_code distinct_remdups_id[OF assms]) alsohave"... = (∑v∈keys s'. mult_scalar (lookup s' v) v)" by (rule sum.mono_neutral_right, fact finite_set, fact, simp add: in_keys_iff) alsohave"... = 0"by (simp add: 1 pmdl.rep_def) finallyhave eq: "proj_poly_syz (length bs) ?r = 0" . show"proj_poly_syz (length bs) s = proj_poly_syz (length bs) ?r" by (simp add: eq ‹s ∈ syzygy_module_list bs› proj_poly_syz_eq_zero_iff component_of_syzygy_module_list) next fix k assume"k < length bs" have"proj_poly k s = map2 (*) (cofactor_list_syz (length bs) s) (map (proj_poly k) (init_syzygy_list bs)) ! k" by (simp add: ‹k < length bs› init_syzygy_list_nth proj_lift_poly_syz cofactor_list_syz_nth) alsohave"... = sum_list (map2 (*) (cofactor_list_syz (length bs) s) (map (proj_poly k) (init_syzygy_list bs)))" by (rule sum_list_eq_nthI[symmetric],
simp_all add: ‹k < length bs› init_syzygy_list_nth proj_lift_poly_syz) alsohave"... = proj_poly k ?r" by (simp add: proj_sum_list map2_times_proj) finallyshow"proj_poly k s = proj_poly k ?r" . qed alsohave"…∈ pmdl (set (init_syzygy_list bs))"by (fact pmdl.span_listI) finallyshow"s ∈ pmdl (set (init_syzygy_list bs))" . qed
lemma syz_cofactors: assumes"p ∈ pmdl (set (init_syzygy_list bs))" shows"proj_poly_syz (length bs) p = sum_list (map2 mult_scalar (cofactor_list_syz (length bs) p) bs)" using assms proof (induct rule: pmdl_induct) case module_0 show ?caseby (simp, rule sum_list_zeroI', simp) next case (module_plus p b c t) from this(3) obtain i where i: "i < length bs"and b: "b = (init_syzygy_list bs) ! i" unfolding length_init_syzygy_list[symmetric, of bs] by (metis in_set_conv_nth) have"proj_poly_syz (length bs) (p + monom_mult c t b) = proj_poly_syz (length bs) p + monom_mult c t (bs ! i)" by (simp only: proj_poly_syz_plus proj_poly_syz_monom_mult b init_syzygy_list_nth[OF i]
proj_poly_syz_lift_poly_syz[OF i]) alsohave"... = sum_list (map2 mult_scalar (cofactor_list_syz (length bs) p) bs) + monom_mult c t (bs ! i)"by (simp only: module_plus(2)) alsohave"... = sum_list (map2 mult_scalar (cofactor_list_syz (length bs) (p + monom_mult c t b)) bs)" proof (simp add: cofactor_list_syz_plus map2_mult_scalar_plus sum_list_map2_plus) have proj_b: "j < length bs ==> proj_poly j b = (1 when j = i)"for j by (simp add: b init_syzygy_list_nth i proj_lift_poly_syz) have eq: "j < length bs ==> (map2 mult_scalar (cofactor_list_syz (length bs) (monom_mult c t b)) bs) ! j = (monom_mult c t (bs ! i) when j = i)"for j by (simp add: cofactor_list_syz_nth proj_monom_mult proj_b mult_scalar_monom_mult when_def) have"sum_list (map2 mult_scalar (cofactor_list_syz (length bs) (monom_mult c t b)) bs) = (map2 mult_scalar (cofactor_list_syz (length bs) (monom_mult c t b)) bs) ! i" by (rule sum_list_eq_nthI, simp add: i, simp add: eq del: nth_zip nth_map) alsohave"... = mult_scalar (punit.monom_mult c t (proj_poly i b)) (bs ! i)" by (simp add: i cofactor_list_syz_nth proj_monom_mult) alsohave"... = monom_mult c t (bs ! i)" by (simp add: proj_b i mult_scalar_monomial times_monomial_left[symmetric]) finallyshow"monom_mult c t (bs ! i) = sum_list (map2 mult_scalar (cofactor_list_syz (length bs) (monom_mult c t b)) bs)" by (simp only:) qed finallyshow ?case . qed
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.