Theory VS_Groups

```(* Title: Examples/Vector_Spaces/VS_Groups.thy
Author: Mihails Milehins
*)
section‹Groups›
theory VS_Groups
imports VS_Prerequisites
begin

subsection‹Definitions and elementary properties›

fixes S :: "'a set" and pls :: "'a ⇒ 'a ⇒ 'a" (infixl ‹⊕⇩o⇩w› 65)
"⟦ a ∈ S; b ∈ S; c ∈ S ⟧ ⟹ (a ⊕⇩o⇩w b) ⊕⇩o⇩w c = a ⊕⇩o⇩w (b ⊕⇩o⇩w c)"
and add_closed: "⟦ a ∈ S; b ∈ S ⟧ ⟹ a ⊕⇩o⇩w b ∈ S"
begin

lemma add_closed'[simp]: "∀x∈S. ∀y∈S. x ⊕⇩o⇩w y ∈ S" by (auto simp: add_closed)

end

assumes add_commute: "⟦ a ∈ S; b ∈ S ⟧ ⟹ a ⊕⇩o⇩w b = b ⊕⇩o⇩w a"

fixes z
assumes add_zero: "a ∈ S ⟹ z ⊕⇩o⇩w a = a"
and zero_closed[simp]: "z ∈ S"
begin

lemma carrier_ne[simp]: "S ≠ {}" using zero_closed by blast

end

definition "sum_with pls z f S =
(
if ∃C. f ` S ⊆ C ∧ comm_monoid_add_ow C pls z
then Finite_Set.fold (pls o f) z S
else z
)"

lemma sum_with_empty[simp]: "sum_with pls z f {} = z"
by (auto simp: sum_with_def)

lemma sum_with_cases[case_names comm zero]:
assumes "⋀C. ⟦ f ` S ⊆ C; comm_monoid_add_ow C pls z ⟧ ⟹
P (Finite_Set.fold (pls o f) z S)"
and "(⋀C. comm_monoid_add_ow C pls z ⟹ (∃s∈S. f s ∉ C)) ⟹ P z"
shows "P (sum_with pls z f S)"
using assms by (auto simp: sum_with_def)

begin

lemma sum_with_infinite: "infinite A ⟹ sum_with (⊕⇩o⇩w) z g A = z"
by (induction rule: sum_with_cases) auto

context
begin

abbreviation pls' :: "'a ⇒ 'a ⇒ 'a"
where "pls' ≡ λx y. (if x ∈ S then x else z) ⊕⇩o⇩w (if y ∈ S then y else z)"

lemma fold_pls'_closed: "Finite_Set.fold (pls' ∘ g) z A ∈ S" if "g ` A ⊆ S"
proof cases
assume A: "finite A"
interpret comp_fun_commute "pls' o g"
by unfold_locales auto
from fold_graph_fold[OF A] have
"fold_graph (pls' ∘ g) z A (Finite_Set.fold (pls' ∘ g) z A)" .
from
fold_graph_closed_lemma[OF this, of S "pls' ∘ g"]
zero_closed
show ?thesis
by auto

lemma fold_pls'_eq:
assumes "g ` A ⊆ S"
shows "Finite_Set.fold (pls' ∘ g) z A = Finite_Set.fold (pls ∘ g) z A"
by (intro fold_closed_eq[where B=S]) auto

lemma sum_with_closed:
assumes "g ` A ⊆ S"
shows "sum_with pls z g A ∈ S"
proof -
interpret comp_fun_commute "pls' o g"
by unfold_locales auto
have "∃C. g ` A ⊆ C ∧ comm_monoid_add_ow C pls z"
then show ?thesis
using fold_pls'_closed[OF assms]
by (simp add: sum_with_def fold_pls'_eq assms)
qed

lemma sum_with_insert:
assumes g_into: "g x ∈ S" "g ` A ⊆ S"
and A: "finite A"
and x: "x ∉ A"
shows "sum_with pls z g (insert x A) = (g x) ⊕⇩o⇩w (sum_with pls z g A)"
proof -
interpret comp_fun_commute "pls' o g"
have
"Finite_Set.fold (pls ∘ g) z (insert x A) =
Finite_Set.fold (pls' ∘ g) z (insert x A)"
using g_into by (subst fold_pls'_eq) auto
also have "… = pls' (g x) (Finite_Set.fold (pls' ∘ g) z A)"
unfolding fold_insert[OF A x] by (auto simp: o_def)
also have "… = (g x) ⊕⇩o⇩w (Finite_Set.fold (pls' ∘ g) z A)"
proof -
from fold_graph_fold[OF A] have
"fold_graph (pls' ∘ g) z A (Finite_Set.fold (pls' ∘ g) z A)" .
from
fold_graph_closed_lemma[OF this, of S "pls' ∘ g"]
zero_closed
have "Finite_Set.fold (pls' ∘ g) z A ∈ S"
by auto
then show ?thesis using g_into by auto
qed
also have
"Finite_Set.fold (pls' ∘ g) z A = Finite_Set.fold (pls ∘ g) z A"
using g_into by (subst fold_pls'_eq) auto
finally have
"Finite_Set.fold (pls ∘ g) z (insert x A) =
pls (g x) (Finite_Set.fold (pls ∘ g) z A)" .
moreover have
"∃C. g ` insert x A ⊆ C ∧ comm_monoid_add_ow C pls z"
"∃C. g ` A ⊆ C ∧ comm_monoid_add_ow C pls z"
ultimately show ?thesis by (simp add: sum_with_def)
qed

end

end

fixes mns um
assumes ab_left_minus: "a ∈ S ⟹ (um a) ⊕⇩o⇩w a = z"
"⟦ a ∈ S; b ∈ S ⟧ ⟹ mns a b = a ⊕⇩o⇩w (um b)"
and uminus_closed: "a ∈ S ⟹ um a ∈ S"

subsection‹Instances (by type class constraints)›

(∀a∈S. ∀b∈S. ∀c∈S. pls (pls a b) c =
pls a (pls b c)) ∧ (∀a∈S. ∀b∈S. pls a b ∈ S)"

semigroup_add_ow S pls ∧ (∀a∈S. ∀b∈S. pls a b = pls b a)"

ab_semigroup_add_ow S pls ∧ (∀a∈S. pls z a = a) ∧ z ∈ S"

by
(
auto simp:
ac_simps
)

"ab_group_add_ow S pls z mns um ⟷
(∀a∈S. pls (um a) a = z) ∧
(∀a∈S. ∀b∈S. mns a b = pls a (um b)) ∧
(∀a∈S. um a ∈ S)"

lemma sum_with[ud_with]: "sum = sum_with (+) 0"
proof(intro HOL.ext)
fix f :: "'a ⇒ 'b" and S :: "'a set"
show "sum f S = sum_with (+) 0 f S"
proof(induction rule: sum_with_cases)
case (comm C) then show ?case unfolding sum.eq_fold by simp
next
case zero from zero[OF comm_monoid_add_ow] show ?case by simp
qed
qed

lemmas [tts_implicit] = sum_with[symmetric]

subsection‹Transfer rules›

context
includes lifting_syntax
begin

includes lifting_syntax
assumes [transfer_rule]: "bi_unique A"
shows "(rel_set A ===> (A ===> A ===> A) ===> (=))
by transfer_prover

lemma Domainp_applyI:
includes lifting_syntax
shows "(A ===> B) f g ⟹ A x y ⟹ Domainp B (f x)"
by (auto simp: rel_fun_def)

lemma Domainp_apply2I:
includes lifting_syntax
shows "(A ===> B ===> C) f g ⟹ A x y ⟹ B x' y' ⟹ Domainp C (f x x')"
by (force simp: rel_fun_def)

includes lifting_syntax
assumes [transfer_rule]: "bi_unique A"
shows
"(rel_set A ===> (A ===> A ===> A) ===> (=))

assumes [transfer_rule]: "right_total A" "bi_unique A"
shows "((A ===> A ===> A) ===> (=))
proof -
let ?P = "((A ===> A ===> A) ===> (=))"
let ?rf_UNIV =
"(λf::['b, 'b] ⇒ 'b. (∀x y. x ∈ UNIV ⟶ y ∈ UNIV ⟶ f x y ∈ UNIV))"
apply transfer_prover_start
apply transfer_step+
by auto
thus ?thesis by simp
qed

includes lifting_syntax
assumes [transfer_rule]: "bi_unique A"
shows
"(rel_set A ===> (A ===> A ===> A) ===> A ===> (=))

assumes [transfer_rule]: "right_total A" "bi_unique A"
shows
"((A ===> A ===> A) ===> (=))
unfolding
by transfer_prover

assumes [transfer_rule]: "right_total A" "bi_unique A"
shows "((A ===> A ===> A) ===> A ===> (=))
proof(intro rel_funI)
fix p p' z z'
assume [transfer_rule]: "(A ===> A ===> A) p p'" "A z z'"
show
"comm_monoid_add_ow (Collect (Domainp A)) p z =
unfolding
apply transfer
using ‹A z z'›
by auto
qed

assumes [transfer_rule]: "right_total A" "bi_unique A"
shows
"((A ===> A ===> A) ===> A  ===> (A ===> A ===> A) ===> (A ===> A)===> (=))
proof (intro rel_funI)
fix p p' z z' m m' um um'
assume [transfer_rule]:
"(A ===> A ===> A) p p'" "A z z'" "(A ===> A ===> A) m m'"
and um[transfer_rule]: "(A ===> A) um um'"
show
"ab_group_add_ow (Collect (Domainp A)) p z m um =
unfolding
by transfer (use um in ‹auto simp: rel_fun_def›)
qed

assumes ex_comm: "∃C. f ` S ⊆ C ∧ comm_monoid_add_ow C pls zero"
and transfers:
"(A ===> A ===> A) pls pls'"
"A zero zero'"
"Domainp (rel_set B) S"
and in_dom: "⋀x. x ∈ S ⟹ Domainp A (f x)"
obtains C where
"comm_monoid_add_ow C pls zero" "f ` S ⊆ C" "Domainp (rel_set A) C"
proof -
from ex_comm obtain C0 where C0: "f ` S ⊆ C0"
and comm: "comm_monoid_add_ow C0 pls zero"
by auto
define C where "C = C0 ∩ Collect (Domainp A)"
using comm Domainp_apply2I[OF ‹(A ===> A ===> A) pls pls'›] ‹A zero zero'›
by
(
auto simp:
C_def
)
moreover have "f ` S ⊆ C" using C0 by (auto simp: C_def in_dom)
moreover have "Domainp (rel_set A) C" by (auto simp: C_def Domainp_set)
ultimately show ?thesis ..
qed

lemma Domainp_sum_with:
includes lifting_syntax
assumes "⋀x. x ∈ t ⟹ Domainp A (r x)" "t ⊆ Collect (Domainp A)"
and transfer_rules[transfer_rule]: "(A ===> A ===> A) p p'" "A z z'"
shows DsI: "Domainp A (sum_with p z r t)"
proof cases
assume ex: "∃C. r ` t ⊆ C ∧ comm_monoid_add_ow C p z"
have "Domainp (rel_set A) t" using assms by (auto simp: Domainp_set)
OF ex transfer_rules(1,2) this assms(1)
]
obtain C where C:
"comm_monoid_add_ow C p z" "r ` t ⊆ C" "Domainp (rel_set A) C"
by auto
interpret comm_monoid_add_ow C p z by fact
from sum_with_closed[OF C(2)] C(3)
show ?thesis by auto (meson C(3) Domainp_set)
qed (use ‹A z _› in ‹auto simp: sum_with_def›)

lemma sum_with_transfer[transfer_rule]:
assumes [transfer_rule]: "right_total A" "bi_unique A" "bi_unique B"
shows "((A ===> A ===> A) ===> A ===> (B ===> A) ===> rel_set B ===> A)
sum_with sum_with"
proof(intro rel_funI)
fix pls pls' zero zero' f g S T
assume transfer_pls[transfer_rule]: "(A ===> A ===> A) pls pls'"
and transfer_zero[transfer_rule]: "A zero zero'"
assume transfer_g[transfer_rule]: "(B ===> A) f g"
and transfer_T[transfer_rule]: "rel_set B S T"
show "A (sum_with pls zero f S) (sum_with pls' zero' g T)"
proof cases
assume ex_comm: "∃C. f ` S ⊆ C ∧ comm_monoid_add_ow C pls zero"
have Domains: "Domainp (rel_set B) S" "(⋀x. x ∈ S ⟹ Domainp A (f x))"
using transfer_T transfer_g by auto (meson Domainp_applyI rel_set_def)
OF ex_comm transfer_pls transfer_zero Domains
]
obtain C where comm: "comm_monoid_add_ow C pls zero"
and C: "f ` S ⊆ C"
and "Domainp (rel_set A) C"
by auto
then obtain C' where [transfer_rule]: "rel_set A C C'" by auto
interpret comm: comm_monoid_add_ow C pls zero by fact
have C': "g ` T ⊆ C'" by transfer (rule C)
have comm': "comm_monoid_add_ow C' pls' zero'" by transfer (rule comm)
then interpret comm': comm_monoid_add_ow C' pls' zero' .
from C' comm' have ex_comm':
"∃C. g ` T ⊆ C ∧ comm_monoid_add_ow C pls' zero'"
by auto
show ?thesis
using transfer_T C C'
proof (induction S arbitrary: T rule: infinite_finite_induct)
case (infinite S)
note [transfer_rule] = infinite.prems
from infinite.hyps have "infinite T" by transfer
then show ?case by (simp add: sum_with_def infinite.hyps ‹A zero zero'›)
next
case [transfer_rule]: empty
have "T = {}" by transfer rule
then show ?case by (simp add: sum_with_def ‹A zero zero'›)
next
case (insert x F)
note [transfer_rule] = insert.prems(1)
have [simp]: "finite T" by transfer (simp add: insert.hyps)
obtain y where [transfer_rule]: "B x y" and y: "y ∈ T"
by (meson insert.prems insertI1 rel_setD1)
define T' where "T' = T - {y}"
have T_def: "T = insert y T'" by (auto simp: T'_def y)
define sF where "sF = sum_with pls zero f F"
define sT where "sT = sum_with pls' zero' g T'"
have [simp]: "y ∉ T'" "finite T'" by (auto simp: y T'_def)
have "rel_set B (insert x F - {x}) T'"
unfolding T'_def by transfer_prover
then have transfer_T'[transfer_rule]: "rel_set B F T'"
using insert.hyps by simp
from insert.prems have "f ` F ⊆ C" "g ` T' ⊆ C'" by (auto simp: T'_def)
from insert.IH[OF transfer_T' this] have [transfer_rule]: "A sF sT"
by (auto simp: sF_def sT_def o_def)
have rew:
"(sum_with pls zero f (insert x F)) =
pls (f x) (sum_with pls zero f F)"
apply (subst comm.sum_with_insert)
subgoal using insert.prems by auto
subgoal using insert.prems by auto
subgoal by fact
subgoal by fact
subgoal by auto
done
have rew':
"(sum_with pls' zero' g (insert y T')) =
pls' (g y) (sum_with pls' zero' g T')"
apply (subst comm'.sum_with_insert)
subgoal
apply transfer
using insert.prems by auto
subgoal
apply transfer
using insert.prems by auto
subgoal by fact
subgoal by fact
subgoal by auto
done
have
"A
(sum_with pls zero f (insert x F))
(sum_with pls' zero' g (insert y T'))"
unfolding sT_def[symmetric] sF_def[symmetric] rew rew'
by transfer_prover
then show ?case by (simp add: T_def)
qed
next
assume *: "∄C. f ` S ⊆ C ∧ comm_monoid_add_ow C pls zero"
then have **: "∄C'. g ` T ⊆ C' ∧ comm_monoid_add_ow C' pls' zero'"
by transfer simp
show ?thesis by (simp add: sum_with_def * ** ‹A zero zero'›)
qed
qed

end

subsection‹Relativization.›

begin

tts_context
tts: (?'a to S)
rewriting ctr_simps
eliminating ‹S ≠ {}› through auto
begin

tts_lemma mono_neutral_cong_left:
assumes "range h ⊆ S"
and "range g ⊆ S"
and "finite T"
and "Sa ⊆ T"
and "∀x∈T - Sa. h x = z"
and "⋀x. x ∈ Sa ⟹ g x = h x"
shows "sum_with (⊕⇩o⇩w) z g Sa = sum_with (⊕⇩o⇩w) z h T"
is sum.mono_neutral_cong_left.

end

end

text‹\newpage›

end```