Theory Prod_Ultrametric_Restriction_Spaces
section ‹Product›
theory Prod_Ultrametric_Restriction_Spaces
imports Ultrametric_Restriction_Spaces Restriction_Spaces
begin
text ‹
The product type \<^typ>‹'a × 'b› of to metric spaces is already instantiated as
a metric space by setting @{thm dist_prod_def[no_vars]}.
Unfortunately, this definition is not compatible with the distance required
by the \<^class>‹non_decseq_restriction_space›..
We first have to define a new product type with a trivial ⬚‹typedef›.
›
subsection ‹Isomorphic Product Construction›
subsubsection ‹Definition and First Properties›
typedef ('a, 'b) prod⇩m⇩a⇩x (‹(_ ×⇩m⇩a⇩x/ _)› [21, 20] 20) = ‹UNIV :: ('a × 'b) set›
morphisms from_prod⇩m⇩a⇩x to_prod⇩m⇩a⇩x by simp
declare from_prod⇩m⇩a⇩x_inject [simp]
from_prod⇩m⇩a⇩x_inverse [simp]
lemmas to_prod⇩m⇩a⇩x_inject_simplified [simp] = to_prod⇩m⇩a⇩x_inject [simplified]
and to_prod⇩m⇩a⇩x_inverse_simplified[simp] = to_prod⇩m⇩a⇩x_inverse[simplified]
lemmas to_prod⇩m⇩a⇩x_induct_simplified = to_prod⇩m⇩a⇩x_induct[simplified]
and to_prod⇩m⇩a⇩x_cases_simplified = to_prod⇩m⇩a⇩x_cases [simplified]
and from_prod⇩m⇩a⇩x_induct_simplified = from_prod⇩m⇩a⇩x_induct[simplified]
and from_prod⇩m⇩a⇩x_cases_simplified = from_prod⇩m⇩a⇩x_cases [simplified]
setup_lifting type_definition_prod⇩m⇩a⇩x
lift_definition Pair⇩m⇩a⇩x :: ‹'a ⇒ 'b ⇒ 'a ×⇩m⇩a⇩x 'b› is Pair .
free_constructors case_prod⇩m⇩a⇩x for Pair⇩m⇩a⇩x fst⇩m⇩a⇩x snd⇩m⇩a⇩x
by (metis Pair⇩m⇩a⇩x.abs_eq from_prod⇩m⇩a⇩x_inverse surjective_pairing)
(metis Pair⇩m⇩a⇩x.rep_eq prod.inject)
lemma fst⇩m⇩a⇩x_def : ‹fst⇩m⇩a⇩x ≡ map_fun from_prod⇩m⇩a⇩x id fst›
by (intro eq_reflection ext, simp add: fst⇩m⇩a⇩x_def,
metis Pair⇩m⇩a⇩x.rep_eq from_prod⇩m⇩a⇩x_inverse fst⇩m⇩a⇩x_def prod.collapse prod⇩m⇩a⇩x.sel(1))
lemma fst⇩m⇩a⇩x_rep_eq : ‹fst⇩m⇩a⇩x x = fst (from_prod⇩m⇩a⇩x x)›
by (metis Pair⇩m⇩a⇩x.rep_eq fst_conv prod⇩m⇩a⇩x.collapse)
lemma fst⇩m⇩a⇩x_abs_eq [simp] : ‹fst⇩m⇩a⇩x (to_prod⇩m⇩a⇩x y) = fst y›
by (metis Pair⇩m⇩a⇩x.abs_eq prod.exhaust_sel prod⇩m⇩a⇩x.sel(1))
lemma fst⇩m⇩a⇩x_transfer [transfer_rule]: ‹rel_fun (pcr_prod⇩m⇩a⇩x (=) (=)) (=) fst fst⇩m⇩a⇩x›
by (metis (mono_tags) Pair⇩m⇩a⇩x.rep_eq cr_prod⇩m⇩a⇩x_def fst_conv prod⇩m⇩a⇩x.collapse prod⇩m⇩a⇩x.pcr_cr_eq rel_funI)
lemma snd⇩m⇩a⇩x_def : ‹snd⇩m⇩a⇩x ≡ map_fun from_prod⇩m⇩a⇩x id snd›
by (intro eq_reflection ext, simp add: snd⇩m⇩a⇩x_def,
metis Pair⇩m⇩a⇩x.rep_eq from_prod⇩m⇩a⇩x_inverse prod.collapse prod⇩m⇩a⇩x.case)
lemma snd⇩m⇩a⇩x_rep_eq : ‹snd⇩m⇩a⇩x x = snd (from_prod⇩m⇩a⇩x x)›
by (metis Pair⇩m⇩a⇩x.rep_eq prod⇩m⇩a⇩x.collapse snd_conv)
lemma snd⇩m⇩a⇩x_abs_eq [simp] : ‹snd⇩m⇩a⇩x (to_prod⇩m⇩a⇩x y) = snd y›
by (metis Pair⇩m⇩a⇩x.abs_eq prod.exhaust_sel prod⇩m⇩a⇩x.sel(2))
lemma snd⇩m⇩a⇩x_transfer [transfer_rule] : ‹rel_fun (pcr_prod⇩m⇩a⇩x (=) (=)) (=) snd snd⇩m⇩a⇩x›
by (metis (mono_tags, lifting) Pair⇩m⇩a⇩x.rep_eq cr_prod⇩m⇩a⇩x_def
prod⇩m⇩a⇩x.collapse prod⇩m⇩a⇩x.pcr_cr_eq rel_funI snd_conv)
lemma case_prod⇩m⇩a⇩x_def : ‹case_prod⇩m⇩a⇩x ≡ map_fun id (map_fun from_prod⇩m⇩a⇩x id) case_prod›
by (intro eq_reflection ext, simp add: prod⇩m⇩a⇩x.case_eq_if fst⇩m⇩a⇩x_rep_eq snd⇩m⇩a⇩x_rep_eq split_beta)
lemma case_prod⇩m⇩a⇩x_rep_eq : ‹case_prod⇩m⇩a⇩x f p = (case from_prod⇩m⇩a⇩x p of (x, y) ⇒ f x y)›
by (simp add: fst⇩m⇩a⇩x_rep_eq prod⇩m⇩a⇩x.case_eq_if snd⇩m⇩a⇩x_rep_eq split_beta)
lemma case_prod⇩m⇩a⇩x_abs_eq [simp] : ‹case_prod⇩m⇩a⇩x f (to_prod⇩m⇩a⇩x q) = (case q of (x, y) ⇒ f x y)›
by (simp add: prod⇩m⇩a⇩x.case_eq_if split_beta)
lemma case_prod⇩m⇩a⇩x_transfer [transfer_rule] : ‹rel_fun (=) (rel_fun (pcr_prod⇩m⇩a⇩x (=) (=)) (=)) case_prod case_prod⇩m⇩a⇩x›
by (simp add: cr_prod⇩m⇩a⇩x_def fst⇩m⇩a⇩x_rep_eq prod⇩m⇩a⇩x.case_eq_if prod⇩m⇩a⇩x.pcr_cr_eq rel_fun_def snd⇩m⇩a⇩x_rep_eq split_beta)
subsection ‹Syntactic Sugar›
text ‹The following syntactic sugar is of course recovered from the theory \<^theory>‹HOL.Product_Type›.›
nonterminal tuple_args⇩m⇩a⇩x and patterns⇩m⇩a⇩x
syntax
"_tuple⇩m⇩a⇩x" :: "'a ⇒ tuple_args⇩m⇩a⇩x ⇒ 'a ×⇩m⇩a⇩x 'b" (‹(1⦉_,/ _⦊)›)
"_tuple_arg⇩m⇩a⇩x" :: "'a ⇒ tuple_args⇩m⇩a⇩x" (‹_›)
"_tuple_args⇩m⇩a⇩x" :: "'a ⇒ tuple_args⇩m⇩a⇩x ⇒ tuple_args⇩m⇩a⇩x" (‹_,/ _›)
"_pattern⇩m⇩a⇩x" :: "pttrn ⇒ patterns⇩m⇩a⇩x ⇒ pttrn" (‹⦉_,/ _⦊›)
"" :: "pttrn ⇒ patterns⇩m⇩a⇩x" (‹_›)
"_patterns⇩m⇩a⇩x" :: "pttrn ⇒ patterns⇩m⇩a⇩x ⇒ patterns⇩m⇩a⇩x" (‹_,/ _›)
translations
"⦉x, y⦊" ⇌ "CONST Pair⇩m⇩a⇩x x y"
"_pattern⇩m⇩a⇩x x y" ⇌ "CONST Pair⇩m⇩a⇩x x y"
"_patterns⇩m⇩a⇩x x y" ⇌ "CONST Pair⇩m⇩a⇩x x y"
"_tuple⇩m⇩a⇩x x (_tuple_args⇩m⇩a⇩x y z)" ⇌ "_tuple⇩m⇩a⇩x x (_tuple_arg⇩m⇩a⇩x (_tuple⇩m⇩a⇩x y z))"
"λ⦉x, y, zs⦊. b" ⇌ "CONST case_prod⇩m⇩a⇩x (λx ⦉y, zs⦊. b)"
"λ⦉x, y⦊. b" ⇌ "CONST case_prod⇩m⇩a⇩x (λx y. b)"
"_abs (CONST Pair⇩m⇩a⇩x x y) t" ⇀ "λ⦉x, y⦊. t"
text ‹With this syntactic sugar, one can write
\<^term>‹case a of ⦉b, c, d, e⦊ ⇒ ⦉c, d⦊›, \<^term>‹λ⦉y, u⦊. a›,
\<^term>‹λ⦉a, b⦊. ⦉a, b, c , d ,e⦊›, \<^term>‹λ⦉a, b, c⦊. a›, ‹…›
as for the type \<^typ>‹'a × 'b›.›
lemmas to_prod⇩m⇩a⇩x_tuple [simp] = Pair⇩m⇩a⇩x.abs_eq[symmetric]
and from_prod⇩m⇩a⇩x_tuple⇩m⇩a⇩x [simp] = Pair⇩m⇩a⇩x.rep_eq
subsection ‹Product›
text ‹We first redo the work of \<^theory>‹Restriction_Spaces.Restriction_Spaces_Prod›.›
instantiation prod⇩m⇩a⇩x :: (restriction, restriction) restriction
begin
lift_definition restriction_prod⇩m⇩a⇩x :: ‹'a ×⇩m⇩a⇩x 'b ⇒ nat ⇒ 'a ×⇩m⇩a⇩x 'b› is ‹(↓)› .
lemma restriction_prod⇩m⇩a⇩x_def' : ‹p ↓ n = ⦉fst⇩m⇩a⇩x p ↓ n, snd⇩m⇩a⇩x p ↓ n⦊›
by transfer (simp add: restriction_prod_def)
instance by (intro_classes, transfer, simp)
end
instance prod⇩m⇩a⇩x :: (restriction_space, restriction_space) restriction_space
by (intro_classes; transfer) (simp_all add: ex_not_restriction_related)
instantiation prod⇩m⇩a⇩x :: (restriction_σ, restriction_σ) restriction_σ
begin
definition restriction_σ_prod⇩m⇩a⇩x :: ‹('a ×⇩m⇩a⇩x 'b) itself ⇒ nat ⇒ real›
where ‹restriction_σ_prod⇩m⇩a⇩x _ n ≡
max (restriction_σ TYPE('a) n) (restriction_σ TYPE('b) n)›
instance by intro_classes
end
instantiation prod⇩m⇩a⇩x :: (non_decseq_restriction_space, non_decseq_restriction_space)
non_decseq_restriction_space
begin
definition dist_prod⇩m⇩a⇩x :: ‹['a ×⇩m⇩a⇩x 'b, 'a ×⇩m⇩a⇩x 'b] ⇒ real›
where ‹dist_prod⇩m⇩a⇩x f g ≡ INF n ∈ restriction_related_set f g. restriction_σ TYPE('a ×⇩m⇩a⇩x 'b) n›
definition uniformity_prod⇩m⇩a⇩x :: ‹(('a ×⇩m⇩a⇩x 'b) × 'a ×⇩m⇩a⇩x 'b) filter›
where ‹uniformity_prod⇩m⇩a⇩x ≡ INF e∈{0 <..}. principal {(x, y). dist x y < e}›
definition open_prod⇩m⇩a⇩x :: ‹('a ×⇩m⇩a⇩x 'b) set ⇒ bool›
where ‹open_prod⇩m⇩a⇩x U ≡ ∀x∈U. eventually (λ(x', y). x' = x ⟶ y ∈ U) uniformity›
instance
proof intro_classes
show ‹restriction_σ TYPE('a ×⇩m⇩a⇩x 'b) ⇢ 0›
by (rule real_tendsto_sandwich
[of ‹λn. 0› _ _ ‹λn. restriction_σ TYPE('a) n + restriction_σ TYPE('b) n›])
(simp_all add: order_less_imp_le restriction_σ_prod⇩m⇩a⇩x_def max_def
restriction_σ_tendsto_zero tendsto_add_zero)
qed (simp_all add: uniformity_prod⇩m⇩a⇩x_def open_prod⇩m⇩a⇩x_def
restriction_σ_prod⇩m⇩a⇩x_def max_def dist_prod⇩m⇩a⇩x_def)
end
instance prod⇩m⇩a⇩x :: (decseq_restriction_space, decseq_restriction_space) decseq_restriction_space
proof intro_classes
show ‹decseq (restriction_σ TYPE('a ×⇩m⇩a⇩x 'b))›
proof (intro decseq_SucI)
show ‹restriction_σ TYPE('a ×⇩m⇩a⇩x 'b) (Suc n) ≤ restriction_σ TYPE('a ×⇩m⇩a⇩x 'b) n› for n
using decseq_SucD[of ‹restriction_σ TYPE('a)› n]
decseq_SucD[of ‹restriction_σ TYPE('b)› n]
by (auto simp add: restriction_σ_prod⇩m⇩a⇩x_def decseq_restriction_σ)
qed
qed
instance prod⇩m⇩a⇩x :: (strict_decseq_restriction_space, strict_decseq_restriction_space) strict_decseq_restriction_space
proof intro_classes
show ‹strict_decseq (restriction_σ TYPE('a ×⇩m⇩a⇩x 'b))›
proof (intro strict_decseq_SucI)
show ‹restriction_σ TYPE('a ×⇩m⇩a⇩x 'b) (Suc n) < restriction_σ TYPE('a ×⇩m⇩a⇩x 'b) n› for n
using strict_decseq_SucD[of ‹restriction_σ TYPE('a)› n]
strict_decseq_SucD[of ‹restriction_σ TYPE('b)› n]
by (auto simp add: restriction_σ_prod⇩m⇩a⇩x_def strict_decseq_restriction_σ)
qed
qed
instantiation prod⇩m⇩a⇩x :: (restriction_δ, restriction_δ) restriction_δ
begin
definition restriction_δ_prod⇩m⇩a⇩x :: ‹('a ×⇩m⇩a⇩x 'b) itself ⇒ real›
where ‹restriction_δ_prod⇩m⇩a⇩x _ ≡ max (restriction_δ TYPE('a)) (restriction_δ TYPE('b))›
instance by intro_classes (simp_all add: restriction_δ_prod⇩m⇩a⇩x_def max_def)
end
instance prod⇩m⇩a⇩x :: (at_least_geometric_restriction_space, at_least_geometric_restriction_space)
at_least_geometric_restriction_space
proof intro_classes
show ‹0 < restriction_σ TYPE('a ×⇩m⇩a⇩x 'b) n› for n by simp
next
show ‹restriction_σ TYPE('a ×⇩m⇩a⇩x 'b) (Suc n)
≤ restriction_δ TYPE('a ×⇩m⇩a⇩x 'b) * restriction_σ TYPE('a ×⇩m⇩a⇩x 'b) n› for n
by (auto intro: order_trans[OF restriction_σ_le]
simp add: restriction_δ_prod⇩m⇩a⇩x_def mult_mono' restriction_σ_prod⇩m⇩a⇩x_def)
next
show ‹dist p1 p2 = Inf (restriction_σ_related_set p1 p2)› for p1 p2 :: ‹'a ×⇩m⇩a⇩x 'b›
by (simp add: dist_prod⇩m⇩a⇩x_def)
qed
instance prod⇩m⇩a⇩x :: (geometric_restriction_space, geometric_restriction_space) geometric_restriction_space
proof intro_classes
show ‹restriction_σ TYPE('a ×⇩m⇩a⇩x 'b) n = restriction_δ TYPE('a ×⇩m⇩a⇩x 'b) ^ n› for n
by (simp add: restriction_σ_prod⇩m⇩a⇩x_def restriction_σ_is restriction_δ_prod⇩m⇩a⇩x_def max_def)
(meson nle_le power_mono zero_le_restriction_δ)
next
show ‹dist p1 p2 = Inf (restriction_σ_related_set p1 p2)› for p1 p2 :: ‹'a ×⇩m⇩a⇩x 'b›
by (simp add: dist_prod⇩m⇩a⇩x_def)
qed
lemma max_dist_projections_le_dist_prod⇩m⇩a⇩x :
‹max (dist (fst⇩m⇩a⇩x p1) (fst⇩m⇩a⇩x p2)) (dist (snd⇩m⇩a⇩x p1) (snd⇩m⇩a⇩x p2)) ≤ dist p1 p2›
proof (unfold dist_restriction_is max_def, split if_split, intro conjI impI)
show ‹Inf (restriction_σ_related_set (snd⇩m⇩a⇩x p1) (snd⇩m⇩a⇩x p2)) ≤ Inf (restriction_σ_related_set p1 p2)›
proof (rule cINF_superset_mono[OF nonempty_restriction_related_set])
show ‹bdd_below (restriction_σ_related_set (snd⇩m⇩a⇩x p1) (snd⇩m⇩a⇩x p2))›
by (meson bdd_belowI2 zero_le_restriction_σ)
qed (simp_all add: subset_iff add: restriction_prod⇩m⇩a⇩x_def' restriction_σ_prod⇩m⇩a⇩x_def)
next
show ‹Inf (restriction_σ_related_set (fst⇩m⇩a⇩x p1) (fst⇩m⇩a⇩x p2)) ≤ Inf (restriction_σ_related_set p1 p2)›
proof (rule cINF_superset_mono[OF nonempty_restriction_related_set])
show ‹bdd_below (restriction_σ_related_set (fst⇩m⇩a⇩x p1) (fst⇩m⇩a⇩x p2))›
by (meson bdd_belowI2 zero_le_restriction_σ)
qed (simp_all add: subset_iff add: restriction_prod⇩m⇩a⇩x_def' restriction_σ_prod⇩m⇩a⇩x_def)
qed
subsection ‹Completeness›
subsubsection ‹Preliminaries›
default_sort non_decseq_restriction_space
lemma restriction_σ_prod⇩m⇩a⇩x_commute :
‹restriction_σ TYPE('b ×⇩m⇩a⇩x 'a) = restriction_σ TYPE('a ×⇩m⇩a⇩x 'b)›
unfolding restriction_σ_prod⇩m⇩a⇩x_def by (rule ext) simp
definition dist_left_prod⇩m⇩a⇩x :: ‹('a ×⇩m⇩a⇩x 'b) itself ⇒ 'a ⇒ 'a ⇒ real›
where ‹dist_left_prod⇩m⇩a⇩x _ x y ≡ INF n ∈ restriction_related_set x y. restriction_σ TYPE('a ×⇩m⇩a⇩x 'b) n›
definition dist_right_prod⇩m⇩a⇩x :: ‹('a ×⇩m⇩a⇩x 'b) itself ⇒ 'b ⇒ 'b ⇒ real›
where ‹dist_right_prod⇩m⇩a⇩x _ x y ≡ INF n ∈ restriction_related_set x y. restriction_σ TYPE('a ×⇩m⇩a⇩x 'b) n›
lemma dist_right_prod⇩m⇩a⇩x_is_dist_left_prod⇩m⇩a⇩x :
‹dist_right_prod⇩m⇩a⇩x TYPE('b ×⇩m⇩a⇩x 'a) = dist_left_prod⇩m⇩a⇩x TYPE('a ×⇩m⇩a⇩x 'b)›
unfolding dist_left_prod⇩m⇩a⇩x_def dist_right_prod⇩m⇩a⇩x_def
by (subst restriction_σ_prod⇩m⇩a⇩x_commute) simp
lemma dist_le_dist_left_prod⇩m⇩a⇩x : ‹dist x y ≤ dist_left_prod⇩m⇩a⇩x TYPE('a ×⇩m⇩a⇩x 'b) x y›
proof (unfold dist_left_prod⇩m⇩a⇩x_def dist_restriction_is,
rule cINF_mono[OF nonempty_restriction_related_set[of x y]])
show ‹bdd_below (restriction_σ_related_set x y)›
by (meson bdd_belowI2 zero_le_restriction_σ)
next
show ‹m ∈ restriction_related_set x y ⟹
∃n∈restriction_related_set x y. σ⇩↓ TYPE('a) n ≤ σ⇩↓ TYPE('a ×⇩m⇩a⇩x 'b) m› for m
by (metis max.cobounded1 restriction_σ_prod⇩m⇩a⇩x_def)
qed
lemma dist_le_dist_right_prod⇩m⇩a⇩x : ‹dist x y ≤ dist_right_prod⇩m⇩a⇩x TYPE('b ×⇩m⇩a⇩x 'a) x y›
by (simp add: dist_le_dist_left_prod⇩m⇩a⇩x dist_right_prod⇩m⇩a⇩x_is_dist_left_prod⇩m⇩a⇩x)
lemma
fixes p1 p2 :: ‹'a :: decseq_restriction_space ×⇩m⇩a⇩x 'b :: decseq_restriction_space›
shows dist_prod⇩m⇩a⇩x_le_max_dist_left_prod⇩m⇩a⇩x_dist_right_prod⇩m⇩a⇩x :
‹dist p1 p2 ≤ max (dist_left_prod⇩m⇩a⇩x TYPE('a ×⇩m⇩a⇩x 'b) (fst⇩m⇩a⇩x p1) (fst⇩m⇩a⇩x p2))
(dist_right_prod⇩m⇩a⇩x TYPE('a ×⇩m⇩a⇩x 'b) (snd⇩m⇩a⇩x p1) (snd⇩m⇩a⇩x p2))›
proof -
interpret left : DecseqRestrictionSpace ‹(↓)› ‹(=)› ‹UNIV›
‹restriction_σ TYPE('a ×⇩m⇩a⇩x 'b)› ‹dist_left_prod⇩m⇩a⇩x TYPE('a ×⇩m⇩a⇩x 'b)›
by unfold_locales
(simp_all add: restriction_σ_tendsto_zero dist_left_prod⇩m⇩a⇩x_def decseq_restriction_σ)
interpret right : DecseqRestrictionSpace ‹(↓)› ‹(=)› ‹UNIV :: 'b set›
‹restriction_σ TYPE('a ×⇩m⇩a⇩x 'b)› ‹dist_right_prod⇩m⇩a⇩x TYPE('a ×⇩m⇩a⇩x 'b)›
by unfold_locales
(simp_all add: restriction_σ_tendsto_zero dist_right_prod⇩m⇩a⇩x_def decseq_restriction_σ)
show ‹dist p1 p2 ≤ max (dist_left_prod⇩m⇩a⇩x TYPE('a ×⇩m⇩a⇩x 'b) (fst⇩m⇩a⇩x p1) (fst⇩m⇩a⇩x p2))
(dist_right_prod⇩m⇩a⇩x TYPE('a ×⇩m⇩a⇩x 'b) (snd⇩m⇩a⇩x p1) (snd⇩m⇩a⇩x p2))›
by (auto simp add: dist_restriction_is_bis left.dist_restriction_is_bis
right.dist_restriction_is_bis prod⇩m⇩a⇩x.expand restriction_prod⇩m⇩a⇩x_def')
(smt (verit, best) Collect_cong nle_le restriction_related_le)
qed
default_sort type
subsubsection ‹Complete Restriction Space›
text ‹When the instances \<^typ>‹'a› and \<^typ>‹'b› of \<^class>‹decseq_restriction_space›
are also instances of \<^class>‹complete_space›,
the type \<^typ>‹'a ×⇩m⇩a⇩x 'b› is an instance of \<^class>‹complete_space›.›
lemma restriction_chain_prod⇩m⇩a⇩x_iff :
‹restriction_chain σ ⟷ restriction_chain (λn. fst⇩m⇩a⇩x (σ n)) ∧
restriction_chain (λn. snd⇩m⇩a⇩x (σ n))›
by (simp add: restriction_chain_def, transfer)
(metis fst_conv prod.collapse restriction_prod_def snd_conv)
lemma restriction_tendsto_prod⇩m⇩a⇩x_iff :
‹σ ─↓→ Σ ⟷ (λn. fst⇩m⇩a⇩x (σ n)) ─↓→ fst⇩m⇩a⇩x Σ ∧ (λn. snd⇩m⇩a⇩x (σ n)) ─↓→ snd⇩m⇩a⇩x Σ›
by (simp add: restriction_tendsto_def, transfer, simp add: restriction_prod_def)
(meson nle_le order.trans)
lemma restriction_convergent_prod⇩m⇩a⇩x_iff :
‹restriction_convergent σ ⟷ restriction_convergent (λn. fst⇩m⇩a⇩x (σ n)) ∧
restriction_convergent (λn. snd⇩m⇩a⇩x (σ n))›
by (simp add: restriction_convergent_def restriction_tendsto_prod⇩m⇩a⇩x_iff)
(metis prod⇩m⇩a⇩x.sel)
instance prod⇩m⇩a⇩x :: (complete_decseq_restriction_space, complete_decseq_restriction_space)
complete_decseq_restriction_space
proof (intro_classes, transfer)
fix σ :: ‹nat ⇒ 'a ×⇩m⇩a⇩x 'b› assume ‹chain⇩↓ σ›
hence ‹chain⇩↓ (λn. fst⇩m⇩a⇩x (σ n))› ‹chain⇩↓ (λn. snd⇩m⇩a⇩x (σ n))›
by (simp_all add: restriction_chain_prod⇩m⇩a⇩x_iff)
hence ‹convergent⇩↓ (λn. fst⇩m⇩a⇩x (σ n))› ‹convergent⇩↓ (λn. snd⇩m⇩a⇩x (σ n))›
by (simp_all add: restriction_chain_imp_restriction_convergent)
thus ‹convergent⇩↓ σ›
by (simp add: restriction_convergent_prod⇩m⇩a⇩x_iff)
qed
instance prod⇩m⇩a⇩x :: (complete_strict_decseq_restriction_space, complete_strict_decseq_restriction_space)
complete_strict_decseq_restriction_space
by intro_classes (simp add: restriction_chain_imp_restriction_convergent)
instance prod⇩m⇩a⇩x :: (complete_at_least_geometric_restriction_space, complete_at_least_geometric_restriction_space)
complete_at_least_geometric_restriction_space
by intro_classes (simp add: restriction_chain_imp_restriction_convergent)
instance prod⇩m⇩a⇩x :: (complete_geometric_restriction_space, complete_geometric_restriction_space)
complete_geometric_restriction_space
by intro_classes (simp add: restriction_chain_imp_restriction_convergent)
text ‹When the types \<^typ>‹'a› and \<^typ>‹'b› share the same restriction sequence,
we have the following equality.›
lemma same_restriction_σ_imp_restriction_σ_prod⇩m⇩a⇩x_is [simp] :
‹restriction_σ TYPE('b :: non_decseq_restriction_space) =
restriction_σ TYPE('a :: non_decseq_restriction_space) ⟹
restriction_σ TYPE('a ×⇩m⇩a⇩x 'b) = restriction_σ TYPE('a)›
unfolding restriction_σ_prod⇩m⇩a⇩x_def by simp
lemma same_restriction_σ_imp_dist_prod⇩m⇩a⇩x_eq_max_dist_projections :
‹dist p1 p2 = max (dist (fst⇩m⇩a⇩x p1) (fst⇩m⇩a⇩x p2)) (dist (snd⇩m⇩a⇩x p1) (snd⇩m⇩a⇩x p2))›
if same_restriction_σ [simp] : ‹restriction_σ TYPE('b) = restriction_σ TYPE('a)›
for p1 p2 :: ‹'a :: decseq_restriction_space ×⇩m⇩a⇩x 'b :: decseq_restriction_space›
proof (rule order_antisym)
have ‹dist_left_prod⇩m⇩a⇩x TYPE('a ×⇩m⇩a⇩x 'b) (fst⇩m⇩a⇩x p1) (fst⇩m⇩a⇩x p2) = dist (fst⇩m⇩a⇩x p1) (fst⇩m⇩a⇩x p2)›
by (simp add: dist_left_prod⇩m⇩a⇩x_def dist_restriction_is)
moreover have ‹dist_right_prod⇩m⇩a⇩x TYPE('a ×⇩m⇩a⇩x 'b) (snd⇩m⇩a⇩x p1) (snd⇩m⇩a⇩x p2) = dist (snd⇩m⇩a⇩x p1) (snd⇩m⇩a⇩x p2)›
by (simp add: dist_right_prod⇩m⇩a⇩x_def dist_restriction_is)
ultimately show ‹dist p1 p2 ≤ max (dist (fst⇩m⇩a⇩x p1) (fst⇩m⇩a⇩x p2)) (dist (snd⇩m⇩a⇩x p1) (snd⇩m⇩a⇩x p2))›
by (metis dist_prod⇩m⇩a⇩x_le_max_dist_left_prod⇩m⇩a⇩x_dist_right_prod⇩m⇩a⇩x)
next
show ‹max (dist (fst⇩m⇩a⇩x p1) (fst⇩m⇩a⇩x p2)) (dist (snd⇩m⇩a⇩x p1) (snd⇩m⇩a⇩x p2)) ≤ dist p1 p2›
by (fact max_dist_projections_le_dist_prod⇩m⇩a⇩x)
qed
text ‹Now, one can write things like \<^term>‹υ ⦉x, y⦊ . f ⦉x, y⦊›.›
text ‹We could of course imagine more support for \<^typ>‹'a ×⇩m⇩a⇩x 'b› type,
but as restriction spaces are intended to be used without recourse
to metric spaces, we have not undertaken this task for the time being.›
end