Up to index of Isabelle/HOL/HOL-Algebra/example_Bicomplex
theory BPL_classes_2008(* Title: code_generation/BPL_classes_2008.thy ID: $Id: BPL_classes_Isabelle2008.thy $ Author: Jesus Aransay *) theory BPL_classes_2008 imports Basic_Perturbation_Lemma_local_nilpot While begin section{*Additional type classes*} text{*In this section we introduce some additional type classes to those provided by the Isabelle standard distribution*} text{*For instance, we need a class @{term diff_group_add} that can be defined from the @{term ab_group_add} type class from the Isabelle library:*} class diff_group_add = ab_group_add + fixes diff :: "'a => 'a" ("d _" [81] 80) assumes diff_hom: "d (x + y) = (d x) + (d y)" and diff_nilpot: "diff o diff = (λx. 0)" lemma (in diff_group_add) [simp]: "d (d x) = 0" using diff_nilpot unfolding expand_fun_eq by simp text{*According to the previous syntax definitions, @{term [locale=diff_group_add] "(λx. d x)"} is to be used with the parameter over which it is applied, and @{term [locale=diff_group_add] diff} remains to be used as a function*} text{*We can indeed prove instances of the specified type classes. An instance of a type class makes the type class sound.*} instantiation int :: diff_group_add begin definition diff_int_def: "diff ≡ (λx. 0::int)" instance proof show "diff o diff = (λx::int. 0)" unfolding diff_int_def unfolding expand_fun_eq by simp fix x y ::int show "d (x + y) = (d x) + (d y)" unfolding diff_int_def by arith qed end text{*A limitation of type classes can be observed in the following definition; using the @{term "op +"} symbol for @{term "fun"} is not possible. In a type class definition, symbols only refer to the type class being defined.*} text{*The following type class definition is not valid; the + operation can only be used for the type class being defined*} (*class diff_group_add_pert = diff_group_add + fixes pert :: "'a => 'a" ("δ _" [81] 80) assumes pert_hom_ab: "δ (a + b) = δ a + δ b" and pert_preserv_diff_group_add: "diff_group_add (op -) (λx. - x) 0 (op +) (diff + pert)"*) text{*The following type class represents a differential group and a perturbation over it.*} class diff_group_add_pert = diff_group_add + fixes pert :: "'a => 'a" ("δ _" [81] 80) assumes pert_hom_ab: "δ (a + b) = δ a + δ b" and pert_preserv_diff_group_add: "diff_group_add (op -) (λx. - x) 0 (op +) (λx. d x + δ x)" instantiation int :: diff_group_add_pert begin definition pert_int_def: "pert ≡ (λx. 0::int)" instance proof fix a b :: int show "δ (a + b) = δ a + δ b" unfolding pert_int_def by simp next show "diff_group_add op - uminus (0::int) op + (λx. d x + δ x)" unfolding diff_group_add_def unfolding diff_group_add_axioms_def proof (intro conjI) show " ab_group_add op - uminus (0::int) op +" by intro_locales next show "∀x (y::int). d (x + y) + δ (x + y) = d x + δ x + (d y + δ y)" proof (rule allI)+ fix a b :: int show "d (a + b) + δ (a + b) = d a + δ a + (d b + δ b)" unfolding diff_int_def unfolding pert_int_def by arith qed next show "(λx::int. d x + δ x) o (λx. d x + δ x) = (λx. 0)" unfolding diff_int_def unfolding pert_int_def by (simp add: expand_fun_eq) qed qed end text{*We now prove some facts about generic functions. With appropriate restrictions over the type classes over which they are defined, functions can be proved to be also instances of some type classes.*} instantiation "fun" :: (ab_semigroup_add, ab_semigroup_add) ab_semigroup_add begin definition plus_fun_def: "f + g == (%x. f x + g x)" instance proof fix x y z :: "'a => 'b" show "x + y + z = x + (y + z)" unfolding plus_fun_def by (auto simp add: add_assoc) next fix x y :: "'a => 'b" show "x + y = y + x" unfolding plus_fun_def by (auto simp add: add_commute) qed end instantiation "fun" :: (comm_monoid_add, comm_monoid_add) comm_monoid_add begin definition zero_fun_def: "0 == (λx. 0)" instance proof fix a :: "'a => 'b" show "0 + a = a" unfolding zero_fun_def plus_fun_def by simp qed end text{*The Isabelle release 2008 already contains the definition of the difference of functions and also the unary minus*} instantiation "fun" :: (ab_group_add, ab_group_add) ab_group_add begin instance proof fix a :: "'a => 'b" show "- a + a = 0" unfolding fun_Compl_def unfolding zero_fun_def unfolding plus_fun_def by simp next fix a b :: "'a => 'b" show "a - b = a + - b" unfolding plus_fun_def unfolding fun_diff_def unfolding fun_Compl_def by (simp add: expand_fun_eq) qed end text{*The following type class specifies a differential group with a perturbation and also a homotopy operator.*} text{*The previous fact about the @{text "fun"} datatype contructor allows us now to use @{term "op -"} to define @{text α} in a more readable way*} class diff_group_add_pert_hom = diff_group_add_pert + fixes hom_oper:: "'a => 'a" ("h _" [81] 80) assumes h_hom_ab: "h (a + b) = h a + h b" and h_nilpot: "(λx. h x) o (λx. h x) = (λx. 0)" begin definition α :: "'a => 'a" where "α = (λx. - (pert (hom_oper x)))" end instantiation int :: diff_group_add_pert_hom begin definition hom_oper_int_def: "hom_oper ≡ (λx. 0::int)" instance proof fix a b :: int show "h (a + b) = h a + h b" unfolding hom_oper_int_def by arith next show "(λx. h x) o (λx. h x) = (λx::int. 0)" unfolding hom_oper_int_def unfolding expand_fun_eq by auto qed end lemma [code]: shows "α = (- ((λ x. δ x) o (λx. h x)))" unfolding α_def unfolding fun_Compl_def by simp section{*Local nilpotency*} text{*We add now the notion of @{text "local_bounded_func"}in a purely \emph{existential} way; from the existential definition we will later define the function providing this local bound for every x.*} text{*The reason to introduce now this notion is that @{term α} is the function verifying the local nilpotency condition*} context ab_group_add begin definition local_bounded_func :: "('a => 'a) => bool" where "local_bounded_func f = (∀ x. ∃ n. (f^n) x = 0)" text{*Here is a relevant difference with the previous proof of the BPL; there, the local bound was defined as the Least natural number @{term "n::nat"} satisfying the property @{term [locale=diff_group_add_pert_hom] "(α^n) (x::'a) = 0"}. Now, in our attempt to make this definition computable, or executable, we define it as an iterating structure (a \emph{For} loop), where the boolean condition in the loop is expressed as @{term [locale=ab_group_add] "(λ y. y ≠ 0)"}*} text{*Later we will try to apply the code generator over these definitions*} definition local_bound_gen :: "('a => 'a) => 'a => nat => nat" where "local_bound_gen f x n == For (λ y. y ≠ 0) f (λ y n. n + (1::nat)) x n" definition local_bound:: "('a => 'a) => 'a => nat" where "local_bound f x = local_bound_gen f x 0" end text{* We now define the simplification rule for @{term "local_bound_gen"}: *} lemmas local_bound_gen_simp = For_simp[of "(λ y. y ≠ (0::'a::ab_group_add))" _ "λ y n. n+(1::nat)", simplified local_bound_gen_def[symmetric]] text{*Two simple "calculations" with @{term "local_bound"}: *} lemma "local_bound f 0 = 0" unfolding local_bound_def unfolding local_bound_gen_simp [of f 0 0] by simp lemma "x ≠ 0 ==> local_bound (λ x. 0) x = 1" unfolding local_bound_def using local_bound_gen_simp by simp text{*Now, we connect the neccesary termination of For with our termination condition, @{term local_bounded_func}. *} text{*Then, under the @{term local_bounded_func} premise the loop will be terminating.*} lemma local_bounded_func_impl_terminates_loop: "local_bounded_func f = (∀ x. terminates (λ y. y ≠ 0, f, x))" unfolding local_bounded_func_def unfolding terminates_simp unfolding Orbit_def by simp lemma LEAST_local_bound_0: "(LEAST n::nat. (f ^ n) (0::'a::ab_group_add) = (0::'a)) = 0" using Least_le [of "λn. (f ^n) 0 = 0" 0] by simp lemma local_bound_gen_correct: "terminates (λ y. y ≠ (0::'a::ab_group_add), f, x) ==> local_bound_gen f x m = m + (LEAST n::nat. (f^n) x = 0)" apply (rule For_pinduct[where i=x and s=m and Ac="λ y n. n+1"]) apply simp apply (subst local_bound_gen_simp) apply (case_tac "i = 0") apply (simp add: LEAST_local_bound_0) apply simp apply (frule_tac x=i in terminates_implies) apply (frule_tac i=i in terminates_imp) apply simp apply (frule_tac x="f i" in terminates_implies) apply auto apply (rule Least_Suc2[symmetric]) apply (auto simp add: funpow_zip) done text{*The following lemma exactly represents the difference between our old definitions, with which we proved the BPL, and the new ones, from which we are trying to generate code; under the termination premise, both @{term "(LEAST n::nat. (f^n) (x::'a::ab_group_add) = 0)"}, the old definition of local nilpotency, and @{term [locale=ab_group_add] "local_bound f x"}, the loop computing the lower bound, are equivalent*} text{*Whereas @{term "(LEAST n::nat. (f^n) (x::'a::ab_group_add) = 0)"} does not have a computable interpretation, @{term [locale=ab_group_add] "local_bound f x"} does have it, and code can be generated from it.*} lemma local_bound_correct: "terminates (λ y. y ≠ (0::'a::ab_group_add), f, x) ==> local_bound f x = (LEAST n::nat. (f^n) x = 0)" unfolding local_bound_def unfolding local_bound_gen_correct [of f x 0] by arith lemma local_bounded_func_impl_local_bound_is_Least: assumes lbf_f:"local_bounded_func f" shows "local_bound f x = (LEAST n::nat. (f^n) x = 0)" using lbf_f unfolding local_bounded_func_impl_terminates_loop [OF ] using local_bound_correct [of f x] .. text{* Both @{term "local_bound"} and @{term "terminates"} are executable.*} text{*This is another possible definition of our iterative process as a tail recursion, instead of using @{term While}, suggested by Alexander Krauss; code generation is also possible from this definition.*} text{*A good motivation to use the @{term While} operator instead of this one, is that some additional induction principles have been provided for the @{term For} and @{term While} operators.*} function (tailrec) local_bound' :: "('a::zero => 'a) => 'a => nat => nat" where "local_bound' f x n = (if (f^n) x = 0 then n else local_bound' f x (Suc n))" by pat_completeness auto lemma [code func]: "local_bound' f (x::'a::zero) n = (if (f^n) x = 0 then n else local_bound' f x (Suc n))" by simp export_code local_bound' in SML file "local_bound.ML" lemma [code func]: "While continue f s = (if continue s then While continue f (f s) else s)" unfolding While_simp [of continue f s] .. export_code While in SML file "Loop.ML" export_code local_bound in SML file "local_bound2.ML" section{*Finite sums*} text{*The following definition of @{term fin_sum} will replace the definitions for sums of series used in the formal proof of the BPL.*} text{*That definitions were based on the fold operator over sets, from which direct code generation cannot be obtained.*} text{*The finite sum of a series is defined as a primitive recursive function over the natural numbers.*} text{*This definition will have to be proved later equivalent, in our setting, to the sums appearing in the BPL proof.*} primrec fin_sum :: "(('a::ab_group_add) => 'a) => nat => ('a => 'a)" where "fin_sum f 0 =id" | "fin_sum f (Suc n) = f^(Suc n) + (fin_sum f n)" text{*The following definition of @{term diff_group_add_pert_hom_bound_exist} contains the local nilpotency condition. It is based on an existential statement.*} text{*For all @{term "x"} belonging to our differential group, we state the existence of a natural number @{term "n::nat"} which is a bound for @{term [locale=diff_group_add_pert_hom] "α"}*} text{*We then prove that it is equivalent to the previously given definition of @{term locale_bounded_func}.*} text{*Finally, we link this fact to the previous results about computation of the bounds as a \emph{For} operator.*} class diff_group_add_pert_hom_bound_exist = diff_group_add_pert_hom + assumes local_nilp_cond: "∀x.∃n::nat. (α^n) x = 0" (*The following definition cannot be inserted in the @{text "class"} context begin definition Φ :: "'a => 'a" where "Φ == (λx. (fin_sum α) (local_bound α x) x)" end*) lemma diff_group_add_pert_hom_bound_exist_impl_local_bounded_func_alpha: assumes diff_group_add_pert_hom_bound_exist: "diff_group_add_pert_hom_bound_exist op - (λx. - x) 0 op + (λx. d x) (λx. δ x) (λx. h x)" shows "local_bounded_func (α::'a::diff_group_add_pert_hom_bound_exist => 'a)" unfolding local_bounded_func_def using local_nilp_cond . lemma diff_group_add_pert_hom_bound_exist_impl_local_bound_is_Least: assumes diff: "diff_group_add_pert_hom_bound_exist op - (λx. - x) 0 op + (λx. d x) (λx. δ x) (λx. h x)" shows "local_bound α (x::'a::diff_group_add_pert_hom_bound_exist) = (LEAST n::nat. (α^n) x = 0)" unfolding local_bounded_func_impl_local_bound_is_Least [OF diff_group_add_pert_hom_bound_exist_impl_local_bounded_func_alpha [OF diff]] .. (*text The definition command does not allow the following: definition (in diff_group_add_pert_hom_bound_exist) Φ :: "'a => 'a" where "Φ == (λx. fin_sum (α) (local_bound α x) x)"*) text{*Apparently, @{typ "'a"} does not belong to the appropriate type class.*} text{*It does not seem either a good option to use long qualifiers with the locale name*} text{*Instead, we have to use the following explicit restriction of the type parameter*} text{*The following definitions will have to be later compared with the ones @{term [locale=BPL] "Φ"}, \dots*} text{*Additionally, code generation from them must be possible.*} (*definition Φ :: "('a::diff_group_add_pert_hom_bound_exist => 'a)" where "Φ == (λx. fin_sum α (local_bound (diff_group_add_pert_hom.α uminus pert hom_oper) x) x)"*) definition Φ :: "('a::diff_group_add_pert_hom_bound_exist => 'a)" where "Φ = (λx. fin_sum α (local_bound α x) x)" definition β :: "('a::diff_group_add_pert_hom_bound_exist => 'a)" where "β = (- ((λx. h x) o (λ x. δ x)))" definition Ψ :: "('a::diff_group_add_pert_hom_bound_exist => 'a)" where "Ψ = (λx. fin_sum β (local_bound β x) x)" text{*The following definitions are also to be compared with the ones appearing in the output of the @{thm BPL.BPL}*} definition dC' :: "('a::diff_group_add_pert_hom_bound_exist => 'b::diff_group_add) => ('b => 'a) => ('b => 'b)" where "dC' f g = diff + (f o (λx. δ x) o Ψ o g)" definition f' :: "('a::diff_group_add_pert_hom_bound_exist => 'b::diff_group_add) => ('a => 'b)" where "f' f = f o Φ" definition g' :: "('b::diff_group_add => 'a::diff_group_add_pert_hom_bound_exist) => ('b => 'a)" where g'_def: "g' g == Ψ o g" definition h' :: "('a::diff_group_add_pert_hom_bound_exist => 'a)" where "h' == (λx. h x) o Φ" export_code Φ Ψ f' g' h' dC' in SML file "output_reduction.ML" text{*Some facts about the product of types:*} instantiation * :: (ab_semigroup_add, ab_semigroup_add) ab_semigroup_add begin definition mult_plus_def: "x + y ≡ (let (x1, x2) = x; (y1, y2) = y in (x1 + y1, x2 + y2))" instance proof fix a::"'a::ab_semigroup_add × 'b::ab_semigroup_add" obtain i j where a_split: "a = (i, j)" by force fix b::"'a × 'b" obtain k l where b_split: "b = (k, l)" by force fix c::"'a × 'b" obtain m n where c_split: "c = (m, n)" by force show "a + b + c = a + (b + c)" unfolding a_split b_split c_split unfolding mult_plus_def by (auto simp add: add_assoc) show "a + b = b + a" unfolding a_split b_split unfolding mult_plus_def by (auto simp add: add_commute) qed end definition x5:: "(int × int)" where "x5 = ((3::int), (5::int)) + (5, 7)" definition x6 :: "(int × int) × (int × int)" where "x6 = (((3::int), (5::int)), ((3::int), (5::int))) + ((5, 7), (5, 7))" export_code x5 x6 in SML file "x6.ML" instantiation * :: (comm_monoid_add, comm_monoid_add) comm_monoid_add begin definition mult_zero_def: "0 ≡ (0, 0)" instance by default (simp add: split_paired_all mult_plus_def mult_zero_def) end section{*Equivalence of both approaches*} subsection{*Algebraic structures*} text{*In the following section we prove that the results already proved using the definitions provided by the Algebra Isabelle Library (leading to the @{thm [locale=BPL] BPL}) also hold for the new definitions, where algebraic structures are implemented by means of type classes.*} text{*This does not mean that the proof of the BPL can be developed only by using type classes; the degree of expressivity needed in its proofs should be quite hard to achieve using type classes; specially, the parts where restrictions of domains of functions have to be used.*} text{*We only pretend to prove that the new definitions, to some extent simplified (see for instance the new proposed series in relation to the previous implementation of series), are equivalent to the old ones, and thus, also satisfy the BPL.*} text{*Functions (or functors) translating type classes into algebraic structures implemented as recods are used; these translations are the natural ones*} definition monoid_functor :: "('a => 'a => 'a) => ('a) => 'a monoid" where "monoid_functor A B == (| carrier = UNIV, mult = A, one = B|))," lemma monoid_add_impl_monoid: assumes mon_add: "monoid_add zero' plus'" shows "monoid (| carrier = UNIV, mult = plus', one = zero'|))," using mon_add unfolding monoid_def unfolding monoid_add_def monoid_add_axioms_def unfolding ab_semigroup_add_def unfolding ab_semigroup_add_axioms_def unfolding semigroup_add_def by simp lemma monoid_functor_preserv: assumes monoid_add:"monoid_add zero' plus'" shows "monoid (monoid_functor plus' zero')" using monoid_add_impl_monoid [OF monoid_add] unfolding monoid_functor_def [of plus' zero'] . lemma comm_monoid_add_impl_monoid_add: assumes comm_monoid_add: "comm_monoid_add zero' plus'" shows "monoid_add zero' plus'" using comm_monoid_add unfolding comm_monoid_add_def unfolding monoid_add_def unfolding ab_semigroup_add_def unfolding comm_monoid_add_axioms_def unfolding monoid_add_axioms_def unfolding ab_semigroup_add_axioms_def by auto lemma comm_monoid_add_impl_monoid: assumes c_m: "comm_monoid_add zero' plus'" shows "monoid (| carrier = UNIV, mult = plus', one = zero'|))," using monoid_add_impl_monoid [OF comm_monoid_add_impl_monoid_add [OF c_m]] . lemma ab_group_add_impl_comm_monoid_add: assumes ab_gr_add: "ab_group_add uminus' minus' zero' plus'" shows "comm_monoid_add zero' plus'" using ab_gr_add unfolding ab_group_add_def .. lemma ab_group_class_impl_group: assumes ab_gr_class: "ab_group_add uminus' minus' zero' plus'" shows "group (| carrier = UNIV, mult = plus', one = zero'|))," proof (intro_locales) show "monoid (|carrier = UNIV, mult = plus', one = zero'|))," using monoid_add_impl_monoid [OF comm_monoid_add_impl_monoid_add [OF ab_group_add_impl_comm_monoid_add [OF ab_gr_class]]] . show "group_axioms (|carrier = UNIV, mult = plus', one = zero'|))," using ab_gr_class unfolding group_axioms_def unfolding Units_def unfolding ab_group_add_def unfolding comm_monoid_add_def unfolding ab_group_add_axioms_def unfolding ab_semigroup_add_def ab_semigroup_add_axioms_def by auto+ qed lemma monoid_functor_preserv_group: assumes ab_gr: "ab_group_add uminus' minus' zero' plus'" shows "group (monoid_functor plus' zero')" using ab_group_class_impl_group [OF ab_gr] unfolding monoid_functor_def [of plus' zero'] . lemma ab_group_add_impl_comm_group: assumes ab_gr_add: "ab_group_add uminus' minus' zero' plus'" shows "comm_group (| carrier = UNIV, mult = plus', one = zero'|))," proof (intro_locales) show "monoid (|carrier = UNIV, mult = plus', one = zero'|))," using comm_monoid_add_impl_monoid [OF ab_group_add_impl_comm_monoid_add [OF ab_gr_add]] . show "comm_monoid_axioms (|carrier = UNIV, mult = plus', one = zero'|))," using ab_gr_add unfolding comm_monoid_axioms_def unfolding ab_group_add_def unfolding comm_monoid_add_def unfolding ab_group_add_axioms_def unfolding ab_semigroup_add_def unfolding ab_semigroup_add_axioms_def by auto show "group_axioms (|carrier = UNIV, mult = plus', one = zero'|))," using ab_gr_add unfolding group_axioms_def unfolding Units_def unfolding ab_group_add_def unfolding comm_monoid_add_def unfolding ab_group_add_axioms_def unfolding ab_semigroup_add_def unfolding ab_semigroup_add_axioms_def by auto+ qed lemma monoid_functor_preserv_ab_group: assumes ab_gr_add: "ab_group_add uminus' minus' zero' plus'" shows "comm_group (monoid_functor plus' zero')" using ab_group_add_impl_comm_group [OF ab_gr_add] unfolding monoid_functor_def [of plus' zero'] . lemma diff_group_add_impl_comm_group: assumes diff_gr_add: "diff_group_add uminus' minus' zero' plus' diff'" shows "comm_group (|carrier = UNIV, mult = plus', one = zero'|))," proof (rule ab_group_add_impl_comm_group) show "ab_group_add uminus' minus' zero' plus'" using diff_gr_add unfolding diff_group_add_def by simp qed lemma diff_group_add_impl_diff_group: assumes diff_gr_add: "diff_group_add uminus' minus' zero' prod' diff'" shows "diff_group (|carrier = UNIV, mult = prod', one = zero', diff_group.diff = diff' |))," proof (intro_locales) from diff_group_add_impl_comm_group [OF diff_gr_add] have comm_gr: "comm_group (|carrier = UNIV, mult = prod', one = zero'|))," by simp show "monoid (|carrier = UNIV, mult = prod', one = zero', diff_group.diff = diff'|))," using comm_gr unfolding comm_group_def unfolding comm_monoid_def unfolding monoid_def by simp show "comm_monoid_axioms (|carrier = UNIV, mult = prod', one = zero', diff_group.diff = diff'|))," using comm_gr unfolding comm_group_def unfolding comm_monoid_def unfolding comm_monoid_axioms_def by simp show "group_axioms (|carrier = UNIV, mult = prod', one = zero', diff_group.diff = diff'|))," using comm_gr unfolding comm_group_def unfolding group_def unfolding group_axioms_def unfolding Units_def by simp show "diff_group_axioms (|carrier = UNIV, mult = prod', one = zero', diff_group.diff = diff'|))," using diff_gr_add unfolding diff_group_add_def unfolding diff_group_add_axioms_def unfolding diff_group_axioms_def unfolding hom_completion_def unfolding hom_def unfolding completion_fun2_def unfolding completion_def by auto qed definition diff_group_functor :: "('a => 'a) => ('a => 'a => 'a) => ('a) => ('a => 'a => 'a) => ('a => 'a) => 'a diff_group" where "diff_group_functor uminus' minus' zero' prod' diff' = (| carrier = UNIV, mult = prod', one = zero', diff_group.diff = diff'|))," lemma diff_group_functor_preserves: assumes diff_gr_add: "diff_group_add minus' uminus' zero' prod' diff'" shows "diff_group (diff_group_functor uminus' minus' zero' prod' diff')" using diff_group_add_impl_diff_group [OF diff_gr_add] unfolding diff_group_functor_def [of uminus' minus' zero' prod' diff'] . text{*After the previous equivalences between algebraic structures, now we prove the equivalence between the old definitions about homomorphisms and the new ones:*} subsection{*Homomorphisms and endomorphisms.*} (*definition homo :: "('a::monoid_add => 'b::monoid_add) => bool" where "homo f <-> (ALL a b. f (a + b) = f a + f b)"*) definition homo_ab :: "('a::comm_monoid_add => 'b::comm_monoid_add) => bool" where "homo_ab f = (ALL a b. f (a + b) = f a + f b)" lemma homo_ab_apply: assumes h_f: "homo_ab f" shows "f (a + b) = f a + f b" using homo_ab_def [of f] h_f by simp lemma homo_ab_preserves_hom_completion: assumes homo_ab_f: "homo_ab f" shows "f ∈ hom_completion (monoid_functor (op +) 0) (monoid_functor (op +) 0)" using homo_ab_f unfolding hom_completion_def unfolding homo_ab_def unfolding monoid_functor_def unfolding completion_fun2_def unfolding completion_def unfolding hom_def by auto lemma plus_fun_apply: "(f + g) (x::'a::ab_semigroup_add) = f x + g x" using plus_fun_def [of f g] by simp lemma homo_ab_plus_closed: assumes comm_monoid_add_A: "comm_monoid_add (0::'a::comm_monoid_add) op +" and comm_monoid_add_B: "comm_monoid_add (0::'b::comm_monoid_add) op +" and x: "homo_ab (x::'a::comm_monoid_add => 'b::comm_monoid_add)" and y: "homo_ab y" shows "homo_ab (x + y)" proof (unfold homo_ab_def, rule allI, rule allI) have ab_semigroup_add_plus: "ab_semigroup_add (op +::'b => 'b => 'b)" using comm_monoid_add_B unfolding comm_monoid_add_def .. fix a b :: 'a show "(x + y) (a + b) = (x + y) a + (x + y) b" proof - have "(x + y) (a + b) = x (a + b) + y (a + b)" using plus_fun_apply [of x y "a + b"] . also have "… = x a + x b + (y a + y b)" unfolding homo_ab_apply [OF x] unfolding homo_ab_apply [OF y] .. also have "… = x a + (x b + y a + y b)" by (auto simp add: add_assoc) also have "… = x a + (y a + x b + y b)" by (auto simp add: add_commute add_assoc) also have "… = x a + y a + (x b + y b)" by (auto simp add: add_assoc) also have "… = (x + y) a + (x + y) b" unfolding sym [OF plus_fun_apply [of x y a]] unfolding sym [OF plus_fun_apply [of x y b]] .. finally show ?thesis . qed qed lemma end_comm_monoid_add_closed: assumes comm_monoid_add: "comm_monoid_add (0::'a::comm_monoid_add) op +" and x: "homo_ab (x::'a::comm_monoid_add => 'a)" and y: "homo_ab y" shows "homo_ab (x + y)" using homo_ab_plus_closed [OF comm_monoid_add comm_monoid_add x y] . lemma comm_monoid_add_impl_homo_abelian_monoid: assumes comm_monoid_add: "comm_monoid_add (0::'a::comm_monoid_add) op +" shows "abelian_monoid (|carrier = {f::'a::comm_monoid_add => 'a. homo_ab f}, mult = op o, one = id, zero = 0, add = op +|))," proof (intro abelian_monoidI, auto) fix x y :: "'a => 'a" assume x: "homo_ab x" and y: "homo_ab y" show "homo_ab (x + y)" using end_comm_monoid_add_closed [OF comm_monoid_add x y] . next show "homo_ab (0::'a => 'a)" unfolding zero_fun_def homo_ab_def by simp next fix x y z :: "'a => 'a" assume x: "homo_ab x" and y: "homo_ab y" and z: "homo_ab z" show "x + y + z = x + (y + z)" unfolding plus_fun_def by (simp only: add_assoc) next fix x y :: "'a => 'a" assume x: "homo_ab x" and y: "homo_ab y" show "x + y = y + x" unfolding plus_fun_def expand_fun_eq by (simp add: add_ac) qed lemma ab_group_add_impl_uminus_fun_closed: assumes ab_group_add: "ab_group_add op - (λx. - x) (0::'a::ab_group_add) op +" and f: "homo_ab (f::'a::ab_group_add => 'a)" shows "homo_ab (- f)" proof (unfold fun_Compl_def homo_ab_def, rule allI, rule allI) fix a b :: 'a show "- f (a + b) = - f a + - f b" proof - have l_h_s: "f (a + b) + - f (a + b) = 0" using sym [OF add_commute [of "- f (a + b)" "f (a + b)"]] unfolding ab_left_minus [of "f (a + b)"] . have "f (a + b) + (- f a + - f b) = - f a + - f b + f (a + b)" using sym [OF add_commute [of "- f a + - f b" "f (a + b)"]] . also have "- f a + - f b + f (a + b) = - f a + - f b + (f a + f b)" unfolding homo_ab_apply [OF f] .. also have "… = ((- f a + - f b) + f a) + f b" unfolding sym [OF add_assoc [of "- f a + - f b" "f a" "f b"]] .. also have "… = (- f a + (- f b + f a)) + f b" unfolding add_assoc [of "- f a" "- f b" "f a"] .. also have "… = (- f a + (f a + - f b)) + f b" unfolding add_commute [of "- f b" "f a"] .. also have "… = ((- f a + f a) + - f b) + f b" unfolding sym [OF add_assoc [of "- f a" "f a" "- f b"]] .. also have "… = 0 + - f b + f b" unfolding ab_left_minus [of "f a"] .. also have "… = 0 + (- f b + f b)" unfolding add_assoc [of 0 "- f b" "f b"] .. also have "… = 0 + 0" unfolding ab_left_minus [of "f b"] .. also have "… = 0" by simp finally have r_h_s: "f (a + b) + (- f a + - f b) = 0" . with l_h_s have "f (a + b) + - f (a + b) = f (a + b) + (- f a + - f b)" by simp then have "- (f::'a => 'a) ((a::'a) + (b::'a)) + (f (a + b) + - f (a + b)) = - f (a + b) + (f (a + b) + (- f a + - f b))" by simp with sym [OF add_assoc [of "- f (a + b)" "f (a + b)" "- f (a + b)"]] sym [OF add_assoc [of "- f (a + b)" "f (a + b)" "- f a + - f b"]] have "(- (f::'a => 'a) ((a::'a) + (b::'a)) + f (a + b)) + - f (a + b) = (- f (a + b) + f (a + b)) + (- f a + - f b)" by simp with ab_left_minus [of "f (a + b)"] have "0 + - f (a + b) = 0 + (- f a + - f b)" by simp with left_minus [of "- f (a + b)"] left_minus [of "(- f a + - f b)"] show ?thesis by simp qed qed lemma ab_group_add_impl_homo_abelian_group_axioms: assumes ab_group_add: "ab_group_add op - (λx. - x) (0::'a::ab_group_add) op +" shows "abelian_group_axioms (|carrier = {f::'a::ab_group_add => 'a. homo_ab f}, mult = op o, one = id, zero = 0, add = op +|))," proof (unfold abelian_group_axioms_def, simp) show "comm_group (|carrier = Collect homo_ab, mult = op +, one = (0::'a => 'a)|))," proof (intro_locales) show "monoid (|carrier = Collect homo_ab, mult = op +, one = (0::'a => 'a)|))," proof (intro monoidI, simp_all) fix x y :: "'a => 'a" assume x: "homo_ab x" and y: "homo_ab y" show "homo_ab (x + y)" using ab_group_add end_comm_monoid_add_closed [OF _ x y] unfolding ab_group_add_def by simp next show "homo_ab (0::'a => 'a)" unfolding zero_fun_def homo_ab_def by simp qed next show "comm_monoid_axioms (|carrier = Collect homo_ab, monoid.mult = op +, one = (0::'a => 'a)|))," unfolding comm_monoid_axioms_def by auto next show "group_axioms (|carrier = Collect homo_ab, monoid.mult = op +, one = (0::'a => 'a)|))," proof (unfold group_axioms_def Units_def, auto) fix x :: "'a => 'a" assume x: "homo_ab x" show "∃y::'a => 'a. homo_ab y ∧ y + x = 0 ∧ x + y = 0" proof (rule exI [of _ "- x"], intro conjI) show "homo_ab (- x)" using ab_group_add_impl_uminus_fun_closed [OF ab_group_add x] . show "(- x) + x = 0" by simp show "x + (- x) = 0" by simp qed qed qed qed text{*The previous lemma, @{thm ab_group_add_impl_homo_abelian_group_axioms}, proves the elements of @{term homo_ab} to be an abelian monoid under suitable operations.*} text{*In order to show that composition gives place to a monoid, the underlying structure needs not to be even a monoid*} lemma homo_monoid: shows "monoid (|carrier = {f. homo_ab f}, monoid.mult = op o, one = id, zero = 0, add = op +|))," (is "monoid ?HOMO_AB") proof (intro monoidI, auto) fix x y :: "'a => 'a" assume x: "homo_ab x" and y: "homo_ab y" then show "homo_ab (x o y)" unfolding homo_ab_def by simp next show "homo_ab id" unfolding homo_ab_def by simp next fix x y z :: "'a => 'a" assume x: "homo_ab x" and y: "homo_ab y" and z: "homo_ab z" show "x o y o z = x o (y o z)" by (simp add: expand_fun_eq) qed text{*A couple of lemmas completing the proof of the set @{term homo_ab} being a ring, with suitable operations*} lemma ab_group_add_impl_homo_ring_axioms: assumes ab_group_add: "ab_group_add op - (λx. - x) (0::'a::ab_group_add) op +" shows "ring_axioms (|carrier = {f. homo_ab f}, mult = op o, one = id, zero = (0::'a::ab_group_add => 'a), add = op +|))," proof (intro ring_axioms.intro, auto) fix x y z :: "'a => 'a" assume x: "homo_ab x" and y: "homo_ab y" and z: "homo_ab z" show "(x::'a => 'a) + y o z = (x o z) + (y o z)" unfolding plus_fun_def unfolding expand_fun_eq by auto show "(z::'a => 'a) o x + y = (z o x) + (z o y)" using z unfolding expand_fun_eq plus_fun_def homo_ab_def by auto qed lemma ab_group_add_impl_homo_ring: assumes ab_group_add: "ab_group_add op - (λx. - x) (0::'a::ab_group_add) op +" shows "ring (|carrier = {f::'a::ab_group_add => 'a. homo_ab f}, mult = op o, one = id, zero = (0::'a => 'a), add = op +|))," using ab_group_add using comm_monoid_add_impl_homo_abelian_monoid using ab_group_add_impl_homo_abelian_group_axioms using homo_monoid using ab_group_add_impl_homo_ring_axioms by (unfold ab_group_add_def, intro_locales, auto) text{*The following definition includes the notion of differential homomorphism, a homomorphism that additionally commutes with the corresponding differentials.*} definition homo_diff :: "('a::diff_group_add => 'b::diff_group_add) => bool" where "homo_diff f = ((ALL a b. f (a + b) = f a + f b) ∧ f o diff = diff o f)" lemma homo_diff_preserves_hom_diff: assumes homo_diff_f: "homo_diff f" shows "f ∈ hom_diff (diff_group_functor (λx. - x) op - 0 (op +) diff) (diff_group_functor (λx. - x) op - 0 (op +) diff)" using homo_diff_f unfolding hom_diff_def unfolding hom_completion_def unfolding homo_diff_def unfolding diff_group_functor_def unfolding completion_fun2_def unfolding completion_def unfolding hom_def by auto subsection{*Definition of constants.*} text{*The following definition of reduction is to be understand as follows: a pair of homomorphisms @{text "(f, g)"} will be a reduction iff: the underlying algebraic structures (given as classes) are, respectively, a differential group class with a perturbation and a homology operator (i.e, class @{term diff_group_add_pert_hom_bound_exists}) satisfying the local nilpotency condition, and a differential group class (@{term diff_group_add}), and the homomorphisms @{text f}, @{text g} and @{text h} satisfy the properties required by the usual reduction definition.*} text{*In the definition it can be noted the convenience of using overloading symbols provided by the class mechanism.*} definition reduction_class_ext :: "('a::diff_group_add_pert_hom_bound_exist => 'b::diff_group_add) => ('b => 'a) => bool" where "reduction_class_ext f g = ((diff_group_add_pert_hom_bound_exist op - (λx::'a. - x) 0 (op +) diff pert hom_oper) ∧ (diff_group_add op - (λx::'b. - x) 0 (op +) diff) ∧ (homo_diff f) ∧ (homo_diff g) ∧ (f o g = id) ∧ ((g o f) + (diff o hom_oper) + (hom_oper o diff) = id) ∧ (f o hom_oper = (0::'a => 'b)) ∧ (hom_oper o g = (0::'b => 'a)))" text{*The previous definition contains all the ingredients required to apply the old proof of the BPL.*} lemma reduction_class_ext_impl_diff_group_add_pert_hom_bound_exist: assumes r_c_e: "reduction_class_ext (f::'a::diff_group_add_pert_hom_bound_exist => 'b::diff_group_add) g" shows "(diff_group_add_pert_hom_bound_exist op - (λx::'a::diff_group_add_pert_hom_bound_exist. - x) 0 (op +) diff pert hom_oper)" using r_c_e unfolding reduction_class_ext_def .. lemma reduction_class_ext_impl_diff_group_add: assumes r_c_e: "reduction_class_ext (f::'a::diff_group_add_pert_hom_bound_exist => 'b::diff_group_add) g" shows "(diff_group_add op - (λx::'b::diff_group_add. - x) 0 (op +) diff)" using r_c_e unfolding reduction_class_ext_def by fast lemma reduction_class_ext_impl_homo_diff_f: assumes r_c_e: "reduction_class_ext (f::'a::diff_group_add_pert_hom_bound_exist => 'b::diff_group_add) g" shows "homo_diff f" using r_c_e unfolding reduction_class_ext_def by fast lemma reduction_class_ext_impl_homo_diff_g: assumes r_c_e: "reduction_class_ext (f::'a::diff_group_add_pert_hom_bound_exist => 'b::diff_group_add) g" shows "homo_diff g" using r_c_e unfolding reduction_class_ext_def by fast lemma reduction_class_ext_impl_fg_id: assumes r_c_e: "reduction_class_ext (f::'a::diff_group_add_pert_hom_bound_exist => 'b::diff_group_add) g" shows "f o g = id" using r_c_e unfolding reduction_class_ext_def by fast lemma reduction_class_ext_impl_gf_dh_hd_id: assumes r_c_e: "reduction_class_ext (f::'a::diff_group_add_pert_hom_bound_exist => 'b::diff_group_add) g" shows "(g o f) + (diff o hom_oper) + (hom_oper o diff) = id" using r_c_e unfolding reduction_class_ext_def by fast lemma reduction_class_ext_impl_fh_0: assumes r_c_e: "reduction_class_ext (f::'a::diff_group_add_pert_hom_bound_exist => 'b::diff_group_add) g" shows "f o hom_oper = 0" using r_c_e unfolding reduction_class_ext_def by fast lemma reduction_class_ext_impl_hg_0: assumes r_c_e: "reduction_class_ext (f::'a::diff_group_add_pert_hom_bound_exist => 'b::diff_group_add) g" shows "hom_oper o g = 0" using r_c_e unfolding reduction_class_ext_def by fast text{*The following lemma will be useful later, when we verify the premises of the BPL*} lemma hdh_eq_h: assumes r_c_e: "reduction_class_ext f (g::'b::diff_group_add => 'a::diff_group_add_pert_hom_bound_exist)" shows "(hom_oper::'a::diff_group_add_pert_hom_bound_exist => 'a) o diff o hom_oper = hom_oper" proof - have "hom_oper = hom_oper o id" by simp also have "… = hom_oper o ((g o f) + (diff o hom_oper) + (hom_oper o diff))" using r_c_e unfolding reduction_class_ext_def by simp also have "… = hom_oper o (diff o hom_oper)" using reduction_class_ext_impl_diff_group_add_pert_hom_bound_exist [OF r_c_e] using reduction_class_ext_impl_hg_0 [OF r_c_e] unfolding diff_group_add_pert_hom_bound_exist_def unfolding diff_group_add_pert_hom_def unfolding diff_group_add_pert_hom_axioms_def unfolding expand_fun_eq plus_fun_def zero_fun_def by auto finally show ?thesis by (simp add: o_assoc) qed lemma diff_group_add_pert_hom_bound_exist_impl_diff_group_add: assumes d_g: "(diff_group_add_pert_hom_bound_exist op - (λx::'a::diff_group_add_pert_hom_bound_exist. - x) 0 (op +) diff pert hom_oper)" shows "diff_group_add op - (λx::'a::diff_group_add_pert_hom_bound_exist. - x) 0 (op +) diff" using d_g unfolding diff_group_add_pert_hom_bound_exist_def unfolding diff_group_add_pert_hom_def unfolding diff_group_add_pert_def by fast text{*The new definition of @{term reduction_class_ext} preserves the previous definition of reduction in the old approach, @{term reduction}*} lemma reduction_class_ext_preserves_reduction: assumes r_c_e: "reduction_class_ext f g" shows "reduction (diff_group_functor (λx::'a::diff_group_add_pert_hom_bound_exist. - x) (op -) 0 (op +) diff) (diff_group_functor (λx::'b::diff_group_add. - x) (op -) 0 (op +) diff) f g hom_oper" (is "reduction ?D ?C f g hom_oper") proof (unfold reduction_def reduction_axioms_def, auto) have dga: "diff_group_add_pert_hom_bound_exist op - uminus (0::'a) op + diff pert hom_oper" using reduction_class_ext_impl_diff_group_add_pert_hom_bound_exist [OF r_c_e] . show "diff_group ?D" using diff_group_functor_preserves [of "op -" uminus "(0::'a)" "op +" diff] diff_group_add_pert_hom_bound_exist_impl_diff_group_add [OF dga] by simp next show "diff_group ?C" using r_c_e diff_group_functor_preserves [of "op -" uminus "(0::'b)" "op +" diff] unfolding reduction_class_ext_def [of f g] by simp next show "f ∈ hom_diff ?D ?C" using r_c_e homo_diff_preserves_hom_diff [of f] unfolding reduction_class_ext_def [of f g] by simp next show "g ∈ hom_diff ?C ?D" using r_c_e homo_diff_preserves_hom_diff [of g] unfolding reduction_class_ext_def [of f g] by simp next show "hom_oper ∈ hom_completion ?D ?D" using diff_group_add_pert_hom.h_hom_ab [of "op -" uminus "(0::'a)" "op +" diff pert hom_oper] using homo_ab_preserves_hom_completion [of "(λx::'a. h x)"] using r_c_e unfolding hom_completion_def unfolding hom_def unfolding completion_fun2_def unfolding completion_def unfolding reduction_class_ext_def unfolding diff_group_functor_def unfolding diff_group_add_pert_hom_bound_exist_def by auto next show "(λx. h x) o (λx. h x) = (λx::'a. monoid.one ?D)" using diff_group_add_pert_hom.h_nilpot [of "op -" uminus "(0::'a)" "op +" diff pert hom_oper] using r_c_e unfolding reduction_class_ext_def unfolding diff_group_add_pert_hom_bound_exist_def unfolding zero_fun_def unfolding reduction_class_ext_def unfolding diff_group_functor_def by simp next show "f o g = (λx::'b. if x ∈ carrier ?C then id x else monoid.one ?C)" using r_c_e unfolding reduction_class_ext_def unfolding diff_group_functor_def expand_fun_eq by simp next show "f o (λx. h x) = (λx::'a. monoid.one ?C)" using r_c_e unfolding reduction_class_ext_def diff_group_functor_def zero_fun_def by simp next show "(λx. h x) o g = (λx::'b. monoid.one ?D)" using r_c_e unfolding reduction_class_ext_def diff_group_functor_def zero_fun_def by simp next show "(λx::'a. if x ∈ carrier ?D then monoid.mult ?D ((g o f) x) (if x ∈ carrier ?D then monoid.mult ?D ((diff_group.diff ?D o hom_oper) x) ((hom_oper o diff_group.diff ?D) x) else monoid.one ?D) else monoid.one ?D) = (λx::'a. if x ∈ carrier ?D then id x else monoid.one ?D)" using r_c_e unfolding reduction_class_ext_def unfolding diff_group_functor_def unfolding plus_fun_def by (auto simp add: expand_fun_eq add_assoc) qed text{*The new definition of perturbation, included in the definition of @{term diff_group_add_pert}, also preserves the old definition of perturbation, @{term "analytic_part_local.pert"}*} lemma diff_group_add_pert_hom_bound_exist_preserves_pert: assumes diff_group_add_pert_hom_bound_exist: "diff_group_add_pert_hom_bound_exist (op -) (λx::'a::diff_group_add_pert_hom_bound_exist. - x) 0 (op +) diff pert hom_oper" shows "pert ∈ analytic_part_local.pert (diff_group_functor (λx::'a::diff_group_add_pert_hom_bound_exist. - x) (op -) 0 (op +) diff)" (is "pert ∈ analytic_part_local.pert ?D") proof (unfold pert_def, auto) show "pert ∈ hom_completion ?D ?D" using diff_group_add_pert_hom_bound_exist unfolding diff_group_add_pert_hom_bound_exist_def unfolding diff_group_add_pert_hom_def unfolding diff_group_add_pert_def unfolding diff_group_add_pert_axioms_def unfolding diff_group_functor_def unfolding monoid_functor_def unfolding hom_completion_def unfolding completion_fun2_def completion_def hom_def by simp next have diff_group_add: "diff_group_add (op -) uminus (0::'a) op + diff" using diff_group_add_pert_hom_bound_exist_impl_diff_group_add [OF diff_group_add_pert_hom_bound_exist] . show "diff_group (|carrier = carrier ?D, mult = mult ?D, one = one ?D, diff_group.diff = λx::'a. if x ∈ carrier ?D then mult ?D (diff_group.diff ?D x) (δ x) else one ?D|))," using diff_group_add_pert_hom_bound_exist using diff_group_functor_preserves [of "op -" uminus "(0::'a)" "op +" "diff + pert"] unfolding plus_fun_def unfolding diff_group_add_pert_hom_bound_exist_def unfolding diff_group_add_pert_hom_def unfolding diff_group_add_pert_def unfolding diff_group_add_pert_axioms_def diff_group_functor_def by auto qed text{*From the premises stated in @{term diff_group_add_pert_hom_bound_exist}, @{term [locale=diff_group_add_pert_hom_bound_exist] α} is nilpotent*} lemma α_locally_nilpotent: assumes diff_group_add_pert_hom_bound_exist: "diff_group_add_pert_hom_bound_exist (op -) (λx::'a::diff_group_add_pert_hom_bound_exist. - x) 0 (op +) diff pert hom_oper" shows "(α^(local_bound α x)) (x::'a::diff_group_add_pert_hom_bound_exist) = 0" unfolding diff_group_add_pert_hom_bound_exist_impl_local_bound_is_Least [OF diff_group_add_pert_hom_bound_exist, of x] proof (rule LeastI_ex) show "∃k. (α ^ k) x = (0::'a)" proof - obtain n where n_bound: "(α^ n) (x::'a::diff_group_add_pert_hom_bound_exist) = 0" using diff_group_add_pert_hom_bound_exist_impl_local_bounded_func_alpha [OF diff_group_add_pert_hom_bound_exist] unfolding local_bounded_func_def by auto then show ?thesis using exI by auto qed qed text{*The algebraic structure given by the endomorphisms of a @{text "diff_group_add"} with suitable operations is a ring*} lemma (in group_add) shows "op - = (λx y. x + (- y))" unfolding expand_fun_eq unfolding diff_minus by simp lemma (in diff_group_add) hom_completion_ring: shows "ring (|carrier = hom_completion (diff_group_functor (λx::'a. - x) (op -) 0 (op +) diff) (diff_group_functor (λx::'a. - x) (op -) 0 (op +) diff), mult = op o, one = λx::'a. if x ∈ carrier (diff_group_functor (λx::'a. - x) (op -) 0 (op +) diff) then id x else one (diff_group_functor (λx::'a. - x) (op -) 0 (op +) diff), zero = λx::'a. if x ∈ carrier (diff_group_functor (λx::'a. - x) (op -) 0 (op +) diff) then one (diff_group_functor (λx::'a. - x) (op -) 0 (op +) diff) else one (diff_group_functor (λx::'a. - x) (op -) 0 (op +) diff), add = λ(f::'a => 'a) (g::'a => 'a) x::'a. if x ∈ carrier (diff_group_functor (λx::'a. - x) (op -) 0 (op +) diff) then mult (diff_group_functor (λx::'a. - x) (op -) 0 (op +) diff) (f x) (g x) else one (diff_group_functor (λx::'a. - x) (op -) 0 (op +) diff)|))," using diff_group_functor_preserves [OF prems] using comm_group.hom_completion_ring [of "(diff_group_functor (λx::'a. - x) op - 0 (op +) diff)"] using diff_minus unfolding diff_group_def by simp lemma homo_ab_is_hom_completion: assumes homo_ab_f: "homo_ab f" and diff_group_add: "diff_group_add (op -) (λx::'a::diff_group_add. - x) 0 (op +) diff" shows "f ∈ hom_completion (diff_group_functor (λx::'a::diff_group_add. - x) (op -) 0 (op +) diff) (diff_group_functor (λx::'a. - x) (op -) 0 (op +) diff)" using homo_ab_f using diff_group_add unfolding hom_completion_def unfolding homo_ab_def unfolding diff_group_functor_def unfolding hom_def unfolding completion_fun2_def unfolding completion_def by auto lemma hom_completion_is_homo_ab: assumes f_hom_compl: "f ∈ hom_completion (diff_group_functor (λx::'a::diff_group_add. - x) (op -) 0 (op +) diff) (diff_group_functor (λx::'a. - x) (op -) 0 (op +) diff)" and diff_group_add: "diff_group_add (op -) (λx::'a::diff_group_add. - x) 0 (op +) diff" shows "homo_ab f" using f_hom_compl using diff_group_add unfolding hom_completion_def unfolding homo_ab_def unfolding diff_group_functor_def unfolding hom_def unfolding completion_fun2_def unfolding completion_def by auto lemma hom_completion_equiv_homo_ab: assumes diff_group_add: "diff_group_add (op -) (λx::'a::diff_group_add. - x) 0 (op +) diff" shows "homo_ab f <-> f ∈ hom_completion (diff_group_functor (λx::'a::diff_group_add. - x) (op -) 0 (op +) diff) (diff_group_functor (λx::'a. - x) (op -) 0 (op +) diff)" using homo_ab_is_hom_completion [of f] using hom_completion_is_homo_ab [of f] using diff_group_add by auto text{*Equivalence between the definition of power in the Isabelle Algebra Library, @{term nat_pow_def}, over the ring of endomorphisms, and the definition of power for functions, definition @{term fun_pow}*} definition ring_hom_compl :: "('a diff_group) => ('a => 'a) ring" where "ring_hom_compl D == (|carrier = hom_completion D D, mult = op o, one = λx::'a. if x ∈ carrier D then id x else one D, zero = λx::'a. if x ∈ carrier D then one D else one D, add = λ(f::'a => 'a) (g::'a => 'a) x::'a. if x ∈ carrier D then mult D (f x) (g x) else one D|))," (*abbreviation "ring_hom D D == (|carrier = hom_completion D D, mult = op o, one = λx::'a. if x ∈ carrier D then id x else one D, zero = λx::'a. if x ∈ carrier D then one D else one D, add = λ(f::'a => 'a) (g::'a => 'a) x::'a. if x ∈ carrier D then mult D (f x) (g x) else one D|)),"*) lemma ring_nat_pow_equiv_funpow: assumes diff_group_add: "diff_group_add (op -) (λx::'a::diff_group_add. - x) 0 (op +) diff" and f_hom_completion: "f ∈ hom_completion (diff_group_functor (λx::'a::diff_group_add. - x) (op -) 0 (op +) diff) (diff_group_functor (λx::'a. - x) (op -) 0 (op +) diff)" shows "f (^)ring_hom_compl (diff_group_functor (λx::'a::diff_group_add. - x) (op -) 0 (op +) diff) (n::nat) = f^n" (is "f (^)?R n = f^n") proof (induct n) case 0 show "f(^)?R (0::nat) = f^0" unfolding ring_hom_compl_def unfolding nat_pow_def unfolding diff_group_functor_def expand_fun_eq by auto next case Suc fix n :: nat assume hypo: "f (^)?R n = f^n" show "f (^)?R (Suc n) = f^(Suc n)" proof - have " f^(Suc n) = f o (f^n)" by simp also have "… = mult ?R (f (^)?R (1::nat)) (f (^)?R n)" using hypo analytic_part_local.monoid.nat_pow_1 [of ?R f] using f_hom_completion using diff_group_add.hom_completion_ring [OF diff_group_add] unfolding Ring.ring_def ring_hom_compl_def by simp also have "… = f (^)?R (1 + n)" using monoid.nat_pow_mult [of ?R f 1 n] using f_hom_completion diff_group_add.hom_completion_ring [OF diff_group_add] unfolding Ring.ring_def ring_hom_compl_def by simp also have "… = f (^)?R (Suc n)" by simp finally show ?thesis by simp qed qed text{*Equivalence between the @{text "uminus"} definition in the ring of endomorphisms, and the @{thm fun_Compl_def}*} lemma minus_ring_homo_equal_uminus_fun: assumes diff_group_add: "diff_group_add (op -) (λx::'a::diff_group_add. - x) 0 (op +) diff" and homo_ab_f: "homo_ab f" shows "\<ominus>ring_hom_compl (diff_group_functor (λx::'a::diff_group_add. - x) (op -) 0 (op +) diff) (f::'a::diff_group_add => 'a) = - f" (is "\<ominus>?R f = - f") using diff_group_add.hom_completion_ring [OF diff_group_add] using abelian_group.minus_equality [of ?R f "- f"] using homo_ab_is_hom_completion [OF homo_ab_f diff_group_add] using homo_ab_is_hom_completion [OF ab_group_add_impl_uminus_fun_closed [OF _ homo_ab_f]] using diff_group_add unfolding ring_hom_compl_def [of "diff_group_functor (λx::'a::diff_group_add. - x) (op -) 0 (op +) diff"] unfolding Ring.ring_def unfolding abelian_group_def unfolding diff_group_add_def unfolding ab_group_add_def unfolding ab_group_add_axioms_def unfolding fun_Compl_def unfolding plus_fun_def zero_fun_def unfolding diff_group_functor_def expand_fun_eq by auto lemma minus_ring_hom_completion_equal_uminus_fun: assumes diff_group_add: "diff_group_add (op -) (λx::'a::diff_group_add. - x) 0 (op +) diff" and f_hom_completion: "f ∈ hom_completion (diff_group_functor (λx::'a::diff_group_add. - x) (op -) 0 (op +) diff) (diff_group_functor (λx::'a. - x) (op -) 0 (op +) diff)" shows "\<ominus>ring_hom_compl (diff_group_functor (λx::'a::diff_group_add. - x) (op -) 0 (op +) diff) f = - f" (is "\<ominus>?R f = - f") using minus_ring_homo_equal_uminus_fun using hom_completion_equiv_homo_ab using diff_group_add using f_hom_completion by auto lemma α_in_hom_completion: assumes diff_group_add_pert_hom: "diff_group_add_pert_hom (op -) (λx::'a::diff_group_add_pert_hom. - x) 0 op + diff pert hom_oper" shows "α ∈ hom_completion (diff_group_functor (λx::'a::diff_group_add_pert_hom. - x) op - 0 op + diff) (diff_group_functor (λx::'a. - x) op - 0 op + diff)" (is "α ∈ hom_completion ?D ?D") proof - let ?R = "ring_hom_compl ?D" have diff_group_add: "diff_group_add op - uminus (0::'a) op + diff" using diff_group_add_pert_hom by (intro_locales) have delta_in_R: "pert ∈ carrier ?R" and h_in_R: "hom_oper ∈ carrier ?R" using diff_group_add_pert_hom unfolding ring_hom_compl_def unfolding reduction_class_ext_def unfolding diff_group_add_pert_hom_def unfolding diff_group_add_pert_def unfolding diff_group_add_pert_axioms_def unfolding diff_group_add_pert_hom_axioms_def unfolding hom_completion_def unfolding hom_def unfolding Pi_def unfolding completion_fun2_def completion_def unfolding diff_group_functor_def by auto have deltah_in_R: "pert o hom_oper ∈ carrier ?R" using delta_in_R using h_in_R using diff_group_add.hom_completion_ring [OF diff_group_add] using monoid.m_closed [of "?R" "pert" "hom_oper"] unfolding Ring.ring_def ring_hom_compl_def by simp show ?thesis using deltah_in_R using abelian_group.a_inv_closed [OF _ deltah_in_R] using diff_group_add.hom_completion_ring [OF diff_group_add] using minus_ring_hom_completion_equal_uminus_fun [of "pert o hom_oper", OF diff_group_add] unfolding ring_hom_compl_def α_def Ring.ring_def fun_Compl_def by simp qed lemma β_in_hom_completion: assumes diff_group_add_pert_hom: "diff_group_add_pert_hom op - (λx::'a::diff_group_add_pert_hom_bound_exist. - x) 0 op + diff pert hom_oper" shows "β ∈ hom_completion (diff_group_functor (λx::'a::diff_group_add_pert_hom_bound_exist. - x) op - 0 op + diff) (diff_group_functor (λx::'a. - x) op - 0 op + diff)" (is "β ∈ hom_completion ?D ?D") proof - let ?R = "ring_hom_compl ?D" have diff_group_add: "diff_group_add op - uminus (0::'a) op + diff" using diff_group_add_pert_hom by (intro_locales) have delta_in_R: "pert ∈ carrier ?R" and h_in_R: "hom_oper ∈ carrier ?R" using diff_group_add_pert_hom unfolding ring_hom_compl_def unfolding reduction_class_ext_def unfolding diff_group_add_pert_hom_def unfolding diff_group_add_pert_def unfolding diff_group_add_pert_axioms_def unfolding diff_group_add_pert_hom_axioms_def unfolding hom_completion_def unfolding hom_def unfolding Pi_def unfolding completion_fun2_def completion_def unfolding diff_group_functor_def by auto have hdelta_in_R: "hom_oper o pert ∈ carrier ?R" using delta_in_R using h_in_R using diff_group_add.hom_completion_ring [OF diff_group_add] using monoid.m_closed [of "?R" "hom_oper" "pert"] unfolding Ring.ring_def ring_hom_compl_def by simp show ?thesis using hdelta_in_R using abelian_group.a_inv_closed [OF _ hdelta_in_R] using diff_group_add.hom_completion_ring [OF diff_group_add] using minus_ring_hom_completion_equal_uminus_fun [of "hom_oper o pert", OF diff_group_add] unfolding ring_hom_compl_def β_def Ring.ring_def fun_Compl_def by simp qed text{*Our previous deinition of @{term "reduction_class_ext"} satisfies the definition of the locale @{term "local_nilpotent_term"}*} lemma reduction_class_ext_preserves_local_nilpotent_term: assumes reduction_class_ext_f_g: "reduction_class_ext (f::'a::diff_group_add_pert_hom_bound_exist => 'b::diff_group_add) g" shows "local_nilpotent_term (diff_group_functor (λx::'a::diff_group_add_pert_hom_bound_exist. - x) op - 0 op + diff) (ring_hom_compl (diff_group_functor (λx::'a. - x) op - 0 op + diff)) α (local_bound α)" (is "local_nilpotent_term ?D ?R α (local_bound α)") proof (intro_locales) have diff_group_add_pert_hom_bound_exist: "diff_group_add_pert_hom_bound_exist op - (λx::'a. - x) 0 op + diff pert hom_oper" using reduction_class_ext_f_g unfolding reduction_class_ext_def [of f g] by simp then have diff_group_add_pert_hom: "diff_group_add_pert_hom op - (λx::'a. - x) 0 op + diff pert hom_oper" unfolding diff_group_add_pert_hom_bound_exist_def by simp have diff_group_add: "diff_group_add op - (λx::'a. - x) 0 op + diff" using diff_group_add_pert_hom_bound_exist_impl_diff_group_add [OF diff_group_add_pert_hom_bound_exist] by simp show "monoid ?D" using diff_group_functor_preserves [OF diff_group_add] unfolding diff_group_def comm_group_def comm_monoid_def by fast show "comm_monoid_axioms ?D" using diff_group_functor_preserves [OF diff_group_add] unfolding diff_group_def comm_group_def comm_monoid_def by fast show "group_axioms ?D" using diff_group_functor_preserves [OF diff_group_add] unfolding diff_group_def comm_group_def group_def by simp show "diff_group_axioms ?D" using diff_group_functor_preserves [OF diff_group_add] unfolding diff_group_def by simp show "abelian_monoid ?R" using diff_group_add.hom_completion_ring [OF diff_group_add] unfolding ring_hom_compl_def Ring.ring_def abelian_group_def by simp show "abelian_group_axioms ?R" using diff_group_add.hom_completion_ring [OF diff_group_add] unfolding ring_hom_compl_def Ring.ring_def abelian_group_def by simp show "ring_axioms ?R" using diff_group_add.hom_completion_ring [OF diff_group_add] unfolding Ring.ring_def ring_hom_compl_def by simp show "monoid ?R" using diff_group_add.hom_completion_ring [OF diff_group_add] unfolding Ring.ring_def abelian_group_def ring_hom_compl_def by simp show "ring_endomorphisms_axioms ?D ?R" using diff_group_add.hom_completion_ring [OF diff_group_add] unfolding ring_hom_compl_def ring_endomorphisms_axioms_def by simp show "local_nilpotent_term_axioms ?D ?R α (local_bound α)" proof (unfold local_nilpotent_term_axioms_def, intro conjI) show alpha_in_R: "α ∈ carrier ?R" using α_in_hom_completion [OF diff_group_add_pert_hom] unfolding α_def Ring.ring_def ring_hom_compl_def by simp show "∀x ∈ carrier ?D. (α (^)?R (local_bound α x)) x = one ?D" proof (rule ballI) fix x assume x_in_D: "x ∈ carrier ?D" show "(α (^)?R (local_bound α x)) x = monoid.one ?D" proof - have "(α (^)?R (local_bound α x)) x = (α^(local_bound α x)) x" using ring_nat_pow_equiv_funpow [OF diff_group_add, of α] alpha_in_R unfolding ring_hom_compl_def by simp also have "(α ^ local_bound α (x::'a::diff_group_add_pert_hom_bound_exist)) x = 0" using α_locally_nilpotent [OF diff_group_add_pert_hom_bound_exist, of "x::'a"] by simp also have "… = one ?D" unfolding diff_group_functor_def by simp finally show ?thesis by simp qed qed show "∀x::'a. (local_bound α x) = (LEAST n::nat. (α (^)?R n) x = one ?D)" using diff_group_add_pert_hom_bound_exist_impl_local_bounded_func_alpha [OF diff_group_add_pert_hom_bound_exist] using local_bounded_func_impl_terminates_loop [of "α::'a => 'a"] using local_bound_correct [of "α::'a => 'a"] using ring_nat_pow_equiv_funpow [OF diff_group_add, of "α:: 'a => 'a"] using alpha_in_R unfolding ring_hom_compl_def diff_group_functor_def by auto qed qed text{*The following lemma states that the @{term reduction_class_ext} definition together with @{term local_bound_exists} satisifies the premises of the @{thm BPL.BPL}.*} text{*In addition to this result, we also have to prove later that the definitions given in this file for @{term f'}, @{term g'}, @{term Φ}, are equivalent to the ones given inside of the local BPL*} lemma reduction_class_ext_preserves_BPL: assumes r_c_e: "reduction_class_ext (f::'a::diff_group_add_pert_hom_bound_exist => 'b::diff_group_add) g" shows "BPL (diff_group_functor (λx::'a::diff_group_add_pert_hom_bound_exist. - x) op - 0 op + diff) (ring_hom_compl (diff_group_functor (λx::'a. - x) op - 0 op + diff)) hom_oper (diff_group_functor (λx::'b::diff_group_add. - x) op - 0 op + diff) f g pert (local_bound α)" (is "BPL ?D ?R hom_oper ?C f g pert (local_bound α)") proof (intro_locales) have diff_group_add_pert_hom_bound_exist: "diff_group_add_pert_hom_bound_exist op - (λx::'a. - x) 0 op + diff pert hom_oper" using r_c_e unfolding reduction_class_ext_def [of f g] .. have diff_group_add: "diff_group_add op - (λx::'a. - x) 0 op + diff" using diff_group_add_pert_hom_bound_exist_impl_diff_group_add [OF diff_group_add_pert_hom_bound_exist] . show "monoid ?D" using diff_group_functor_preserves [OF diff_group_add] unfolding diff_group_def comm_group_def unfolding comm_monoid_def by fast show "comm_monoid_axioms ?D" using diff_group_functor_preserves [OF diff_group_add] unfolding diff_group_def comm_group_def unfolding comm_monoid_def by fast show "group_axioms ?D" using diff_group_functor_preserves [OF diff_group_add] unfolding diff_group_def comm_group_def group_def by fast show "diff_group_axioms ?D" using diff_group_functor_preserves [OF diff_group_add] unfolding diff_group_def .. have diff_group_add_C: "diff_group_add op - (λx::'b. - x) 0 op + diff" using r_c_e unfolding reduction_class_ext_def by simp show "monoid ?C" using diff_group_functor_preserves [OF diff_group_add_C] unfolding diff_group_def unfolding comm_group_def unfolding comm_monoid_def by fast show "comm_monoid_axioms ?C" using diff_group_functor_preserves [OF diff_group_add_C] unfolding diff_group_def unfolding comm_group_def unfolding comm_monoid_def by fast show "group_axioms ?C" using diff_group_functor_preserves [OF diff_group_add_C] unfolding diff_group_def unfolding comm_group_def unfolding group_def by fast show "diff_group_axioms ?C" using diff_group_functor_preserves [OF diff_group_add_C] unfolding diff_group_def by fast show "abelian_monoid ?R" using diff_group_add.hom_completion_ring [OF diff_group_add] unfolding ring_hom_compl_def unfolding Ring.ring_def unfolding abelian_group_def by fast show "abelian_group_axioms ?R" using diff_group_add.hom_completion_ring [OF diff_group_add] unfolding Ring.ring_def unfolding abelian_group_def unfolding ring_hom_compl_def by fast show "ring_axioms ?R" using diff_group_add.hom_completion_ring [OF diff_group_add] unfolding ring_hom_compl_def unfolding Ring.ring_def by fast show "monoid ?R" using diff_group_add.hom_completion_ring [OF diff_group_add] unfolding Ring.ring_def unfolding abelian_group_def unfolding ring_hom_compl_def by fast show "ring_endomorphisms_axioms ?D ?R" using diff_group_add.hom_completion_ring [OF diff_group_add] unfolding ring_hom_compl_def unfolding ring_endomorphisms_axioms_def by fast show "lemma_2_2_14_axioms ?D ?R (λx. h x)" proof (unfold lemma_2_2_14_axioms_def ring_hom_compl_def, simp, intro conjI) show "hom_oper ∈ hom_completion ?D ?D" using r_c_e unfolding reduction_class_ext_def unfolding diff_group_add_pert_hom_bound_exist_def unfolding diff_group_add_pert_hom_def unfolding diff_group_add_pert_hom_axioms_def unfolding hom_completion_def unfolding hom_def unfolding Pi_def unfolding completion_fun2_def unfolding completion_def unfolding diff_group_functor_def by simp show "(λx. h x) o (λx. h x) = (λx::'a. one ?D)" using r_c_e unfolding reduction_class_ext_def unfolding diff_group_add_pert_hom_bound_exist_def unfolding diff_group_add_pert_hom_def unfolding diff_group_add_pert_hom_axioms_def unfolding zero_fun_def unfolding diff_group_functor_def by simp show "(λx. h x) o diff_group.diff ?D o (λx. h x) = (λx. h x)" unfolding diff_group_functor_def apply simp using hdh_eq_h [OF r_c_e] . qed show "reduction_axioms ?D ?C f g (λx. h x)" using reduction_class_ext_preserves_reduction [OF r_c_e] unfolding reduction_def by fast show "alpha_beta_axioms ?D (λx. δ x)" using diff_group_add_pert_hom_bound_exist_preserves_pert [OF diff_group_add_pert_hom_bound_exist] unfolding alpha_beta_axioms_def . show "local_nilpotent_term_axioms ?D ?R (\<ominus>?R mult ?R (λx. δ x) (λx. h x)) (local_bound α)" proof - have delta_in_R: "(λx. δ x) ∈ carrier ?R" and h_in_R: "(λx. h x) ∈ carrier ?R" using r_c_e unfolding ring_hom_compl_def unfolding reduction_class_ext_def unfolding diff_group_add_pert_hom_bound_exist_def unfolding diff_group_add_pert_hom_def unfolding diff_group_add_pert_hom_axioms_def unfolding diff_group_add_pert_def unfolding diff_group_add_pert_axioms_def unfolding hom_completion_def unfolding hom_def unfolding Pi_def unfolding completion_fun2_def unfolding completion_def unfolding diff_group_functor_def by simp_all have deltah_in_R: "(λx. δ x) o (λx. h x) ∈ carrier ?R" using delta_in_R h_in_R using diff_group_add.hom_completion_ring [OF diff_group_add] using monoid.m_closed [of ?R "λx. δ x" "λx. h x"] unfolding ring_hom_compl_def unfolding Ring.ring_def by simp have minus_eq: "(\<ominus>?R mult ?R (λx. δ x) (λx. h x)) = - ((λx. δ x) o (λx. h x))" using deltah_in_R using diff_group_add.hom_completion_ring [OF diff_group_add] using abelian_group.a_inv_closed [OF _ deltah_in_R] using minus_ring_hom_completion_equal_uminus_fun [OF diff_group_add, of "(λx. δ x) o (λx. h x)"] unfolding ring_hom_compl_def by simp show ?thesis using reduction_class_ext_preserves_local_nilpotent_term [OF r_c_e] unfolding minus_eq unfolding local_nilpotent_term_def unfolding α_def unfolding fun_Compl_def unfolding o_apply .. qed qed text{*The definition of @{term reduction_class_ext} satisfies the definition of the locale @{term "lemma_2_2_15"}.*} lemma reduction_class_ext_preserves_lemma_2_2_15: assumes r_c_e: "reduction_class_ext (f::'a::diff_group_add_pert_hom_bound_exist => 'b::diff_group_add) g" shows "lemma_2_2_15 (diff_group_functor (λx::'a::diff_group_add_pert_hom_bound_exist. - x) op - 0 op + diff) (ring_hom_compl (diff_group_functor (λx::'a. - x) op - 0 op + diff)) hom_oper (diff_group_functor (λx::'b::diff_group_add. - x) op - 0 op + diff) f g pert (local_bound α)" using reduction_class_ext_preserves_BPL [OF r_c_e] unfolding BPL_def unfolding lemma_2_2_17_def unfolding proposition_2_2_16_def .. text{*The definition of @{term reduction_class_ext} satisfies the definiton of the locale @{term local_nilpotent_alpha}*} lemma reduction_class_ext_preserves_local_nilpotent_alpha: assumes r_c_e: "reduction_class_ext (f::'a::diff_group_add_pert_hom_bound_exist => 'b::diff_group_add) g" shows "local_nilpotent_alpha (diff_group_functor (λx::'a::diff_group_add_pert_hom_bound_exist. - x) op - 0 op + diff) (ring_hom_compl (diff_group_functor (λx::'a. - x) op - 0 op + diff)) (diff_group_functor (λx::'b::diff_group_add. - x) op - 0 op + diff) f g hom_oper pert (local_bound α)" using reduction_class_ext_preserves_BPL [OF r_c_e] unfolding BPL_def unfolding lemma_2_2_17_def unfolding proposition_2_2_16_def unfolding lemma_2_2_15_def by fast text{*The definition @{term "(λx::'a::diff_group_add_pert_hom_bound_exist. fin_sum α (local_bound α x) x)"} in @{term reduction_class_ext} is equivalent to the previous definition of @{term [locale=local_nilpotent_term] power_series} in locale @{term local_nilpotent_term}.*} lemma reduction_class_ext_preserves_power_series: assumes r_c_e: "reduction_class_ext (f::'a::diff_group_add_pert_hom_bound_exist => 'b::diff_group_add) g" shows "local_nilpotent_term.power_series (diff_group_functor (λx::'a::diff_group_add_pert_hom_bound_exist. - x) op - 0 op + diff) (ring_hom_compl (diff_group_functor (λx::'a. - x) op - 0 op + diff)) α (local_bound α) = (λx::'a. fin_sum α (local_bound α x) x)" (is "local_nilpotent_term.power_series ?D ?R α (local_bound α) = (λx. fin_sum α (local_bound α x) x)") proof (unfold expand_fun_eq, rule allI) fix x :: 'a show "local_nilpotent_term.power_series ?D ?R α (local_bound α) x = fin_sum α (local_bound α x) x" proof - have local_nilpotent_term: "local_nilpotent_term ?D ?R α (local_bound α)" using reduction_class_ext_preserves_local_nilpotent_term [OF r_c_e] . have diff_group_add_pert_hom_bound_exist: "diff_group_add_pert_hom_bound_exist op - (λx::'a. - x) 0 op + diff pert hom_oper" using r_c_e unfolding reduction_class_ext_def [of f g] .. have diff_group_add_pert_hom: "diff_group_add_pert_hom op - (λx::'a. - x) 0 op + diff pert hom_oper" using diff_group_add_pert_hom_bound_exist by (intro_locales) have diff_group_add: "diff_group_add op - (λx::'a. - x) 0 op + diff" using diff_group_add_pert_hom_bound_exist_impl_diff_group_add [OF diff_group_add_pert_hom_bound_exist] . have "local_nilpotent_term.power_series ?D ?R α (local_bound α) x = (\<Otimes>?Di::nat∈{..local_bound α x}. (α (^)?R i) x)" using local_nilpotent_term.power_series_def [OF local_nilpotent_term] by simp also have "(\<Otimes>?Di::nat∈{..local_bound α x}. (α (^)?R i) x) = (\<Otimes>?Di::nat∈{..local_bound α x}. (α^i) x)" unfolding ring_nat_pow_equiv_funpow [OF diff_group_add α_in_hom_completion [OF diff_group_add_pert_hom]] .. also have "… = fin_sum α (local_bound α x) x" proof (induct "local_bound α x") case 0 { have "(\<Otimes>?Di::nat∈{..0::nat}. (α^i) x) = (α^(0::nat)) x" using comm_monoid.finprod_0 [of ?D] using diff_group_functor_preserves [OF diff_group_add] unfolding diff_group_def unfolding comm_group_def unfolding diff_group_functor_def by simp also have "… = fin_sum α (0::nat) x" by simp finally show "(\<Otimes>?Di::nat∈{..0::nat}. (α^i) x) = fin_sum α (0::nat) x" . } next case Suc { fix n :: nat assume hypo: "(\<Otimes>?Di::nat∈{..n}. (α^i) x) = fin_sum α n x" have "(\<Otimes>?Di::nat∈{..Suc n}. (α^i) x) = monoid.mult ?D ((α^(Suc n)) x) (\<Otimes>?Di::nat∈{..n}. (α^i) x)" using comm_monoid.finprod_Suc [of ?D] using diff_group_functor_preserves [OF diff_group_add] unfolding diff_group_def unfolding comm_group_def unfolding diff_group_functor_def by simp also have "… = monoid.mult ?D ((α^(Suc n)) x) (fin_sum α n x)" unfolding hypo .. also have "… = ((α^(Suc n)) x) + (fin_sum α n x)" unfolding diff_group_functor_def unfolding monoid.select_convs (1) .. also have "… = ((α^(Suc n)) + (fin_sum α (n))) x" unfolding plus_fun_def [of "((α::'a => 'a)^(Suc n))" "(fin_sum α (n))"] .. also have "… = (fin_sum α (Suc n) x)" unfolding fin_sum.simps (2) .. finally show "(\<Otimes>?Di::nat∈{..Suc (n::nat)}. (α^i) (x::'a)) = fin_sum α (Suc n) x" . } qed finally show ?thesis . qed qed text{*The definition of @{thm Φ_def} is equivalent to the previous definition of @{term [locale=local_nilpotent_alpha] Φ} in @{term "locale_nilpotent_alpha"}*} lemma reduction_class_ext_preserves_Φ: assumes r_c_e: "reduction_class_ext (f::'a::diff_group_add_pert_hom_bound_exist => 'b::diff_group_add) g" shows "local_nilpotent_alpha.Φ (diff_group_functor (λx::'a::diff_group_add_pert_hom_bound_exist. - x) op - 0 op + diff) (ring_hom_compl (diff_group_functor (λx::'a. - x) op - 0 op + diff)) hom_oper pert (local_bound α) = Φ" (is "local_nilpotent_alpha.Φ ?D ?R hom_oper pert (local_bound α) = Φ") unfolding local_nilpotent_alpha.phi_def [OF reduction_class_ext_preserves_local_nilpotent_alpha [OF r_c_e]] unfolding local_nilpotent_term.power_series_def [OF _, of x] proof - show "local_nilpotent_term.power_series ?D ?R (\<ominus>?R monoid.mult ?R pert hom_oper) (local_bound α) = Φ" proof - have "local_nilpotent_term.power_series ?D ?R (\<ominus>?R monoid.mult ?R (λx. δ x) (λx. h x)) (local_bound α) = local_nilpotent_term.power_series ?D ?R α (local_bound α)" proof - have diff_group_add_pert_hom_bound_exist: "diff_group_add_pert_hom_bound_exist op - (λx::'a. - x) 0 op + diff pert hom_oper" using r_c_e unfolding reduction_class_ext_def [of f g] by fast have diff_group_add: "diff_group_add op - (λx::'a. - x) 0 op + diff" using diff_group_add_pert_hom_bound_exist_impl_diff_group_add [OF diff_group_add_pert_hom_bound_exist] . have delta_in_R: "pert ∈ carrier ?R" and h_in_R: "(λx. h x) ∈ carrier ?R" using r_c_e unfolding ring_hom_compl_def unfolding reduction_class_ext_def unfolding diff_group_add_pert_hom_bound_exist_def unfolding diff_group_add_pert_hom_def unfolding diff_group_add_pert_hom_axioms_def unfolding diff_group_add_pert_def unfolding diff_group_add_pert_axioms_def unfolding hom_completion_def unfolding hom_def unfolding Pi_def unfolding completion_fun2_def unfolding completion_def unfolding diff_group_functor_def by auto have deltah_in_R: "(λx. δ x) o (λx. h x) ∈ carrier ?R" using delta_in_R h_in_R using diff_group_add.hom_completion_ring [OF diff_group_add] using monoid.m_closed [of ?R "(λx. δ x)" "(λx. h x)"] unfolding Ring.ring_def ring_hom_compl_def by simp have minus_equiv: "\<ominus>?R mult ?R (λx. δ x) (λx. h x) = α" using abelian_group.a_inv_closed [OF _ deltah_in_R] using diff_group_add.hom_completion_ring [OF diff_group_add] using minus_ring_hom_completion_equal_uminus_fun [of "(λx. δ x) o (λx. h x)", OF diff_group_add] using deltah_in_R unfolding α_def unfolding ring_hom_compl_def unfolding fun_Compl_def by simp show ?thesis unfolding minus_equiv .. qed also have "… = (λx::'a. (fin_sum α (local_bound α x)) x)" unfolding reduction_class_ext_preserves_power_series [OF r_c_e] .. also have "… = Φ" unfolding Φ_def α_def .. finally show ?thesis . qed qed text{*Now, as a corollary, we prove that the previous definition of the output @{term [locale=BPL] "f'"} of the @{text "BPL"}, is equivalent to the definition @{term "f o Φ"}.*} corollary reduction_class_ext_preserves_output_f: assumes r_c_e: "reduction_class_ext (f::'a::diff_group_add_pert_hom_bound_exist => 'b::diff_group_add) g" shows "f o local_nilpotent_alpha.Φ (diff_group_functor (λx::'a::diff_group_add_pert_hom_bound_exist. - x) op - 0 op + diff) (ring_hom_compl (diff_group_functor (λx::'a. - x) op - 0 op + diff)) hom_oper pert (local_bound α) = f o Φ" unfolding reduction_class_ext_preserves_Φ [OF r_c_e] .. text{*Now, as a corollary, we prove that the previous definition of the output @{term "h'"} of the @{text "BPL"}, is equivalent to the definition @{thm "h'_def"}.*} corollary reduction_class_ext_preserves_output_h: assumes r_c_e: "reduction_class_ext (f::'a::diff_group_add_pert_hom_bound_exist => 'b::diff_group_add) g" shows "lemma_2_2_15.h' (diff_group_functor (λx::'a::diff_group_add_pert_hom_bound_exist. - x) op - 0 op + diff) (ring_hom_compl (diff_group_functor (λx::'a. - x) op - 0 op + diff)) hom_oper pert (local_bound α) = h'" unfolding lemma_2_2_15.h'_def [OF reduction_class_ext_preserves_lemma_2_2_15 [OF r_c_e]] unfolding reduction_class_ext_preserves_Φ [OF r_c_e] unfolding h'_def unfolding ring_hom_compl_def unfolding monoid.select_convs (1) .. text{*The definition of @{term "reduction_class_ext"} satisfies the definition of the locale @{text "alpha_beta"}*} lemma reduction_class_ext_preserves_alpha_beta: assumes r_c_e: "reduction_class_ext (f::'a::diff_group_add_pert_hom_bound_exist => 'b::diff_group_add) g" shows "alpha_beta (diff_group_functor (λx::'a. - x) op - 0 op + diff) (ring_hom_compl (diff_group_functor (λx::'a::diff_group_add_pert_hom_bound_exist. - x) op - 0 op + diff)) (diff_group_functor (λx::'b::diff_group_add. - x) op - 0 op + diff) f g (λx. h x) (λx. δ x)" using reduction_class_ext_preserves_BPL [OF r_c_e] unfolding BPL_def unfolding lemma_2_2_17_def unfolding proposition_2_2_16_def unfolding lemma_2_2_15_def unfolding lemma_2_2_14_def unfolding local_nilpotent_alpha_def by fast text{*The new definition of the power series over @{thm "β_def"} is equivalent to the definition of the power series over @{term "β"} in the previous version.*} lemma reduction_class_ext_preserves_beta_bound: assumes r_c_e: "reduction_class_ext (f::'a::diff_group_add_pert_hom_bound_exist => 'b::diff_group_add) g" shows "local_bounded_func (β::'a::diff_group_add_pert_hom_bound_exist => 'a)" proof - let ?D = "(diff_group_functor (λx::'a. - x) op - 0 op + diff)" let ?R = "ring_hom_compl ?D" obtain "bound_psi" where local_nilp_term: "local_nilpotent_term ?D ?R (alpha_beta.β ?R hom_oper pert) bound_psi" using local_nilpotent_alpha.bound_psi_exists [OF reduction_class_ext_preserves_local_nilpotent_alpha [OF r_c_e]] by auto have diff_group_add_pert_hom_bound_exist: "diff_group_add_pert_hom_bound_exist op - (λx::'a. - x) 0 op + diff pert hom_oper" using r_c_e unfolding reduction_class_ext_def [of f g] by fast have diff_group_add: "diff_group_add op - (λx::'a. - x) 0 op + diff" using diff_group_add_pert_hom_bound_exist_impl_diff_group_add [OF diff_group_add_pert_hom_bound_exist] . have delta_in_R: "pert ∈ carrier ?R" and h_in_R: "hom_oper ∈ carrier ?R" using r_c_e unfolding ring_hom_compl_def unfolding reduction_class_ext_def unfolding diff_group_add_pert_hom_bound_exist_def unfolding diff_group_add_pert_hom_def unfolding diff_group_add_pert_hom_axioms_def unfolding diff_group_add_pert_def unfolding diff_group_add_pert_axioms_def unfolding hom_completion_def unfolding hom_def unfolding Pi_def unfolding completion_fun2_def unfolding completion_def unfolding diff_group_functor_def by auto have hdelta_in_R: "(λx. h x) o (λx. δ x) ∈ carrier ?R" using delta_in_R h_in_R using diff_group_add.hom_completion_ring [OF diff_group_add] using monoid.m_closed [of ?R "(λx. h x)" "(λx. δ x)"] unfolding Ring.ring_def ring_hom_compl_def by simp have β_equiv: "alpha_beta.β ?R (λx. h x) (λx. δ x) = β" proof - have "alpha_beta.β ?R (λx. h x) (λx. δ x) = \<ominus>?R monoid.mult ?R (λx. h x) (λx. δ x)" unfolding alpha_beta.beta_def [OF reduction_class_ext_preserves_alpha_beta [OF r_c_e]] .. also have "\<ominus>?R monoid.mult ?R (λx. h x) (λx. δ x) = - ((λx. h x) o (λx. δ x))" using hdelta_in_R using minus_ring_hom_completion_equal_uminus_fun [OF diff_group_add] unfolding ring_hom_compl_def by simp finally show ?thesis unfolding β_def . qed have lnt: "local_nilpotent_term ?D ?R β bound_psi" unfolding sym [OF β_equiv] using local_nilp_term . have bound_ex:"∀x::'a. ∃n::nat. (β (^)?R n) x = 0" using lnt unfolding local_nilpotent_term_def unfolding local_nilpotent_term_axioms_def unfolding diff_group_functor_def by auto have "∀x::'a. ∃n::nat. (β ^ n) x = 0" using ring_nat_pow_equiv_funpow [OF diff_group_add β_in_hom_completion] using diff_group_add_pert_hom_bound_exist using bound_ex unfolding diff_group_add_pert_hom_bound_exist_def by simp then show ?thesis unfolding local_bounded_func_def . qed lemma reduction_class_ext_preserves_power_series_β: assumes r_c_e: "reduction_class_ext (f::'a::diff_group_add_pert_hom_bound_exist => 'b::diff_group_add) g" shows "local_nilpotent_term.power_series (diff_group_functor (λx::'a::diff_group_add_pert_hom_bound_exist. - x) op - 0 op + diff) (ring_hom_compl (diff_group_functor (λx::'a. - x) op - 0 op + diff)) β (local_bound β) = (λx::'a. fin_sum β (local_bound β x) x)" (is "local_nilpotent_term.power_series ?D ?R β (local_bound β) = (λx::'a. fin_sum β (local_bound β x) x)") proof (unfold expand_fun_eq, rule allI) fix x :: 'a show "local_nilpotent_term.power_series ?D ?R β (local_bound β) x = fin_sum β (local_bound β x) x" proof - have diff_group_add_pert_hom_bound_exist: "diff_group_add_pert_hom_bound_exist op - (λx::'a. - x) 0 op + diff pert hom_oper" using r_c_e unfolding reduction_class_ext_def [of f g] by fast have diff_group_add: "diff_group_add op - (λx::'a. - x) 0 op + diff" using diff_group_add_pert_hom_bound_exist_impl_diff_group_add [OF diff_group_add_pert_hom_bound_exist] . have delta_in_R: "pert ∈ carrier ?R" and h_in_R: "hom_oper ∈ carrier ?R" using r_c_e unfolding reduction_class_ext_def unfolding ring_hom_compl_def unfolding diff_group_add_pert_hom_bound_exist_def unfolding diff_group_add_pert_hom_def unfolding diff_group_add_pert_hom_axioms_def unfolding diff_group_add_pert_def unfolding diff_group_add_pert_axioms_def unfolding hom_completion_def unfolding hom_def unfolding Pi_def unfolding completion_fun2_def unfolding completion_def unfolding diff_group_functor_def by auto have hdelta_in_R: "(λx. h x) o (λx. δ x) ∈ carrier ?R" using delta_in_R h_in_R using diff_group_add.hom_completion_ring [OF diff_group_add] using monoid.m_closed [of ?R "(λx. h x)" "(λx. δ x)"] unfolding ring_hom_compl_def unfolding Ring.ring_def by simp have β_equiv: "alpha_beta.β ?R (λx. h x) (λx. δ x) = β" proof - have "alpha_beta.β ?R (λx. h x) (λx. δ x) = \<ominus>?R monoid.mult ?R (λx. h x) (λx. δ x)" unfolding alpha_beta.beta_def [OF reduction_class_ext_preserves_alpha_beta [OF r_c_e]] .. also have "\<ominus>?R monoid.mult ?R (λx. h x) (λx. δ x) = - ((λx. h x) o (λx. δ x))" using hdelta_in_R using minus_ring_hom_completion_equal_uminus_fun [of "(λx. h x) o (λx. δ x)", OF diff_group_add] unfolding ring_hom_compl_def by simp finally show ?thesis unfolding β_def . qed have bound_equiv: "(λx. LEAST n. (β (^)?R n) x = one ?D) = (local_bound β)" using local_bounded_func_impl_local_bound_is_Least [OF reduction_class_ext_preserves_beta_bound [OF r_c_e]] using ring_nat_pow_equiv_funpow [OF diff_group_add β_in_hom_completion] using diff_group_add_pert_hom_bound_exist unfolding diff_group_add_pert_hom_bound_exist_def unfolding diff_group_functor_def by (simp add: expand_fun_eq) have local_nilpotent_term: "local_nilpotent_term ?D ?R β (local_bound β)" using local_nilpotent_alpha.nilp_alpha_nilp_beta [OF reduction_class_ext_preserves_local_nilpotent_alpha [OF r_c_e]] using local_nilpotent_alpha.nilp_alpha_nilp_beta using β_equiv using bound_equiv by simp have "local_nilpotent_term.power_series ?D ?R β (local_bound β) x = (\<Otimes>?Di::nat∈{..local_bound β x}. (β (^)?R i) x)" unfolding local_nilpotent_term.power_series_def [OF local_nilpotent_term] .. also have "(\<Otimes>?Di::nat∈{..local_bound β x}. (β (^)?R i) x) = (\<Otimes>?Di::nat∈{..local_bound β x}. (β^i) x)" using ring_nat_pow_equiv_funpow [OF diff_group_add β_in_hom_completion] using diff_group_add_pert_hom_bound_exist unfolding diff_group_add_pert_hom_bound_exist_def by simp also have "… = fin_sum β (local_bound β x) x" proof (induct "local_bound β x") case 0 { have "(\<Otimes>?Di::nat∈{..0::nat}. (β^i) x) = (β^(0::nat)) x" using comm_monoid.finprod_0 [of ?D] using diff_group_functor_preserves [OF diff_group_add] unfolding diff_group_def unfolding comm_group_def unfolding diff_group_functor_def by simp also have "… = fin_sum β (0::nat) x" by simp finally show "(\<Otimes>?Di::nat∈{..0::nat}. (β^i) x) = fin_sum β (0::nat) x" by simp } next case Suc { fix n :: nat assume hypo: "(\<Otimes>?Di::nat∈{..n}. (β^i) x) = fin_sum β n x" have "(\<Otimes>?Di::nat∈{..Suc n}. (β^i) x) = mult ?D ((β^(Suc n)) x) (\<Otimes>?Di::nat∈{..n}. (β^i) x)" using comm_monoid.finprod_Suc [of ?D] using diff_group_functor_preserves [OF diff_group_add] unfolding diff_group_def unfolding comm_group_def unfolding diff_group_functor_def by simp also have "… = monoid.mult ?D ((β^(Suc n)) x) (fin_sum β n x)" unfolding hypo .. also have "… = ((β^(Suc n)) x) + (fin_sum β n x)" unfolding diff_group_functor_def unfolding monoid.select_convs (1) .. also have "… = ((β^(Suc n)) + (fin_sum β (n))) x" unfolding plus_fun_def [of "((β::'a => 'a)^(Suc n))" "(fin_sum β (n))"] .. also have "… = (fin_sum β (Suc n) x)" by simp finally show "(\<Otimes>?Di::nat∈{..Suc (n::nat)}. (β^i) (x::'a)) = fin_sum β (Suc n) x" . } qed finally show ?thesis by simp qed qed text{*As well as the equivalence between both definitions of the power series, also the definitions of the bounds are equivalent.*} lemma reduction_class_ext_preserves_bound_psi: assumes r_c_e: "reduction_class_ext (f::'a::diff_group_add_pert_hom_bound_exist => 'b::diff_group_add) g" shows "local_nilpotent_alpha.bound_psi (diff_group_functor (λx::'a::diff_group_add_pert_hom_bound_exist. - x) op - 0 op + diff) (ring_hom_compl (diff_group_functor (λx::'a. - x) op - 0 op + diff)) hom_oper pert = (local_bound β)" (is "local_nilpotent_alpha.bound_psi ?D ?R (λx. h x) (λx. δ x) = (local_bound β)") proof - have diff_group_add_pert_hom_bound_exist: "diff_group_add_pert_hom_bound_exist op - (λx::'a::diff_group_add_pert_hom_bound_exist. - x) 0 op + diff pert hom_oper" using r_c_e unfolding reduction_class_ext_def [of f g] by fast have diff_group_add: "diff_group_add op - (λx::'a. - x) 0 op + diff" using diff_group_add_pert_hom_bound_exist_impl_diff_group_add [OF diff_group_add_pert_hom_bound_exist] . have delta_in_R: "pert ∈ carrier ?R" and h_in_R: "hom_oper ∈ carrier ?R" using r_c_e unfolding reduction_class_ext_def unfolding ring_hom_compl_def unfolding diff_group_add_pert_hom_bound_exist_def unfolding diff_group_add_pert_hom_def unfolding diff_group_add_pert_hom_axioms_def unfolding diff_group_add_pert_def unfolding diff_group_add_pert_axioms_def unfolding hom_completion_def unfolding hom_def unfolding Pi_def unfolding completion_fun2_def unfolding completion_def unfolding diff_group_functor_def by auto have hdelta_in_R: "(λx. h x) o (λx. δ x) ∈ carrier ?R" using delta_in_R h_in_R using diff_group_add.hom_completion_ring [OF diff_group_add] using monoid.m_closed [of ?R "(λx. h x)" "(λx. δ x)"] unfolding Ring.ring_def ring_hom_compl_def by simp have "local_nilpotent_alpha.bound_psi ?D ?R (λx. h x) (λx. δ x) = (λx::'a. LEAST n::nat. (alpha_beta.β ?R (λx. h x) (λx. δ x) (^)?R n) x = one ?D)" using local_nilpotent_alpha.bound_psi_def [OF reduction_class_ext_preserves_local_nilpotent_alpha [OF r_c_e]] by simp also have "… = (λx::'a. LEAST n::nat. (β (^)?R n) x = one ?D)" proof - have β_equiv: "alpha_beta.β ?R (λx. h x) (λx. δ x) = β" proof - have "alpha_beta.β ?R (λx. h x) (λx. δ x) = \<ominus>?R mult ?R (λx. h x) (λx. δ x)" unfolding alpha_beta.beta_def [OF reduction_class_ext_preserves_alpha_beta [OF r_c_e]] .. also have "\<ominus>?R monoid.mult ?R (λx. h x) (λx. δ x) = - ((λx. h x) o (λx. δ x))" using hdelta_in_R using minus_ring_hom_completion_equal_uminus_fun [of "(λx. h x) o (λx. δ x)", OF diff_group_add] unfolding ring_hom_compl_def by simp finally show ?thesis unfolding β_def . qed then show ?thesis by simp qed also have "… = (λx::'a. LEAST n::nat. (β (^)?R n) x = (0::'a))" unfolding diff_group_functor_def unfolding monoid.select_convs .. also have "… = (λx::'a. LEAST n::nat. (β^n) x = (0::'a))" using ring_nat_pow_equiv_funpow [OF diff_group_add β_in_hom_completion] using diff_group_add_pert_hom_bound_exist unfolding diff_group_add_pert_hom_bound_exist_def by simp also have bound_equiv: "… = (local_bound β)" unfolding expand_fun_eq unfolding local_bounded_func_impl_local_bound_is_Least [OF reduction_class_ext_preserves_beta_bound [OF r_c_e]] by fast finally show ?thesis . qed text{*From the equivalence betwen the power series and the equality of the bounds, it follows the equivalence between the old and the new definition of @{term [locale=BPL] "Ψ"}*} lemma reduction_class_ext_preserves_Ψ: assumes r_c_e: "reduction_class_ext (f::'a::diff_group_add_pert_hom_bound_exist => 'b::diff_group_add) g" shows "local_nilpotent_alpha.Ψ (diff_group_functor (λx::'a::diff_group_add_pert_hom_bound_exist. - x) op - 0 op + diff) (ring_hom_compl (diff_group_functor (λx::'a. - x) op - 0 op + diff)) hom_oper pert = Ψ" (is "local_nilpotent_alpha.Ψ ?D ?R (λx. h x) (λx. δ x) = Ψ") proof - have diff_group_add_pert_hom_bound_exist: "diff_group_add_pert_hom_bound_exist op - (λx::'a::diff_group_add_pert_hom_bound_exist. - x) 0 op + diff pert hom_oper" using r_c_e unfolding reduction_class_ext_def [of f g] by fast have diff_group_add: "diff_group_add op - (λx::'a. - x) 0 op + diff" using diff_group_add_pert_hom_bound_exist_impl_diff_group_add [OF diff_group_add_pert_hom_bound_exist] . have delta_in_R: "pert ∈ carrier ?R" and h_in_R: "hom_oper ∈ carrier ?R" using r_c_e unfolding reduction_class_ext_def unfolding ring_hom_compl_def unfolding diff_group_add_pert_hom_bound_exist_def unfolding diff_group_add_pert_hom_def unfolding diff_group_add_pert_hom_axioms_def unfolding diff_group_add_pert_def unfolding diff_group_add_pert_axioms_def unfolding hom_completion_def unfolding hom_def unfolding Pi_def unfolding completion_fun2_def unfolding completion_def unfolding diff_group_functor_def by auto have hdelta_in_R: "(λx. h x) o (λx. δ x) ∈ carrier ?R" using delta_in_R h_in_R using diff_group_add.hom_completion_ring [OF diff_group_add] using monoid.m_closed [of ?R "(λx. h x)" "(λx. δ x)"] unfolding ring_hom_compl_def Ring.ring_def by simp have "local_nilpotent_alpha.Ψ ?D ?R (λx. h x) (λx. δ x) = local_nilpotent_term.power_series ?D ?R (alpha_beta.β ?R (λx. h x) (λx. δ x)) (local_nilpotent_alpha.bound_psi ?D ?R (λx. h x) (λx. δ x))" unfolding local_nilpotent_alpha.psi_def [OF reduction_class_ext_preserves_local_nilpotent_alpha [OF r_c_e]] .. also have "… = local_nilpotent_term.power_series ?D ?R (alpha_beta.β ?R (λx. h x) (λx. δ x)) (local_bound β)" using reduction_class_ext_preserves_bound_psi [OF r_c_e] by simp also have "… = local_nilpotent_term.power_series ?D ?R β (local_bound β)" proof - have β_equiv: "alpha_beta.β ?R (λx. h x) (λx. δ x) = β" proof - have "alpha_beta.β ?R (λx. h x) (λx. δ x) = \<ominus>?R monoid.mult ?R (λx. h x) (λx. δ x)" using alpha_beta.beta_def [OF reduction_class_ext_preserves_alpha_beta [OF r_c_e]] . also have "\<ominus>?R monoid.mult ?R (λx. h x) (λx. δ x) = β" using hdelta_in_R using minus_ring_hom_completion_equal_uminus_fun [of "(λx. h x) o (λx. δ x)", OF diff_group_add] unfolding ring_hom_compl_def by (fold β_def, simp) finally show ?thesis . qed then show ?thesis by simp qed also have "… = (λx. fin_sum β (local_bound β x) x)" using reduction_class_ext_preserves_power_series_β [OF r_c_e] . also have "… = Ψ" unfolding Ψ_def β_def .. finally show ?thesis . qed text{*Now, as a corollary, we prove the equivalence between the previous definition of the output @{term g} of the BPL, and the one in this new approach*} corollary reduction_class_ext_preserves_output_g: assumes r_c_e: "reduction_class_ext (f::'a::diff_group_add_pert_hom_bound_exist => 'b::diff_group_add) g" shows "local_nilpotent_alpha.Ψ (diff_group_functor (λx::'a::diff_group_add_pert_hom_bound_exist. - x) op - 0 op + diff) (ring_hom_compl (diff_group_functor (λx::'a. - x) op - 0 op + diff)) hom_oper pert o g = Ψ o g" unfolding reduction_class_ext_preserves_Ψ [OF r_c_e] .. text{*It also follows the equality of the previous definition of @{term [locale=BPL] "differC'"} and the new definition, @{thm "dC'_def"}*} corollary reduction_class_ext_preserves_output_dC: assumes r_c_e: "reduction_class_ext (f::'a::diff_group_add_pert_hom_bound_exist => 'b::diff_group_add) g" shows "(λx::'b. if x ∈ carrier (diff_group_functor (λx::'b::diff_group_add. - x) op - 0 op + diff) then mult (diff_group_functor (λx::'b::diff_group_add. - x) op - 0 op + diff) (diff_group.diff (diff_group_functor (λx::'b::diff_group_add. - x) op - 0 op + diff) x) ((f o pert o (local_nilpotent_alpha.Ψ (diff_group_functor (λx::'a::diff_group_add_pert_hom_bound_exist. - x) op - 0 op + diff) (ring_hom_compl (diff_group_functor (λx::'a. - x) op - 0 op + diff)) hom_oper pert) o g) x) else one (diff_group_functor (λx::'b. - x) op - 0 op + diff)) = dC' f g" unfolding reduction_class_ext_preserves_Ψ [OF r_c_e] unfolding dC'_def [of f g] unfolding diff_group_functor_def unfolding plus_fun_def by simp text{*Now, from he previous equivalences, we are ready to give the proof of the @{thm [locale=BPL] "BPL"} with the new introduced definitions in terms of classes:*} lemma assumes reduction_class_ext_f_g: "reduction_class_ext (f::'a::diff_group_add_pert_hom_bound_exist => 'b::diff_group_add) g" shows "reduction (lemma_2_2_15.D' (diff_group_functor (λx::'a::diff_group_add_pert_hom_bound_exist. - x) op - 0 op + diff) (ring_hom_compl (diff_group_functor (λx::'a. - x) op - 0 op + diff)) pert) (|carrier = carrier (diff_group_functor (λx::'b::diff_group_add. - x) op - 0 op + diff), mult = mult (diff_group_functor (λx::'b. - x) op - 0 op + diff), one = one (diff_group_functor (λx::'b. - x) op - 0 op + diff), diff_group.diff = dC' f g|)), (f' f) (g' g) (h')" using BPL.BPL [OF reduction_class_ext_preserves_BPL [OF reduction_class_ext_f_g]] unfolding reduction_class_ext_preserves_output_f [OF reduction_class_ext_f_g] unfolding reduction_class_ext_preserves_output_g [OF reduction_class_ext_f_g] unfolding reduction_class_ext_preserves_output_h [OF reduction_class_ext_f_g] unfolding reduction_class_ext_preserves_output_dC [OF reduction_class_ext_f_g] unfolding f'_def [of f] unfolding g'_def [of g] unfolding h'_def unfolding dC'_def [of f g] . end
lemma
d (d x) = (0::'a)
lemma
α = - (diff_group_add_pert_class.pert o hom_oper)
lemma local_bound_gen_simp:
local_bound_gen f x ac =
(if x ≠ (0::'a) then local_bound_gen f (f x) (ac + 1) else ac)
lemma
local_bound f (0::'a) = 0
lemma
x ≠ (0::'a) ==> local_bound (λx. 0::'a) x = 1
lemma local_bounded_func_impl_terminates_loop:
local_bounded_func f = (∀x. terminates (λy. y ≠ (0::'a), f, x))
lemma LEAST_local_bound_0:
(LEAST n. (f ^ n) (0::'a) = (0::'a)) = 0
lemma local_bound_gen_correct:
terminates (λy. y ≠ (0::'a), f, x)
==> local_bound_gen f x m = m + (LEAST n. (f ^ n) x = (0::'a))
lemma local_bound_correct:
terminates (λy. y ≠ (0::'a), f, x)
==> local_bound f x = (LEAST n. (f ^ n) x = (0::'a))
lemma local_bounded_func_impl_local_bound_is_Least:
local_bounded_func f ==> local_bound f x = (LEAST n. (f ^ n) x = (0::'a))
lemma
local_bound' f x n =
(if (f ^ n) x = (0::'a) then n else local_bound' f x (Suc n))
lemma
While continue f s = (if continue s then While continue f (f s) else s)
lemma diff_group_add_pert_hom_bound_exist_impl_local_bounded_func_alpha:
diff_group_add_pert_hom_bound_exist op - uminus (0::'b) op +
diff_group_add_class.diff diff_group_add_pert_class.pert hom_oper
==> local_bounded_func α
lemma diff_group_add_pert_hom_bound_exist_impl_local_bound_is_Least:
diff_group_add_pert_hom_bound_exist op - uminus (0::'b) op +
diff_group_add_class.diff diff_group_add_pert_class.pert hom_oper
==> local_bound α x = (LEAST n. (α ^ n) x = (0::'a))
lemma monoid_add_impl_monoid:
monoid_add zero' plus'
==> monoid (| carrier = UNIV, mult = plus', one = zero' |)
lemma monoid_functor_preserv:
monoid_add zero' plus' ==> monoid (monoid_functor plus' zero')
lemma comm_monoid_add_impl_monoid_add:
comm_monoid_add zero' plus' ==> monoid_add zero' plus'
lemma comm_monoid_add_impl_monoid:
comm_monoid_add zero' plus'
==> monoid (| carrier = UNIV, mult = plus', one = zero' |)
lemma ab_group_add_impl_comm_monoid_add:
ab_group_add uminus' minus' zero' plus' ==> comm_monoid_add zero' plus'
lemma ab_group_class_impl_group:
ab_group_add uminus' minus' zero' plus'
==> group (| carrier = UNIV, mult = plus', one = zero' |)
lemma monoid_functor_preserv_group:
ab_group_add uminus' minus' zero' plus' ==> group (monoid_functor plus' zero')
lemma ab_group_add_impl_comm_group:
ab_group_add uminus' minus' zero' plus'
==> comm_group (| carrier = UNIV, mult = plus', one = zero' |)
lemma monoid_functor_preserv_ab_group:
ab_group_add uminus' minus' zero' plus'
==> comm_group (monoid_functor plus' zero')
lemma diff_group_add_impl_comm_group:
diff_group_add uminus' minus' zero' plus' diff'
==> comm_group (| carrier = UNIV, mult = plus', one = zero' |)
lemma diff_group_add_impl_diff_group:
diff_group_add uminus' minus' zero' prod' diff'
==> diff_group
(| carrier = UNIV, mult = prod', one = zero', diff_group.diff = diff' |)
lemma diff_group_functor_preserves:
diff_group_add minus' uminus' zero' prod' diff'
==> diff_group (diff_group_functor uminus' minus' zero' prod' diff')
lemma homo_ab_apply:
homo_ab f ==> f (a + b) = f a + f b
lemma homo_ab_preserves_hom_completion:
homo_ab f
==> f ∈ hom_completion (monoid_functor op + (0::'a))
(monoid_functor op + (0::'b))
lemma plus_fun_apply:
(f + g) x = f x + g x
lemma homo_ab_plus_closed:
[| comm_monoid_add (0::'a) op +; comm_monoid_add (0::'b) op +; homo_ab x;
homo_ab y |]
==> homo_ab (x + y)
lemma end_comm_monoid_add_closed:
[| comm_monoid_add (0::'a) op +; homo_ab x; homo_ab y |] ==> homo_ab (x + y)
lemma comm_monoid_add_impl_homo_abelian_monoid:
comm_monoid_add (0::'a) op +
==> abelian_monoid
(| carrier = {f. homo_ab f}, mult = op o, one = id, zero = 0, add = op + |)
lemma ab_group_add_impl_uminus_fun_closed:
[| ab_group_add op - uminus (0::'a) op +; homo_ab f |] ==> homo_ab (- f)
lemma ab_group_add_impl_homo_abelian_group_axioms:
ab_group_add op - uminus (0::'a) op +
==> abelian_group_axioms
(| carrier = {f. homo_ab f}, mult = op o, one = id, zero = 0, add = op + |)
lemma homo_monoid:
monoid
(| carrier = {f. homo_ab f}, mult = op o, one = id, zero = 0::'b, add = op + |)
lemma ab_group_add_impl_homo_ring_axioms:
ab_group_add op - uminus (0::'a) op +
==> ring_axioms
(| carrier = {f. homo_ab f}, mult = op o, one = id, zero = 0, add = op + |)
lemma ab_group_add_impl_homo_ring:
ab_group_add op - uminus (0::'a) op +
==> Ring.ring
(| carrier = {f. homo_ab f}, mult = op o, one = id, zero = 0, add = op + |)
lemma homo_diff_preserves_hom_diff:
homo_diff f
==> f ∈ hom_diff
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff)
(diff_group_functor uminus op - (0::'b) op + diff_group_add_class.diff)
lemma reduction_class_ext_impl_diff_group_add_pert_hom_bound_exist:
reduction_class_ext f g
==> diff_group_add_pert_hom_bound_exist op - uminus (0::'a) op +
diff_group_add_class.diff diff_group_add_pert_class.pert hom_oper
lemma reduction_class_ext_impl_diff_group_add:
reduction_class_ext f g
==> diff_group_add op - uminus (0::'b) op + diff_group_add_class.diff
lemma reduction_class_ext_impl_homo_diff_f:
reduction_class_ext f g ==> homo_diff f
lemma reduction_class_ext_impl_homo_diff_g:
reduction_class_ext f g ==> homo_diff g
lemma reduction_class_ext_impl_fg_id:
reduction_class_ext f g ==> f o g = id
lemma reduction_class_ext_impl_gf_dh_hd_id:
reduction_class_ext f g
==> (g o f) + (diff_group_add_class.diff o hom_oper) +
(hom_oper o diff_group_add_class.diff) =
id
lemma reduction_class_ext_impl_fh_0:
reduction_class_ext f g ==> f o hom_oper = 0
lemma reduction_class_ext_impl_hg_0:
reduction_class_ext f g ==> hom_oper o g = 0
lemma hdh_eq_h:
reduction_class_ext f g
==> hom_oper o diff_group_add_class.diff o hom_oper = hom_oper
lemma diff_group_add_pert_hom_bound_exist_impl_diff_group_add:
diff_group_add_pert_hom_bound_exist op - uminus (0::'a) op +
diff_group_add_class.diff diff_group_add_pert_class.pert hom_oper
==> diff_group_add op - uminus (0::'a) op + diff_group_add_class.diff
lemma reduction_class_ext_preserves_reduction:
reduction_class_ext f g
==> reduction
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff)
(diff_group_functor uminus op - (0::'b) op + diff_group_add_class.diff) f g
hom_oper
lemma diff_group_add_pert_hom_bound_exist_preserves_pert:
diff_group_add_pert_hom_bound_exist op - uminus (0::'a) op +
diff_group_add_class.diff diff_group_add_pert_class.pert hom_oper
==> diff_group_add_pert_class.pert
∈ analytic_part_local.pert
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff)
lemma α_locally_nilpotent:
diff_group_add_pert_hom_bound_exist op - uminus (0::'a) op +
diff_group_add_class.diff diff_group_add_pert_class.pert hom_oper
==> (α ^ local_bound α x) x = (0::'a)
lemma
op - = (λx y. x + - y)
lemma hom_completion_ring:
Ring.ring
(| carrier =
hom_completion
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff)
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff),
mult = op o,
one = λx. if x ∈ carrier
(diff_group_functor uminus op - (0::'a) op +
diff_group_add_class.diff)
then id x
else \<one>diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff,
zero =
λx. if x ∈ carrier
(diff_group_functor uminus op - (0::'a) op +
diff_group_add_class.diff)
then \<one>diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff
else \<one>diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff,
add = λf g x.
if x ∈ carrier
(diff_group_functor uminus op - (0::'a) op +
diff_group_add_class.diff)
then f x ⊗diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff
g x
else \<one>diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff |)
lemma homo_ab_is_hom_completion:
[| homo_ab f;
diff_group_add op - uminus (0::'a) op + diff_group_add_class.diff |]
==> f ∈ hom_completion
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff)
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff)
lemma hom_completion_is_homo_ab:
[| f ∈ hom_completion
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff)
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff);
diff_group_add op - uminus (0::'a) op + diff_group_add_class.diff |]
==> homo_ab f
lemma hom_completion_equiv_homo_ab:
diff_group_add op - uminus (0::'a) op + diff_group_add_class.diff
==> homo_ab f =
(f ∈ hom_completion
(diff_group_functor uminus op - (0::'a) op +
diff_group_add_class.diff)
(diff_group_functor uminus op - (0::'a) op +
diff_group_add_class.diff))
lemma ring_nat_pow_equiv_funpow:
[| diff_group_add op - uminus (0::'a) op + diff_group_add_class.diff;
f ∈ hom_completion
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff)
(diff_group_functor uminus op - (0::'a) op +
diff_group_add_class.diff) |]
==> f (^)ring_hom_compl (diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff)
n =
f ^ n
lemma minus_ring_homo_equal_uminus_fun:
[| diff_group_add op - uminus (0::'a) op + diff_group_add_class.diff;
homo_ab f |]
==> \<ominus>ring_hom_compl (diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff) f =
- f
lemma minus_ring_hom_completion_equal_uminus_fun:
[| diff_group_add op - uminus (0::'a) op + diff_group_add_class.diff;
f ∈ hom_completion
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff)
(diff_group_functor uminus op - (0::'a) op +
diff_group_add_class.diff) |]
==> \<ominus>ring_hom_compl (diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff) f =
- f
lemma α_in_hom_completion:
diff_group_add_pert_hom op - uminus (0::'a) op + diff_group_add_class.diff
diff_group_add_pert_class.pert hom_oper
==> α ∈ hom_completion
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff)
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff)
lemma β_in_hom_completion:
diff_group_add_pert_hom op - uminus (0::'a) op + diff_group_add_class.diff
diff_group_add_pert_class.pert hom_oper
==> β ∈ hom_completion
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff)
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff)
lemma reduction_class_ext_preserves_local_nilpotent_term:
reduction_class_ext f g
==> local_nilpotent_term
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff)
(ring_hom_compl
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff))
α (local_bound α)
lemma reduction_class_ext_preserves_BPL:
reduction_class_ext f g
==> BPL (diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff)
(ring_hom_compl
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff))
hom_oper
(diff_group_functor uminus op - (0::'b) op + diff_group_add_class.diff) f g
diff_group_add_pert_class.pert (local_bound α)
lemma reduction_class_ext_preserves_lemma_2_2_15:
reduction_class_ext f g
==> lemma_2_2_15
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff)
(ring_hom_compl
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff))
hom_oper
(diff_group_functor uminus op - (0::'b) op + diff_group_add_class.diff) f g
diff_group_add_pert_class.pert (local_bound α)
lemma reduction_class_ext_preserves_local_nilpotent_alpha:
reduction_class_ext f g
==> local_nilpotent_alpha
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff)
(ring_hom_compl
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff))
(diff_group_functor uminus op - (0::'b) op + diff_group_add_class.diff) f g
hom_oper diff_group_add_pert_class.pert (local_bound α)
lemma reduction_class_ext_preserves_power_series:
reduction_class_ext f g
==> local_nilpotent_term.power_series
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff)
(ring_hom_compl
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff))
α (local_bound α) =
(λx. fin_sum α (local_bound α x) x)
lemma reduction_class_ext_preserves_Φ:
reduction_class_ext f g
==> local_nilpotent_alpha.Φ
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff)
(ring_hom_compl
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff))
hom_oper diff_group_add_pert_class.pert (local_bound α) =
Φ
corollary reduction_class_ext_preserves_output_f:
reduction_class_ext f g
==> f o local_nilpotent_alpha.Φ
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff)
(ring_hom_compl
(diff_group_functor uminus op - (0::'a) op +
diff_group_add_class.diff))
hom_oper diff_group_add_pert_class.pert (local_bound α) =
f o Φ
corollary reduction_class_ext_preserves_output_h:
reduction_class_ext f g
==> lemma_2_2_15.h'
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff)
(ring_hom_compl
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff))
hom_oper diff_group_add_pert_class.pert (local_bound α) =
h'
lemma reduction_class_ext_preserves_alpha_beta:
reduction_class_ext f g
==> alpha_beta
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff)
(ring_hom_compl
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff))
(diff_group_functor uminus op - (0::'b) op + diff_group_add_class.diff) f g
hom_oper diff_group_add_pert_class.pert
lemma reduction_class_ext_preserves_beta_bound:
reduction_class_ext f g ==> local_bounded_func β
lemma reduction_class_ext_preserves_power_series_β:
reduction_class_ext f g
==> local_nilpotent_term.power_series
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff)
(ring_hom_compl
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff))
β (local_bound β) =
(λx. fin_sum β (local_bound β x) x)
lemma reduction_class_ext_preserves_bound_psi:
reduction_class_ext f g
==> local_nilpotent_alpha.bound_psi
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff)
(ring_hom_compl
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff))
hom_oper diff_group_add_pert_class.pert =
local_bound β
lemma reduction_class_ext_preserves_Ψ:
reduction_class_ext f g
==> local_nilpotent_alpha.Ψ
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff)
(ring_hom_compl
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff))
hom_oper diff_group_add_pert_class.pert =
Ψ
corollary reduction_class_ext_preserves_output_g:
reduction_class_ext f g
==> local_nilpotent_alpha.Ψ
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff)
(ring_hom_compl
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff))
hom_oper diff_group_add_pert_class.pert o
g =
Ψ o g
corollary reduction_class_ext_preserves_output_dC:
reduction_class_ext f g
==> (λx. if x ∈ carrier
(diff_group_functor uminus op - (0::'b) op +
diff_group_add_class.diff)
then diff_group.diff
(diff_group_functor uminus op - (0::'b) op +
diff_group_add_class.diff)
x ⊗diff_group_functor uminus op - (0::'b) op + diff_group_add_class.diff
(f o diff_group_add_pert_class.pert o
local_nilpotent_alpha.Ψ
(diff_group_functor uminus op - (0::'a) op +
diff_group_add_class.diff)
(ring_hom_compl
(diff_group_functor uminus op - (0::'a) op +
diff_group_add_class.diff))
hom_oper diff_group_add_pert_class.pert o
g)
x
else \<one>diff_group_functor uminus op - (0::'b) op + diff_group_add_class.diff) =
dC' f g
lemma
reduction_class_ext f g
==> reduction
(lemma_2_2_15.D'
(diff_group_functor uminus op - (0::'a) op + diff_group_add_class.diff)
(ring_hom_compl
(diff_group_functor uminus op - (0::'a) op +
diff_group_add_class.diff))
diff_group_add_pert_class.pert)
(| carrier =
carrier
(diff_group_functor uminus op - (0::'b) op +
diff_group_add_class.diff),
mult =
op ⊗diff_group_functor uminus op - (0::'b) op + diff_group_add_class.diff,
one = \<one>diff_group_functor uminus op - (0::'b) op + diff_group_add_class.diff,
diff_group.diff = dC' f g |)
(f' f) (g' g) h'