Module mathcomp.analysis.topology_theory.function_spaces

From HB Require Import structures.
From mathcomp Require Import boot order algebra interval_inference.
From mathcomp Require Import generic_quotient finmap.
#[warning="-warn-library-file-internal-analysis"]
From mathcomp Require Import unstable.
From mathcomp Require Import boolp classical_sets functions cardinality fsbigop.
From mathcomp Require Import reals.
From mathcomp Require Import topology_structure uniform_structure
  supremum_topology initial_topology pseudometric_structure separation_axioms
  compact connected subspace_topology product_topology.

# The topology of functions spaces Function spaces have no canonical topology. We develop the theory of several general-purpose function space topologies here. ## Topologies on `U -> V` There is no canonical topology on `U->V` in this library. Mathematically, the right topology usually depends on context. We provide three general options in this file which work for various amounts of structures on the domain and codomain. Topologies we consider are: - Topology of pointwise convergence + requires only a topology on V - Topology of uniform convergence + requires only a uniformity on V - Topology of uniform convergence on subspaces + requires only a uniformity on V - The compact-open topology + requires a topology on U and V if you're looking for the topology of compact convergence, note that it is exactly the compact-open topology via `compact_open_fam_compactP`. To locally assign a topology to `->`, import one of the following modules - ArrowAsProduct assigns the product topology - ArrowAsUniformType assigns the uniform topology - ArrowAsCompactOpen assign the compact-open topology The major results are: - Compactness in the product topology via Tychonoff's - Compactness in the compact convergence topology via Ascoli's - Conditions when the supremum and weak topology commute in products - The compact-open topology is the topopology of compact convergence - Cartesian closedness for the category of locally compact topologies ## Function space notations ``` {uniform` A -> V} == the space U -> V, equipped with the topology of uniform convergence from a set A to V, where V is a uniformType {uniform U -> V} := {uniform` [set: U] -> V} {uniform A, F --> f} == F converges to f in {uniform A -> V} {uniform, F --> f} := {uniform setT, F --> f} prod_topology I T == the topology of pointwise convergence on the dependent space `forall (i:I), T i` arrow_uniform_type U V == the topology of uniform convergence on the type `U -> V` {ptws U -> V} == prod_topology for the non-dependent product separate_points_from_closed f == for a closed set U and point x outside some member of the family f, it sends f_i(x) outside (closure (f_i @` U)) Used together with join_product. join_product f == the function (x => f ^~ x) When the family f separates points from closed sets, join_product is an embedding. {ptws, F --> f} == F converges to f in {ptws U -> V} {family fam, U -> V} == the supremum of {uniform A -> f} for each A in `fam` In particular, {family compact, U -> V} is the topology of compact convergence. {family fam, F --> f} == F converges to f in {family fam, U -> V} {compact_open, U -> V} == compact-open topology {compact_open, F --> f} == F converges to f in {compact_open, U -> V} eval == the evaluation map for continuous functions ``` ## Ascoli's theorem notations ``` equicontinuous W x == the set (W : X -> Y) is equicontinuous at x singletons T := [set [set x] | x in [set: T]] pointwise_precompact W == for each (x : X), the set of images [f x | f in W] is precompact ```

Reserved Notation "{ 'uniform`' A -> V }"
  (at level 0, A at level 69, format "{ 'uniform`' A -> V }").
Reserved Notation "{ 'uniform' U -> V }"
  (at level 0, U at level 69, format "{ 'uniform' U -> V }").
Reserved Notation "{ 'uniform' A , F --> f }"
  (at level 0, A at level 69, F at level 69,
   format "{ 'uniform' A , F --> f }").
Reserved Notation "{ 'uniform' , F --> f }"
  (at level 0, F at level 69,
   format "{ 'uniform' , F --> f }").
Reserved Notation "{ 'ptws' U -> V }"
  (at level 0, U at level 69, format "{ 'ptws' U -> V }").
Reserved Notation "{ 'ptws' , F --> f }"
  (at level 0, F at level 69, format "{ 'ptws' , F --> f }").
Reserved Notation "{ 'family' fam , U -> V }"
  (at level 0, U at level 69, format "{ 'family' fam , U -> V }").
Reserved Notation "{ 'family' fam , F --> f }"
  (at level 0, F at level 69, format "{ 'family' fam , F --> f }").
Reserved Notation "{ 'compact-open' , U -> V }"
  (at level 0, U at level 69, format "{ 'compact-open' , U -> V }").
Reserved Notation "{ 'compact-open' , F --> f }"
  (at level 0, F at level 69, format "{ 'compact-open' , F --> f }").

Unset SsrOldRewriteGoalsOrder.  
Set Implicit Arguments.
Unset Strict Implicit.
Unset Printing Implicit Defensive.

Local Obligation Tactic := idtac.

Import Order.TTheory GRing.Theory Num.Theory.
Local Open Scope classical_set_scope.
Local Open Scope ring_scope.

Product topology, also known as the topology of pointwise convergence
Section Product_Topology.

Definition prod_topology
Used by
  • mathcomp.analysis.cantor
  • mathcomp.analysis.homotopy_theory.wedge_sigT
  • mathcomp.analysis.normedtype_theory.matrix_normedtype

Source code
{ISource code : Type} (TSource code : I -> Type) := forall iSource code, T i.

Variable ISource code : Type.

Definition product_topology_def

prod_topology : forall {I : Type}, (I -> Type) -> Type prod_topology is not universe polymorphic Arguments prod_topology {I}%_type_scope T%_function_scope prod_topology is transparent Expands to: Constant mathcomp.analysis.topology_theory.function_spaces.prod_topology Declared in library mathcomp.analysis.topology_theory.function_spaces, line 127, characters 11-24


Source code
 (TSource code : I -> topologicalType) :=
  sup_topology (fun iSource code => Topological.class
    (initial_topology (fun fSource code : (forall iSource code, T i) => f i))).

HBSource code.instanceSource code DefinitionSource code _Source code (TSource code :Source code ISource code -> topologicalType) :=
  Topological.copy (prod_topology T) (product_topology_def T).

HBSource code.instanceSource code DefinitionSource code _Source code (TSource code :Source code ISource code -> uniformType) :=
  Uniform.copy (prod_topology T)
    (sup_topology (fun iSource code => Uniform.class (initial_topology (@proj _ T i)))).

HBSource code.instanceSource code DefinitionSource code _Source code (RSource code :Source code realTypeSource code) (Ii : countType)
    (Tc : Ii -> pseudoMetricType R) := PseudoMetric.copy (prod_topology Tc)
  (sup_pseudometric (fun iSource code => PseudoMetric.class (initial_topology (@proj _ Tc i)))
    (countableP _)).

End Product_Topology.

Notation "{ 'ptws' U -> V }"Source code := (prod_topology (fun _ : U => V)) : type_scope.
Notation "{ 'ptws' , F --> f }"Source code :=
  (cvg_to F (nbhs (f : {ptws _ -> _}))) : classical_set_scope.

Module ArrowAsProductSource code.
HBSource code.instanceSource code DefinitionSource code _Source code (USource code :Source code TypeSource code) (TSource code :Source code USource code -> topologicalType) :=
  Topological.copy (forall xSource code : U, T x) (prod_topology T).

HBSource code.instanceSource code DefinitionSource code _Source code (USource code :Source code TypeSource code) (TSource code :Source code USource code -> uniformType) :=
  Uniform.copy (forall xSource code : U, T x) (prod_topology T).

HBSource code.instanceSource code DefinitionSource code _Source code (USource code TSource code :Source code topologicalTypeSource code) :=
  Topological.copy
    (continuousType U T)
    (initial_topology (id : continuousType U T -> (U -> T))).

HBSource code.instanceSource code DefinitionSource code _Source code (USource code :Source code topologicalTypeSource code) (T : uniformType) :=
  Uniform.copy
    (continuousType U T)
    (initial_topology (id : continuousType U T -> (U -> T))).

End ArrowAsProduct.

Section product_spaces.
Local Import ArrowAsProduct.

Section projection_maps.
Context {ISource code : eqType} {KSource code : I -> topologicalType}.

Lemma proj_continuousUsed by
  • mathcomp.analysis.cantor
  • mathcomp.analysis.homotopy_theory.wedge_sigT
  • mathcomp.analysis.normedtype_theory.normed_module

Source code
iSource code : continuous (@proj I K i).
Proof.
move=> f; have /cvg_sup/(_ i)/cvg_image : f --> f by apply: cvg_id.
move=> h; apply: cvg_trans (h _) => {h}.
  by move=> Q /= [W nbdW <-]; apply: filterS nbdW; exact: preimage_image.
rewrite eqEsubset; split => y //; exists (dfwith f y) => //.
by rewrite dfwith_in.
Qed.

Lemma dfwith_continuousUsed by
  • mathcomp.analysis.homotopy_theory.wedge_sigT

Source code
gSource code (iSource code : I) : continuous (@dfwith I K g i).
Proof.
move=> z U [] P [] [] Q QfinP <- [] V JV Vpz.
move/(@preimage_subset _ _ (@dfwith _ _ g i))/filterS; apply.
apply: (@filterS _ _ _ ((@dfwith _ _ g i) @^-1` V)); first by exists V.
have [L Lsub /[dup] VL <-] := QfinP _ JV; rewrite preimage_bigcap.
apply: filter_bigI => /= M /[dup] LM /Lsub /set_mem [] w _ [+] + /[dup] + <-.
have [->|wnx] := eqVneq w i => N oN NM.
  apply: (@filterS _ _ _ N); first by move=> ? ?; rewrite /= dfwith_in.
  apply: open_nbhs_nbhs; split => //; move: Vpz.
  by rewrite -VL => /(_ _ LM); rewrite -NM /= dfwith_in.
apply: nearW => y /=; move: Vpz.
by rewrite -VL => /(_ _ LM); rewrite -NM /= ?dfwith_out // eq_sym.
Qed.

Lemma proj_openSource code iSource code (ASource code : set (prod_topology K)) : open A -> open (proj i @` A).
Proof.
move=> oA; rewrite openE => z [f Af <-]; rewrite openE in oA.
have {oA} := oA _ Af; rewrite /interior => nAf.
apply: (@filterS _ _ _ ((@dfwith _ _ f i) @^-1` A)).
  by move=> w Apw; exists (dfwith f w) => //; rewrite projK.
apply: dfwith_continuous => /=; move: nAf; congr (nbhs _ A).
by apply: functional_extensionality_dep => ?; case: dfwithP.
Qed.

Lemma hausdorff_productUsed by
  • mathcomp.analysis.cantor
  • mathcomp.analysis.homotopy_theory.wedge_sigT

Source code
:
  (forall xSource code, hausdorff_space (K x)) -> hausdorff_space (forall xSource code, K x).
Proof.
move=> hsdfK p q /= clstr; apply: functional_extensionality_dep => x.
apply: hsdfK; move: clstr; rewrite ?cluster_cvgE /= => -[G PG [GtoQ psubG]].
exists (proj x @ G); [exact: fmap_proper_filter|split].
  apply: cvg_trans; last exact: (@proj_continuous x q).
  by apply: cvg_app; exact: GtoQ.
move/(cvg_app (proj x)): psubG => /cvg_trans; apply.
exact: proj_continuous.
Qed.

End projection_maps.

Lemma tychonoffUsed by
  • mathcomp.analysis.cantor
  • mathcomp.analysis.normedtype_theory.matrix_normedtype
  • mathcomp.analysis.normedtype_theory.normed_module

Source code
 (ISource code : eqType) (TSource code : I -> topologicalType)
  (ASource code : forall iSource code, set (T i)) :
  (forall iSource code, compact (A i)) ->
  compact [set fSource code : forall iSource code, T i | forall iSource code, A i (f i)].
Proof.
have [-> _|] := eqVneq [set fSource code : forall iSource code, T i | forall iSource code, A i (f i)] set0.
  exact: compact0.
case/set0P => a0 Aa0 Aco; rewrite compact_ultra => F FU FA.
set subst_coord := fun (iSource code : I) (piSource code : T i) (fSource code : forall xSource code : I, T x) (jSource code : I) =>
  if eqP is ReflectT e then ecast iSource code (T i) (esym e) pi else f j.
have subst_coordT i pi f : subst_coord i pi f i = pi.
  rewrite /subst_coord; case: eqP => // e.
  by rewrite (eq_irrelevance e (erefl _)).
have subst_coordN i pi f j : i != j -> subst_coord i pi f j = f j.
  move=> inej; rewrite /subst_coord; case: eqP => // e.
  by move: inej; rewrite {1}e => /negP.
have pr_surj i : @^~ i @` [set: forall iSource code, T i] = setT.
  rewrite predeqE => pi; split=> // _.
  by exists (subst_coord i pi a0) => //; rewrite subst_coordT.
pose pF iSource code : set_system _ := [set @^~ i @` B | BSource code in F].
have pFultra i : UltraFilter (pF i) by exact: ultra_image (pr_surj i).
have pFA i : pF i (A i).
  exists [set gSource code | forall iSource code, A i (g i)] => //.
  rewrite predeqE => pi; split; first by move=> [g Ag <-]; apply: Ag.
  move=> Aipi; have [f Af] := filter_ex FA.
  exists (subst_coord i pi f); last exact: subst_coordT.
  move=> j; have [<-{j}|] := eqVneq i j; first by rewrite subst_coordT.
  by move=> /subst_coordN ->; exact: Af.
have cvpFA i : A i `&` [set pSource code | pF i --> p] !=set0.
  by rewrite -ultra_cvg_clusterE; apply: Aco.
exists (fun iSource code => xget (a0 i) (A i `&` [set pSource code | pF i --> p])).
split=> [i|]; first by have /(xgetPex (a0 i)) [] := cvpFA i.
apply/cvg_sup => i; apply/cvg_image=> //.
by have /(xgetPex (a0 i)) [] := cvpFA i.
Qed.

Lemma perfect_prodSource code {ISource code : Type} (iSource code : I) (KSource code : I -> topologicalType) :
  perfect_set [set: K i] -> perfect_set [set: forall iSource code, K i].
Proof.
move=> /perfectTP KPo; apply/perfectTP => f oF; apply: (KPo (f i)).
rewrite (_ : [set f i] = proj i @` [set f]).
  by rewrite eqEsubset; split => ? //; [move=> -> /=; exists f | case=> g ->].
by apply: (@proj_open {classic I} _ i); exact: oF.
Qed.

Lemma perfect_diagonalUsed by
  • mathcomp.analysis.cantor

Source code
 (KSource code : nat -> topologicalType) :
  (forall iSource code, exists xySource code : K i * K i, xy.1 != xy.2) ->
  perfect_set [set: forall iSource code, K i].
Proof.
move=> npts; split; first exact: closedT.
rewrite eqEsubset; split => f // _.
pose distincts (iSource code : nat) := projT1 (sigW (npts i)).
pose derange iSource code (zSource code : K i) :=
  if z == (distincts i).1 then (distincts i).2 else (distincts i).1.
pose g (NSource code iSource code : nat) := if (i < N)%N then f i else derange _ (f i).
have gcvg : g @ \oo --> f.
  apply/cvg_sup => N U [V] [[W] oW <-] WfN WU.
  by apply: (filterS WU); rewrite nbhs_simpl /g; exists N.+1 => // i /= ->.
move=> A /gcvg; rewrite nbhs_simpl => -[N _ An].
exists (g N); split => //; last by apply: An; rewrite /= leqnn.
apply/eqP => M; suff: g N N != f N by rewrite M; move/eqP.
rewrite /g ltnn /derange eq_sym; have [->|//] := eqVneq (f N) (distincts N).1.
exact: projT2 (sigW (npts N)).
Qed.

Lemma zero_dimension_prodUsed by
  • mathcomp.analysis.cantor

Source code
 (ISource code : choiceType) (TSource code : I -> topologicalType) :
  (forall iSource code, zero_dimensional (T i)) ->
  zero_dimensional (forall iSource code, T i).
Proof.
move=> dctTI x y /eqP xneqy.
have [i/eqP/dctTI [U [clU Ux nUy]]] : exists iSource code, x i <> y i.
  by apply/existsNP=> W; exact/xneqy/functional_extensionality_dep.
exists (proj i @^-1` U); split => //; apply: preimage_clopen => //.
exact/proj_continuous.
Qed.

Lemma totally_disconnected_prodSource code (ISource code : choiceType)
  (TSource code : I -> topologicalType) (ASource code : forall iSource code, set (T i)) :
  (forall iSource code, totally_disconnected (A i)) ->
  @totally_disconnected (forall iSource code, T i) (fun fSource code => forall iSource code, A i (f i)).
Proof.
move=> dsctAi x /= Aix; rewrite eqEsubset; split; last first.
  by move=> ? ->; exact: connected_component_refl.
move=> f /= [C /= [Cx CA ctC Cf]]; apply/functional_extensionality_dep => i.
suff : proj i @` C `<=` [set x i] by apply; exists f.
rewrite -(dsctAi i) // => Ti ?; exists (proj i @` C) => //.
split; [by exists x | by move=> ? [r Cr <-]; exact: CA |].
apply/(connected_continuous_connected ctC)/continuous_subspaceT.
exact: proj_continuous.
Qed.

A handy technique for embedding a space `T` into a product. The key interface is `separate_points_from_closed`, which guarantees that the topologies - `T`'s native topology - `sup (weak f_i)`: the sup of all the weak topologies of `f_i` - `weak (x => (f_1 x, f_2 x, ...))`: the weak topology from the product space are equivalent (the last equivalence seems to require `accessible_space`).
Section product_embeddings.
Context {ISource code : choiceType} {TSource code : topologicalType} {U_Source code : I -> topologicalType}.
Variable (f_Source code : forall iSource code, T -> U_ i).

Definition separate_points_from_closed

product_topology_def : forall [I : Type], (I -> topologicalType) -> Type product_topology_def is not universe polymorphic Arguments product_topology_def [I]%_type_scope T%_function_scope product_topology_def is transparent Expands to: Constant mathcomp.analysis.topology_theory.function_spaces.product_topology_def Declared in library mathcomp.analysis.topology_theory.function_spaces, line 131, characters 11-31


Source code
:= forall (USource code : set T) xSource code,
  closed U -> ~ U x -> exists iSource code, ~ (closure (f_ i @` U)) (f_ i x).

Hypothesis sepfSource code : separate_points_from_closed.
Hypothesis ctsfSource code : forall iSource code, continuous (f_ i).

Let initialTSource code : topologicalType :=
  sup_topology (fun iSource code => Topological.on (initial_topology (f_ i))).

Let PUSource code : topologicalType := prod_topology U_.

Local Notation sup_openSource code := (@open initialT).
Local Notation "'weak_open' i"Source code := (@open initialT) (at level 0).
Local Notation natural_openSource code := (@open T).

Lemma initial_sep_cvgSource code (FSource code : set_system T) (xSource code : T) :
  Filter F -> (F --> (x : T)) <-> (F --> (x : initialT)).
Proof.
move=> FF; split.
  move=> FTx; apply/cvg_sup => i U.
  have /= -> := @nbhsE (initial_topology (f_ i)) x.
  case=> B [[C oC <- ?]] /filterS; apply; apply: FTx; rewrite /= nbhsE.
  by exists (f_ i @^-1` C) => //; split => //; exact: open_comp.
move/cvg_sup => wiFx U; rewrite /= nbhs_simpl nbhsE => [[B [oB ?]]].
move/filterS; apply; have [//|i nclfix] := @sepf _ x (open_closedC oB).
apply: (wiFx i); have /= -> := @nbhsE (initial_topology (f_ i)) x.
exists (f_ i @^-1` (~` closure [set f_ i x | xSource code in ~` B])); [split=>//|].
  apply: open_comp; last by rewrite ?openC//; exact: closed_closure.
  by move=> + _; exact: (@initial_continuous _ _ (f_ i)).
rewrite -interiorC interiorEbigcup preimage_bigcup => z [V [oV]] VnB => /VnB.
by move/forall2NP => /(_ z) [] // /contrapT.
Qed.

Lemma initial_sep_nbhsESource code xSource code : @nbhs T T x = @nbhs T initialT x.
Proof.
rewrite predeqE => U; split; move: U.
  by have P := initial_sep_cvg x (nbhs_filter (x : initialT)); exact/P.
by have P := initial_sep_cvg x (nbhs_filter (x : T)); exact/P.
Qed.

Lemma initial_sep_openESource code : @open T = @open initialT.
Proof.
rewrite predeqE => A; rewrite ?openE /interior.
by split => + z => /(_ z); rewrite initial_sep_nbhsE.
Qed.

Definition join_product

separate_points_from_closed : forall {I : choiceType} {T : topologicalType} {U_ : I -> topologicalType}, (forall i : I, T -> U_ i) -> Prop separate_points_from_closed is not universe polymorphic Arguments separate_points_from_closed {I T} {U_}%_function_scope f_%_function_scope separate_points_from_closed is transparent Expands to: Constant mathcomp.analysis.topology_theory.function_spaces.separate_points_from_closed Declared in library mathcomp.analysis.topology_theory.function_spaces, line 329, characters 11-38


Source code
 (xSource code : T) : PU := f_ ^~ x.

Lemma join_product_continuousSource code : continuous join_product.
Proof.
suff : continuous (join_product : initialT -> PU).
  by move=> cts x U => /cts; rewrite nbhs_simpl /= -initial_sep_nbhsE.
move=> x; apply/cvg_sup; first exact/fmap_filter/(nbhs_filter (x : initialT)).
move=> i; move: x; apply/(@continuousP _ (initial_topology (@^~ i))) => A [B ? E].
rewrite -E (_ : @^~ i =  proj i) //.
have -> : join_product @^-1` (proj i @^-1` B) = f_ i @^-1` B by [].
apply: open_comp => // + _; rewrite /cvg_to => x U.
by rewrite nbhs_simpl /= -initial_sep_nbhsE; move: x U; exact: ctsf.
Qed.

Local Notation prod_openSource code := (@open (subspace (range join_product))).

Lemma join_product_openSource code (ASource code : set T) : open A ->
  open ((join_product @` A) : set (subspace (range join_product))).
Proof.
move=> oA; rewrite openE => y /= [x Ax] jxy.
have [// | i nAfiy] := @sepf (~` A) x (open_closedC oA).
pose B : set PU := proj i @^-1` (~` closure (f_ i @` (~` A))).
apply: (@filterS _ _ _ (range join_product `&` B)).
  move=> z [[w ?]] wzE Bz; exists w => //.
  move: Bz; rewrite /B -wzE -interiorC interiorEbigcup.
  case=> K [oK KsubA] /KsubA.
  have -> : proj i (join_product w) = f_ i w by [].
  by move=> /exists2P/forallNP/(_ w)/not_andP [] // /contrapT.
apply: open_nbhs_nbhs; split; last by rewrite -jxy.
apply: openI; first exact: open_subspaceT.
apply: open_subspaceW; apply: open_comp; last exact/closed_openC/closed_closure.
by move=> + _; exact: proj_continuous.
Qed.

Lemma join_product_injSource code : accessible_space T -> set_inj [set: T] join_product.
Proof.
move=> /accessible_closed_set1 cl1 x y; case: (eqVneq x y) => // xny _ _ jxjy.
have [] := @sepf [set y] x (cl1 y); first exact/eqP.
move=> i P; suff : join_product x i != join_product y i by rewrite jxjy => /eqP.
apply/negP; move: P; apply: contra_not => /eqP; rewrite /join_product => ->.
by apply: subset_closure; exists y.
Qed.

Lemma join_product_initialSource code : set_inj [set: T] join_product ->
  @open T = @open (initial_topology join_product).
Proof.
move=> inj; rewrite predeqE => U; split; first last.
  by move=> [V ? <-]; apply: open_comp => // + _; exact: join_product_continuous.
move=> /join_product_open/open_subspaceP [V oU VU].
exists V => //; have := @f_equal _ _ (preimage join_product) _ _ VU.
rewrite !preimage_setI // !preimage_range !setIT => ->.
rewrite eqEsubset; split; last exact: preimage_image.
by move=> z [w Uw] /inj <- //; rewrite inE.
Qed.

End product_embeddings.

Global Instance prod_topology_filterSource code (USource code : Type) (TSource code : U -> ptopologicalType)
  (fSource code : prod_topology T) : ProperFilter (nbhs f).
Proof.
exact: nbhs_pfilter. Qed.

End product_spaces.


the uniform topologies type
Section fct_Uniform.
Local Open Scope relation_scope.
Variables (TSource code : choiceType) (USource code : uniformType).

Definition fct_ent

join_product : forall {I : choiceType} {T : topologicalType} {U_ : I -> topologicalType}, (forall i : I, T -> U_ i) -> T -> prod_topology (fun x : I => U_ x) join_product is not universe polymorphic Arguments join_product {I T} {U_}%_function_scope f_%_function_scope x i join_product is transparent Expands to: Constant mathcomp.analysis.topology_theory.function_spaces.join_product Declared in library mathcomp.analysis.topology_theory.function_spaces, line 375, characters 11-23


Source code
:= filter_from (@entourage U)
  (fun PSource code => [set fgSource code | forall tSource code : T, P (fg.1 t, fg.2 t)]).

Lemma fct_ent_filterSource code : Filter fct_ent.
Proof.
apply: filter_from_filter; first by exists setT; apply: filterT.
move=> A B entA entB.
exists (A `&` B); first exact: filterI.
by move=> fg ABfg; split=> t; have [] := ABfg t.
Qed.

Lemma fct_ent_reflSource code ASource code : fct_ent A -> diagonal `<=` A.
Proof.
move=> [B entB sBA] fg feg; apply/sBA => t; rewrite feg.
exact: entourage_refl.
Qed.

Lemma fct_ent_invSource code ASource code : fct_ent A -> fct_ent A^-1.
Proof.
move=> [B entB sBA]; exists B^-1; first exact: entourage_inv.
by move=> fg Bgf; exact/sBA.
Qed.

Lemma fct_ent_splitSource code ASource code : fct_ent A -> exists2 BSource code, fct_ent B & B \; B `<=` A.
Proof.
move=> [B entB sBA].
exists [set fgSource code | forall tSource code, split_ent B (fg.1 t, fg.2 t)].
  by exists (split_ent B).
move=> fg [h spBfh spBhg].
by apply: sBA => t; apply: entourage_split (spBfh t) (spBhg t).
Qed.

Definition arrow_uniform_type

fct_ent : forall [T : choiceType] [U : uniformType], set_system ((T -> U) * (T -> U)) fct_ent is not universe polymorphic Arguments fct_ent [T U] _ fct_ent is transparent Expands to: Constant mathcomp.analysis.topology_theory.function_spaces.fct_ent Declared in library mathcomp.analysis.topology_theory.function_spaces, line 446, characters 11-18


Used by
  • mathcomp.analysis.numfun

Source code
: Type := T -> U.

#[export]Source code HBSource code.instanceSource code DefinitionSource code _Source code :=Source code ChoiceSource code.on arrow_uniform_type.
#[export]Source code HBSource code.instanceSource code DefinitionSource code _Source code :=Source code isUniformSource code.Build arrow_uniform_type
  fct_ent_filter fct_ent_refl fct_ent_inv fct_ent_split.

End fct_Uniform.

#[export]Source code HBSource code.instanceSource code DefinitionSource code _Source code {TSource code :Source code choiceType}Source code {U : puniformType} :=
  Pointed.on (arrow_uniform_type T U).

Lemma cvg_fct_entouragePSource code (TSource code : choiceType) (USource code : uniformType)
    (FSource code : set_system (arrow_uniform_type T U)) (FFSource code : Filter F)
    (fSource code : arrow_uniform_type T U) :
  F --> f <-> forall ASource code, entourage A ->
              \forall gSource code \near F, forall tSource code, A (f t, g t).
Proof.
split => [/cvg_entourageP Ff A entA|Ff].
  by apply: (Ff [set fgSource code | forall tSource code : T, A (fg.1 t, fg.2 t)]); exists A.
apply/cvg_entourageP => A [P entP sPA].
by near=> g do apply: sPA; apply: Ff.
Unshelve. all: by end_near. Qed.

Section fun_Complete.
Context {TSource code : choiceType} {USource code : completeType}.

Lemma fun_completeSource code (FSource code : set_system (arrow_uniform_type T U))
  {FFSource code :  ProperFilter F} : cauchy F -> cvg F.
Proof.
move=> Fc.
have /(_ _) /cauchy_cvg /cvg_app_entourageP cvF : cauchy (@^~_ @ F).
  move=> t A /= entA; rewrite near_simpl -near2E near_map2.
  by apply: Fc; exists A.
apply/cvg_ex; exists (fun tSource code => lim (@^~t @ F)).
apply/cvg_fct_entourageP => A entA; near=> f => t; near F => g.
apply: (entourage_split (g t)) => //; first by near: g; apply: cvF.
move: (t); near: g; near: f; apply: nearP_dep; apply: Fc.
by exists (split_ent A)^-1%relation => /=.
Unshelve. all: by end_near. Qed.

HBSource code.instanceSource code DefinitionSource code _Source code :=Source code Uniform_isCompleteSource code.Build
  (arrow_uniform_type T U) fun_complete.


End fun_Complete.

Functional metric spaces
Section fct_PseudoMetric.
Variable (TSource code : choiceType) (RSource code : numFieldType) (USource code : pseudoMetricType R).
Definition fct_ball

arrow_uniform_type : choiceType -> uniformType -> Type arrow_uniform_type is not universe polymorphic Arguments arrow_uniform_type T U arrow_uniform_type is transparent Expands to: Constant mathcomp.analysis.topology_theory.function_spaces.arrow_uniform_type Declared in library mathcomp.analysis.topology_theory.function_spaces, line 478, characters 11-29


Source code
 (xSource code : arrow_uniform_type T U) (epsSource code : R)
  (ySource code : arrow_uniform_type T U) := forall tSource code : T, ball (x t) eps (y t).
Lemma fct_ball_centerSource code (xSource code : T -> U) (eSource code : R) : 0 < e -> fct_ball x e x.
Proof.
by move=> /posnumP[{}e] ?. Qed.

Lemma fct_ball_symSource code (xSource code ySource code : T -> U) (eSource code : R) : fct_ball x e y -> fct_ball y e x.
Proof.
by move=> P t; apply: ball_sym. Qed.
Lemma fct_ball_triangleSource code (xSource code ySource code zSource code : T -> U) (e1Source code e2Source code : R) :
  fct_ball x e1 y -> fct_ball y e2 z -> fct_ball x (e1 + e2) z.
Proof.
by move=> xy yz t; apply: (@ball_triangle _ _ (y t)). Qed.
Lemma fct_entourageSource code : entourage = entourage_ fct_ball.
Proof.
rewrite predeqE => A; split; last first.
  by move=> [_/posnumP[e] sbeA]; exists [set xySource code | ball xy.1 e%:num xy.2].
move=> [P]; rewrite -entourage_ballE => -[_/posnumP[e] sbeP] sPA.
by exists e%:num => //= fg fg_e; apply: sPA => t; apply: sbeP; apply: fg_e.
Qed.

HBSource code.instanceSource code DefinitionSource code _Source code :=Source code Uniform_isPseudoMetricSource code.Build R
  (arrow_uniform_type T U) fct_ball_center fct_ball_sym
  fct_ball_triangle fct_entourage.
End fct_PseudoMetric.

Module ArrowAsUniformTypeSource code.
HBSource code.instanceSource code DefinitionSource code _Source code (USource code :Source code choiceTypeSource code) (V : uniformType) :=
  Uniform.copy (U -> V) (arrow_uniform_type U V).

HBSource code.instanceSource code DefinitionSource code _Source code (USource code :Source code choiceTypeSource code) (R : numFieldType)
    (V : pseudoMetricType R) :=
  PseudoMetric.copy (U -> V) (arrow_uniform_type U V).

HBSource code.instanceSource code DefinitionSource code _Source code (USource code :Source code topologicalTypeSource code) (T : uniformType) :=
  Uniform.copy
    (continuousType U T)
    (initial_topology (id : continuousType U T -> (U -> T))).


End ArrowAsUniformType.

Limit switching
Section Cvg_switch.
Context {T1Source code T2Source code : choiceType}.
Local Import ArrowAsUniformType.

Lemma cvg_switch_1Source code {USource code : uniformType}
  F1Source code {FF1Source code : ProperFilter F1} F2Source code {FF2Source code : Filter F2}
  (fSource code : T1 -> T2 -> U) (gSource code : T2 -> U) (hSource code : T1 -> U) (lSource code : U) :
  f @ F1 --> g -> (forall x1Source code, f x1 @ F2 --> h x1) -> h @ F1 --> l ->
  g @ F2 --> l.
Proof.
move=> fg fh hl; apply/cvg_app_entourageP => A entA.
near F1 => x1; near=> x2; apply: (entourage_split (h x1)) => //.
  by apply/xsectionP; near: x1; exact: hl.
apply: (entourage_split (f x1 x2)) => //.
  by apply/xsectionP; near: x2; exact: fh.
move: (x2); near: x1; have /cvg_fct_entourageP /(_ _^-1%relation):= fg; apply.
exact: entourage_inv.
Unshelve. all: by end_near. Qed.

Lemma cvg_switch_2Source code {USource code : completeType}
  F1Source code {FF1Source code : ProperFilter F1} F2Source code {FF2Source code : ProperFilter F2}
  (fSource code : T1 -> T2 -> U) (gSource code : T2 -> U) (hSource code : T1 -> U) :
  f @ F1 --> g -> (forall xSource code, f x @ F2 --> h x) ->
  [cvg h @ F1 in U].
Proof.
move=> fg fh; apply: cauchy_cvg => A entA.
rewrite !near_simpl -near2_pair near_map2; near=> x1 y1 => /=; near F2 => x2.
apply: (entourage_split (f x1 x2)) => //.
  by apply/xsectionP; near: x2; exact: fh.
apply: (entourage_split (f y1 x2)) => //; last first.
  apply/xsectionP; near: x2; apply/(fh _ (xsection _^-1%relation _)).
  exact: nbhs_entourage (entourage_inv _).
apply: (entourage_split (g x2)) => //; move: (x2); [near: x1|near: y1].
  have /cvg_fct_entourageP /(_ _^-1%relation) := fg; apply.
  exact: entourage_inv.
by have /cvg_fct_entourageP := fg; apply.
Unshelve. all: by end_near. Qed.

Lemma cvg_switchSource code {USource code : completeType}
  F1Source code (FF1Source code : ProperFilter F1) F2Source code (FF2Source code : ProperFilter F2)
  (fSource code : T1 -> T2 -> U) (gSource code : T2 -> U) (hSource code : T1 -> U) :
  f @ F1 --> g -> (forall x1Source code, f x1 @ F2 --> h x1) ->
  exists lSource code : U, h @ F1 --> l /\ g @ F2 --> l.
Proof.
move=> Hfg Hfh; have hcv := [elaborate cvg_switch_2 Hfg Hfh].
by exists (lim (h @ F1)); split=> //; apply: cvg_switch_1 Hfg Hfh hcv.
Qed.

End Cvg_switch.

Definition uniform_fun

fct_ball : forall [T : choiceType] [R : numFieldType] [U : pseudoMetricType R], arrow_uniform_type T U -> R -> arrow_uniform_type T U -> Prop fct_ball is not universe polymorphic Arguments fct_ball [T R U] x eps%_ring_scope y fct_ball is transparent Expands to: Constant mathcomp.analysis.topology_theory.function_spaces.fct_ball Declared in library mathcomp.analysis.topology_theory.function_spaces, line 532, characters 11-19


Source code
{USource code : Type} (ASource code : set U) (VSource code : Type) : Type := U -> V.

Notation "{ 'uniform`' A -> V }"Source code := (@uniform_fun _ A V) : type_scope.
Notation "{ 'uniform' U -> V }"Source code := ({uniform` [set: U] -> V}) : type_scope.
Notation "{ 'uniform' A , F --> f }"Source code :=
  (cvg_to F (nbhs (f : {uniform` A -> _}))) : classical_set_scope.
Notation "{ 'uniform' , F --> f }"Source code :=
  (cvg_to F (nbhs (f : {uniform _ -> _}))) : classical_set_scope.

Definition sigL_arrow

uniform_fun : forall {U : Type}, set U -> Type -> Type uniform_fun is not universe polymorphic Arguments uniform_fun {U}%_type_scope A%_classical_set_scope V%_type_scope uniform_fun is transparent Expands to: Constant mathcomp.analysis.topology_theory.function_spaces.uniform_fun Declared in library mathcomp.analysis.topology_theory.function_spaces, line 627, characters 11-22


Source code
{USource code : choiceType} (ASource code : set U) (VSource code : uniformType) :
  (U -> V) -> arrow_uniform_type A V := @sigL _ V A.

HBSource code.instanceSource code DefinitionSource code _Source code (USource code :Source code choiceTypeSource code) (A : set U) (V : uniformType) :=
  Uniform.copy {uniform` A -> V} (initial_topology (@sigL_arrow _ A V)).

Section RestrictedUniformTopology.
Context {USource code : choiceType} (ASource code : set U) {VSource code : uniformType} .

Lemma uniform_nbhsSource code (fSource code : {uniform` A -> V}) PSource code:
  nbhs f P <-> (exists ESource code, entourage E /\
    [set hSource code | forall ySource code, A y -> E(f y, h y)] `<=` P).
Proof.
split=> [[Q [[/= W oW <- /=] Wf subP]]|[E [entE subP]]].
  rewrite openE /= /interior in oW.
  case: (oW _ Wf) => ? [ /= E entE] Esub subW.
  exists E; split=> // h Eh; apply/subP/subW/xsectionP/Esub => /= [[u Au]].
  by apply: Eh => /=; rewrite -inE.
case : (pselect (exists (uSource code : U), True)); first last.
  move=> nU; apply: (filterS subP); apply: (@filterS _ _ _ setT).
  by move=> t _ /= y; move: nU; apply: absurd; exists y.
  exact: filterT.
case=> u0 _; near=> g; apply: subP => y /mem_set Ay; rewrite -!(sigLE A).
move: (SigSub _); near: g.
have := (@cvg_image _ _ (@sigL_arrow _ A V) _ f (nbhs_filter f)
  (image_sigL (f u0))).1 cvg_id [set hSource code | forall ySource code, E (sigL A f y, h y)].
case.
  exists [set fgSource code | forall ySource code, E (fg.1 y, fg.2 y)] => //; first by exists E.
  by move=> g /xsectionP.
move=> B nbhsB rBrE; apply: (filterS _ nbhsB) => g Bg [y yA].
by move: rBrE; rewrite eqEsubset; case => [+ _]; apply; exists g.
Unshelve. all: by end_near. Qed.

Lemma uniform_entourageSource code :
  @entourage {uniform` A -> V} =
  filter_from
    (@entourage V)
    (fun PSource code => [set fgSource code | forall tSource code : U, A t -> P (fg.1 t, fg.2 t)]).
Proof.
rewrite eqEsubset; split => P /=.
  case=> /= E [F entF FsubE EsubP]; exists F => //; case=> f g Ffg.
  by apply/EsubP/FsubE=> [[x p]] /=; apply: Ffg; move/set_mem: (p).
case=> E entE EsubP; exists [set fgSource code | forall tSource code, E (fg.1 t, fg.2 t)].
  by exists E.
case=> f g Efg; apply: EsubP => t /mem_set At.
by move: Efg => /= /(_ (@exist _ (fun xSource code => in_mem x (mem A)) _ At)).
Qed.

End RestrictedUniformTopology.

Lemma restricted_cvgESource code {USource code : choiceType} {VSource code : uniformType}
    (FSource code : set_system (U -> V)) ASource code (fSource code : U -> V) :
  {uniform A, F --> f} = (F --> (f : {uniform` A -> V})).
Proof.
by []. Qed.

Lemma pointwise_cvgESource code {USource code : Type} {VSource code : topologicalType}
    (FSource code : set_system (U -> V)) (ASource code : set U) (fSource code : U -> V) :
  {ptws, F --> f} = (F --> (f : {ptws U -> V})).
Proof.
by []. Qed.


We use this function to help Coq identify the correct notation to use when printing. Otherwise you get goals like `F --> f -> F --> f`.
Definition uniform_fun_family

sigL_arrow : forall {U : choiceType} [A : set U] [V : uniformType], (U -> V) -> arrow_uniform_type A V sigL_arrow is not universe polymorphic Arguments sigL_arrow {U} [A]%_classical_set_scope [V] _%_function_scope _ sigL_arrow is transparent Expands to: Constant mathcomp.analysis.topology_theory.function_spaces.sigL_arrow Declared in library mathcomp.analysis.topology_theory.function_spaces, line 636, characters 11-21


Source code
{USource code} VSource code (famSource code : set U -> Prop) := U -> V.

Notation "{ 'family' fam , U -> V }"Source code :=  (@uniform_fun_family U V fam).
Notation "{ 'family' fam , F --> f }"Source code :=
  (cvg_to F (@nbhs _ {family fam, _ -> _} f)) : type_scope.

HBSource code.instanceSource code DefinitionSource code _Source code {USource code :Source code choiceType}Source code {V : uniformType}
    (fam : set U -> Prop) :=
  Uniform.copy {family fam, U -> V} (sup_topology (fun kSource code : sigT fam =>
       Uniform.class {uniform` projT1 k -> V})).

Section UniformCvgLemmas.
Context {USource code : choiceType} {VSource code : uniformType}.

Lemma uniform_set1Source code FSource code (fSource code : U -> V) (xSource code : U) :
  Filter F -> {uniform [set x], F --> f} = (g x @[gSource code --> F] --> f x).
Proof.
move=> FF; rewrite propeqE; split.
  move=> + W => /(_ [set tSource code | W (t x)]) +.
  rewrite -[in X in _ -> X]nbhs_entourageE uniform_nbhs => + [Q entQ subW].
  by apply; exists Q; split => // h Qf; exact/subW/xsectionP/Qf.
move=> Ff W; rewrite uniform_nbhs => [[E] [entE subW]].
apply: (filterS subW); move/(nbhs_entourage (f x))/Ff: entE => //=; near_simpl.
by apply: filter_app; apply: nearW=> ? /xsectionP ? ? ->.
Qed.

Lemma uniform_subset_nbhsSource code (fSource code : U -> V) (ASource code BSource code : set U) :
  B `<=` A -> nbhs (f : {uniform` A -> V}) `=>` nbhs (f : {uniform` B -> V}).
Proof.
move => BsubA P /uniform_nbhs [E [entE EsubP]].
apply: (filterS EsubP); apply/uniform_nbhs; exists E; split => //.
by move=> h Eh y /BsubA Ay; exact: Eh.
Qed.

Lemma uniform_subset_cvgSource code (fSource code : U -> V) (ASource code BSource code : set U) FSource code :
  Filter F -> B `<=` A -> {uniform A, F --> f} -> {uniform B, F --> f}.
Proof.
move => FF /uniform_subset_nbhs => /(_ f).
by move=> nbhsF Acvg; apply: cvg_trans; [exact: Acvg|exact: nbhsF].
Qed.

Lemma pointwise_uniform_cvgUsed by
  • mathcomp.analysis.numfun

Source code
  (fSource code : U -> V) (FSource code : set_system (U -> V)) :
  Filter F -> {uniform, F --> f} -> {ptws, F --> f}.
Proof.
move=> FF; rewrite cvg_sup => + i; have isubT : [set i] `<=` setT by move=> ?.
move=> /(uniform_subset_cvg _ isubT); rewrite uniform_set1.
rewrite cvg_image; first by rewrite eqEsubset; split=> v // _; exists (cst v).
apply: cvg_trans => W /=; rewrite nbhs_simpl; exists (@^~ i @^-1` W) => //.
by rewrite image_preimage // eqEsubset; split=> // j _; exists (fun _ => j).
Qed.

Lemma cvg_sigLSource code (ASource code : set U) (fSource code : U -> V) (FSource code : set_system (U -> V)) :
    Filter F ->
  {uniform A, F --> f} <->
  {uniform, sigL A @ F --> sigL A f}.
Proof.
move=> FF; split.
- move=> cvgF P' /uniform_nbhs [E [entE EsubP]].
  apply: (filterS EsubP); apply: cvgF => /=.
  apply: (filterS (P := [set hSource code | forall ySource code, A y -> E (f y, h y)])).
    + by move=> h/= Eh [y ?] _; apply Eh; rewrite -inE.
    + by (apply/uniform_nbhs; eexists; split; eauto).
- move=> cvgF P' /= /uniform_nbhs [ E [/= entE EsubP]].
  apply: (filterS EsubP).
  move: (cvgF  [set hSource code | (forall ySource code , E (sigL A f y, h y))]) => /=.
  set Q := (x in (_ -> x) -> _); move=> W.
  have: Q by apply W, uniform_nbhs; exists E; split => // h + ?; apply.
  rewrite {}/W {}/Q; near_simpl => /= R; apply: (filterS _ R) => h /=.
  by rewrite forall_sig /sigL /=.
Qed.

Lemma eq_in_closeSource code (ASource code : set U) (fSource code gSource code : {uniform` A -> V}) :
  {in A, f =1 g} -> close f g.
Proof.
rewrite entourage_close => /eq_sigLP eqfg ? [E entE]; apply=> /=.
by rewrite /map_pair/sigL_arrow eqfg; exact: entourage_refl.
Qed.

Lemma hausdorrf_close_eq_inSource code (ASource code : set U) (fSource code gSource code : {uniform` A -> V}) :
  hausdorff_space V -> close f g = {in A, f =1 g}.
Proof.
move=> hV.
rewrite propeqE; split; last exact: eq_in_close.
rewrite entourage_close => C u; rewrite inE => uA; apply: hV.
rewrite /cluster -nbhs_entourageE /= => X Y [X' eX X'X] [Y' eY Y'Y].
exists (g u); split; [apply: X'X| apply: Y'Y]; apply/xsectionP; last first.
  exact: entourage_refl.
apply: (C [set fgSource code | forall ySource code, A y -> X' (fg.1 y, fg.2 y)]) => //=.
by rewrite uniform_entourage; exists X'.
Qed.

Lemma uniform_nbhsTUsed by
  • mathcomp.analysis.real_measure.measurable_realfun
  • mathcomp.analysis.numfun

Source code
 (fSource code : U -> V) :
  (nbhs (f : {uniform U -> V})) = nbhs (f : arrow_uniform_type U V).
Proof.
rewrite eqEsubset; split=> A.
  case/uniform_nbhs => E [entE] /filterS; apply.
  exists [set fhSource code | forall ySource code, E (fh.1 y, fh.2 y)]; first by exists E.
  by move=> ? /xsectionP /=.
case => J [E entE EJ] /filterS; apply; apply/uniform_nbhs; exists E.
by split => // z /= Efz; apply/xsectionP/EJ => t /=; exact: Efz.
Qed.

Lemma cvg_uniformUSource code (fSource code : U -> V) (FSource code : set_system (U -> V)) ASource code BSource code : Filter F ->
  {uniform A, F --> f} -> {uniform B, F --> f} ->
  {uniform (A `|` B), F --> f}.
Proof.
move=> FF AFf BFf Q /=/uniform_nbhs [E [entE EsubQ]].
apply: (filterS EsubQ).
rewrite (_:  [set hSource code | (forall ySource code : U, (A `|` B) y -> E (f y, h y))] =
    [set hSource code | forall ySource code, A y -> E (f y, h y)] `&`
    [set hSource code | forall ySource code, B y -> E (f y, h y)]).
- rewrite eqEsubset; split=> h.
  + by move=> R; split=> t ?; apply: R;[left| right].
  + by move=> [R1 R2] y [? | ?]; [apply: R1| apply: R2].
- apply: filterI; [apply: AFf| apply: BFf].
  + by apply/uniform_nbhs; exists E; split.
  + by apply/uniform_nbhs; exists E; split.
Qed.

Lemma cvg_uniform_set0Source code (FSource code : set_system (U -> V)) (fSource code : U -> V) : Filter F ->
  {uniform set0, F --> f}.
Proof.
move=> FF P /= /uniform_nbhs [E [? R]].
suff -> : P = setT by exact: filterT.
rewrite eqEsubset; split => //=.
by apply: subset_trans R => g _ ?.
Qed.

Lemma fam_cvgPSource code (famSource code : set U -> Prop) (FSource code : set_system (U -> V)) (fSource code : U -> V) :
  Filter F -> {family fam, F --> f} <->
  (forall ASource code : set U, fam A -> {uniform A, F --> f }).
Proof.
split; first by move=> /cvg_sup + A FA; move/(_ (existT _ _ FA)).
by move=> famFf /=; apply/cvg_sup => [[? ?] FA]; apply: famFf.
Qed.

Lemma family_cvg_subsetSource code (famASource code famBSource code : set U -> Prop) (FSource code : set_system (U -> V))
    (fSource code : U -> V) : Filter F ->
  famA `<=` famB -> {family famB, F --> f} -> {family famA, F --> f}.
Proof.
by move=> FF S /fam_cvgP famBFf; apply/fam_cvgP => A ?; apply/famBFf/S.
Qed.

Lemma family_cvg_finite_coversSource code (famASource code famBSource code : set U -> Prop)
  (FSource code : set_system (U -> V)) (fSource code : U -> V) : Filter F ->
  (forall PSource code, famA P ->
    exists (ISource code : choiceType) fSource code,
      (forall iSource code, famB (f i)) /\ finite_subset_cover [set: I] f P) ->
  {family famB, F --> f} -> {family famA, F --> f}.
Proof.
move=> FF ex_finCover /fam_cvgP rFf; apply/fam_cvgP => A famAA.
move: ex_finCover => /(_ _ famAA) [R [g [g_famB [D _]]]].
move/uniform_subset_cvg; apply.
elim/finSet_rect: D => X IHX.
have [->|/set0P[x xX]] := eqVneq [set` X] set0.
  by rewrite coverE bigcup_set0; apply: cvg_uniform_set0.
rewrite coverE (bigcup_fsetD1 x)//; apply: cvg_uniformU.
  exact/rFf/g_famB.
exact/IHX/fproperD1.
Qed.

End UniformCvgLemmas.

Lemma uniform_restrict_cvgUsed by
  • mathcomp.analysis.real_measure.measurable_realfun

Source code
{USource code : choiceType} {VSource code : puniformType}
    (FSource code : set_system (U -> V)) (fSource code : U -> V) ASource code : Filter F ->
  {uniform A, F --> f} <-> {uniform, restrict A @ F --> restrict A f}.
Proof.
move=> FF; rewrite cvg_sigL; split.
- rewrite -sigLK; move/(cvg_app valL) => D.
  apply: cvg_trans; first exact: D.
  move=> P /uniform_nbhs [E [/=entE EsubP]]; apply: (filterS EsubP).
  apply/uniform_nbhs; exists E; split=> //= h /=.
  rewrite /sigL => R u _; rewrite oinv_set_val.
  by case: insubP=> /= *; [apply: R|apply: entourage_refl].
- move/(@cvg_app _ _ _ _ (sigL A)).
  rewrite -fmap_comp sigL_restrict => D.
  apply: cvg_trans; first exact: D.
  move=> P /uniform_nbhs [E [/=entE EsubP]]; apply: (filterS EsubP).
  apply/uniform_nbhs; exists E; split=> //= h /=.
  rewrite /sigL => R [u Au] _ /=.
  by have := R u I; rewrite /patch Au.
Qed.


Section FamilyConvergence.

Lemma fam_cvgESource code {USource code : choiceType} {VSource code : uniformType} (FSource code : set_system (U -> V))
    (fSource code : U -> V) famSource code :
  {family fam, F --> f} = (F --> (f : {family fam, U -> V})).
Proof.
by []. Qed.

Lemma fam_nbhsSource code {USource code : choiceType} {VSource code : uniformType} (famSource code : set U -> Prop)
    (ASource code : set U) (ESource code : set (V * V)) (fSource code : {family fam, U -> V}) :
  entourage E -> fam A -> nbhs f [set gSource code | forall ySource code, A y -> E (f y, g y)].
Proof.
move=> entE famA; have /fam_cvgP /(_ A) : (nbhs f --> f) by []; apply => //.
by apply uniform_nbhs; exists E; split.
Qed.

Lemma fam_compact_nbhsSource code {USource code : topologicalType} {VSource code : uniformType}
    (ASource code : set U) (OSource code : set V) (fSource code : {family compact, U -> V}) :
  open O -> f @` A `<=` O -> compact A -> continuous f ->
  nbhs (f : {family compact, U -> V}) [set gSource code | forall ySource code, A y -> O (g y)].
Proof.
move=> oO fAO /[dup] cA /compact_near_coveringP/near_covering_withinP cfA ctsf.
near=> z => /=; (suff: A `<=` [set ySource code | O (z y)] by exact); near: z.
apply: cfA => x Ax; have : O (f x) by exact: fAO.
move: (oO); rewrite openE /= => /[apply] /[dup] /ctsf Ofx /=.
rewrite /interior -nbhs_entourageE => -[E entE EfO].
exists (f @^-1` xsection (split_ent E) (f x),
    [set gSource code | forall wSource code, A w -> split_ent E (f w, g w)]).
  split => //=; last exact: fam_nbhs.
  by apply: ctsf; rewrite /= -nbhs_entourageE; exists (split_ent E).
case=> y g [/= /xsectionP Efxy] AEg Ay; apply/EfO/xsectionP.
by apply: subset_split_ent => //; exists (f y) => //=; exact: AEg.
Unshelve. all: by end_near. Qed.

End FamilyConvergence.

It turns out `{family compact, U -> V}` can be generalized to only assume `topologicalType` on `V`. This topology is called the compact-open topology. This topology is special because it is the _only_ topology that will allow `curry`/`uncurry` to be continuous.
Section compact_open.
Context {TSource code USource code : topologicalType}.

Definition compact_open

uniform_fun_family : forall {U : Type}, Type -> (set U -> Prop) -> Type uniform_fun_family is not universe polymorphic Arguments uniform_fun_family {U}%_type_scope V%_type_scope fam%_function_scope uniform_fun_family is transparent Expands to: Constant mathcomp.analysis.topology_theory.function_spaces.uniform_fun_family Declared in library mathcomp.analysis.topology_theory.function_spaces, line 699, characters 11-29


Source code
: Type := T -> U.

Section compact_open_setwise.
Context {KSource code : set T}.

Definition compact_openK

compact_open : topologicalType -> topologicalType -> Type compact_open is not universe polymorphic Arguments compact_open {T U} compact_open is transparent Expands to: Constant mathcomp.analysis.topology_theory.function_spaces.compact_open Declared in library mathcomp.analysis.topology_theory.function_spaces, line 925, characters 11-23


Source code
:= let _ := K in compact_open.

Definition compact_openK_nbhs

compact_openK : forall {T : topologicalType}, topologicalType -> set T -> Type compact_openK is not universe polymorphic Arguments compact_openK {T U} {K}%_classical_set_scope compact_openK is transparent Expands to: Constant mathcomp.analysis.topology_theory.function_spaces.compact_openK Declared in library mathcomp.analysis.topology_theory.function_spaces, line 930, characters 11-24


Source code
 (fSource code : compact_openK) :=
  filter_from
    [set OSource code | f @` K `<=` O /\ open O]
    (fun OSource code => [set gSource code | g @` K `<=` O]).

Global Instance compact_openK_nbhs_filterSource code (fSource code : compact_openK) :
  ProperFilter (compact_openK_nbhs f).
Proof.
split; first by case=> g [gKO oO] /(_ f); apply.
apply: filter_from_filter; first by exists setT; split => //; exact: openT.
move=> P Q [fKP oP] [fKQ oQ]; exists (P `&` Q); first split.
- by move=> ? [z Kz M-]; split; [apply: fKP | apply: fKQ]; exists z.
- exact: openI.
by move=> g /= gPQ; split; exact: (subset_trans gPQ).
Qed.

HBSource code.instanceSource code DefinitionSource code _Source code :=Source code ChoiceSource code.on compact_openK.

HBSource code.instanceSource code DefinitionSource code _Source code :=Source code hasNbhsSource code.Build compact_openK compact_openK_nbhs.

Definition compact_open_of_nbhs

compact_openK_nbhs : forall {T U : topologicalType} {K : set T}, compact_openK -> set_system (T -> U) compact_openK_nbhs is not universe polymorphic Arguments compact_openK_nbhs {T U} {K}%_classical_set_scope f _ compact_openK_nbhs is transparent Expands to: Constant mathcomp.analysis.topology_theory.function_spaces.compact_openK_nbhs Declared in library mathcomp.analysis.topology_theory.function_spaces, line 932, characters 11-29


Source code
:= [set ASource code : set compact_openK | A `<=` nbhs^~ A].

Lemma compact_openK_nbhsE_subproofSource code (pSource code : compact_openK) :
  compact_openK_nbhs p =
    [set ASource code | exists BSource code : set compact_openK,
      [/\ compact_open_of_nbhs B, B p & B `<=` A]].
Proof.
rewrite eqEsubset; split => A /=.
  case=> B /= [fKB oB gKBA]; exists [set gSource code | g @` K `<=` B]; split => //.
  by move=> h /= hKB; exists B.
by case=> B [oB Bf /filterS]; apply; exact: oB.
Qed.

Lemma compact_openK_openE_subproofSource code :
  compact_open_of_nbhs = [set ASource code | A `<=` compact_openK_nbhs^~ A].
Proof.
by []. Qed.

HBSource code.instanceSource code DefinitionSource code _Source code :=Source code
  Nbhs_isTopological.Build compact_openK compact_openK_nbhs_filter
  compact_openK_nbhsE_subproof compact_openK_openE_subproof.

End compact_open_setwise.

Definition compact_open_def

compact_open_of_nbhs : forall {T U : topologicalType} {K : set T}, set (set compact_openK) compact_open_of_nbhs is not universe polymorphic Arguments compact_open_of_nbhs {T U} {K}%_classical_set_scope _ compact_open_of_nbhs is transparent Expands to: Constant mathcomp.analysis.topology_theory.function_spaces.compact_open_of_nbhs Declared in library mathcomp.analysis.topology_theory.function_spaces, line 952, characters 11-31


Source code
:=
  sup_topology (fun iSource code : sigT (@compact T) =>
    Topological.class (@compact_openK (projT1 i))).

HBSource code.instanceSource code DefinitionSource code _Source code :=Source code NbhsSource code.copy compact_open compact_open_def.

HBSource code.instanceSource code DefinitionSource code _Source code :Source code Nbhs_isTopologicalSource code compact_open :=
  Topological.copy compact_open compact_open_def.

Lemma compact_open_cvgPSource code (FSource code : set_system compact_open)
    (fSource code : compact_open) :
  Filter F ->
  F --> f <-> forall KSource code OSource code, @compact T K -> @open U O -> f @` K `<=` O ->
    F [set gSource code | g @` K `<=` O].
Proof.
move=> FF; split.
  by move/cvg_sup => + K O cptK ? ? => /(_ (existT _ _ cptK)); apply; exists O.
move=> fko; apply/cvg_sup => -[A cptK] O /= [C /= [fAC oC]].
by move/filterS; apply; exact: fko.
Qed.

Lemma compact_open_openSource code (KSource code : set T) (OSource code : set U) :
  compact K -> open O -> open ([set gSource code | g @` K `<=` O] : set compact_open).
Proof.
pose C := [set gSource code | g @` K `<=` O]; move=> cptK oO.
exists [set C]; last by rewrite bigcup_set1.
move=> _ ->; exists (fset1 C) => //; last by rewrite set_fset1 bigcap_set1.
by move=> _ /[!inE] ->; exists (existT _ _ cptK) => // z Cz; exists O.
Qed.

End compact_open.

HBSource code.instanceSource code DefinitionSource code _Source code {USource code :Source code topologicalType}Source code {V : ptopologicalType} K := 
    Pointed.on (@compact_openK U V K).

HBSource code.instanceSource code DefinitionSource code _Source code {USource code :Source code topologicalType}Source code {V : ptopologicalType} := 
  Pointed.on (@compact_open U V).


Notation "{ 'compact-open' , U -> V }"Source code := (@compact_open U V).
Notation "{ 'compact-open' , F --> f }"Source code :=
  (F --> (f : @compact_open _ _)).

Section compact_open_uniform.
Context {USource code : topologicalType} {VSource code : puniformType}.

Let small_ent_subSource code := @small_set_sub _ (@entourage V).

Lemma compact_open_fam_compactPSource code (fSource code : U -> V) (FSource code : set_system (U -> V)) :
  continuous f -> Filter F ->
  {compact-open, F --> f} <-> {family compact, F --> f}.
Proof.
move=> ctsf FF; split; first last.
  move=> cptF; apply/compact_open_cvgP => K O cptK oO fKO.
  apply: cptF; have := fam_compact_nbhs oO fKO cptK ctsf; apply: filter_app.
  by near=> g => /=  gKO ? [z Kx <-]; exact: gKO.
move/compact_open_cvgP=> cptOF; apply/cvg_sup => -[K cptK R].
case=> D [[E oE <-] Ekf] /filterS; apply.
move: oE; rewrite openE => /(_ _ Ekf); case => A [J entJ] EKR KfE.
near=> z; apply/KfE/xsectionP/EKR => -[u Kp]; rewrite /sigL_arrow /= /set_val /= /eqincl.
(have Ku : K u by rewrite inE in Kp); move: u Ku {D Kp}; near: z.
move/compact_near_coveringP/near_covering_withinP : (cptK); apply.
move=> u Ku; near (powerset_filter_from (@entourage V)) => E'.
have entE' : entourage E' by exact: (near (near_small_set _)).
pose C := f @^-1` xsection E' (f u).
pose B := \bigcup_(zSource code in K `&` closure C) interior (xsection E' (f z)).
have oB : open B by apply: bigcup_open => ? ?; exact: open_interior.
have fKB : f @` (K `&` closure C) `<=` B.
  move=> _ [z KCz <-]; exists z => //; rewrite /interior.
  by rewrite -nbhs_entourageE; exists E'.
have cptKC : compact (K `&` closure C).
  by apply: compact_closedI => //; exact: closed_closure.
have := cptOF (K `&` closure C) B cptKC oB fKB.
exists (C, [set gSource code | [set g x | xSource code in K `&` closure C] `<=` B]).
  split; last exact: cptOF.
  by apply: (ctsf) => //; rewrite /filter_of -nbhs_entourageE; exists E'.
case=> z h /= [Cz KB Kz].
case: (KB (h z)); first by exists z; split => //; exact: subset_closure.
move=> w [Kw Cw /interior_subset Jfwhz]; apply: subset_split_ent => //.
exists (f w); last first.
  apply: (near (small_ent_sub _) E') => //.
  exact/xsectionP.
apply: subset_split_ent => //; exists (f u).
  apply/entourage_sym; apply: (near (small_ent_sub _) E') => //.
  exact/xsectionP.
have [] := Cw (f @^-1` xsection E' (f w)).
  by apply: ctsf; rewrite /= -nbhs_entourageE; exists E'.
move=> r [Cr /= Ewr]; apply: subset_split_ent => //; exists (f r).
  apply: (near (small_ent_sub _) E') => //.
  exact/xsectionP.
apply/entourage_sym; apply: (near (small_ent_sub _) E') => //.
exact/xsectionP.
Unshelve. all: by end_near. Qed.

End compact_open_uniform.

Module ArrowAsCompactOpenSource code.
HBSource code.instanceSource code DefinitionSource code _Source code (USource code :Source code topologicalTypeSource code) (V : topologicalType) :=
  Topological.copy (U -> V) {compact-open, U -> V}.

HBSource code.instanceSource code DefinitionSource code _Source code (USource code :Source code topologicalTypeSource code) (V : topologicalType) :=
  Topological.copy (continuousType U V)
    (initial_topology (id : (continuousType U V) -> (U -> V)) ).
End ArrowAsCompactOpen.

Definition compactly_in

compact_open_def : topologicalType -> topologicalType -> Type compact_open_def is not universe polymorphic Arguments compact_open_def {T U} compact_open_def is transparent Expands to: Constant mathcomp.analysis.topology_theory.function_spaces.compact_open_def Declared in library mathcomp.analysis.topology_theory.function_spaces, line 975, characters 11-27


Source code
{USource code : topologicalType} (ASource code : set U) :=
  [set BSource code | B `<=` A /\ compact B].

Lemma compact_cvg_within_compactSource code {USource code : topologicalType} {VSource code : uniformType}
    (CSource code : set U) (FSource code : set_system (U -> V)) (fSource code : U -> V) :
  Filter F -> compact C ->
  {uniform C, F --> f} <-> {family compactly_in C, F --> f}.
Proof.
move=> FF CC.
apply: (iff_trans _ (iff_sym (fam_cvgP _ _ FF))); split.
- by move=> CFf D [/uniform_subset_cvg + _]; apply.
- by apply; split.
Qed.

Section UniformContinuousLimits.

Lemma uniform_limit_continuousUsed by
  • mathcomp.analysis.numfun

Source code
{USource code : topologicalType} {VSource code : uniformType}
    (FSource code : set_system (U -> V)) (fSource code : U -> V) :
  ProperFilter F -> (\forall gSource code \near F, continuous (g : U -> V)) ->
  {uniform, F --> f} -> continuous f.
Proof.
move=> PF ctsF Ff x; apply/cvg_app_entourageP => A entA; near F => g; near=> y.
apply: (entourage_split (g x)) => //.
  by near: g; apply/Ff/uniform_nbhs; exists (split_ent A); split => // ?; exact.
apply: (entourage_split (g y)) => //; near: y; near: g.
  by apply: (filterS _ ctsF) => g /(_ x) /cvg_app_entourageP; exact.
apply/Ff/uniform_nbhs; exists (split_ent (split_ent A))^-1%relation.
by split; [exact: entourage_inv | move=> g fg; near_simpl; near=> z; exact: fg].
Unshelve. all: end_near. Qed.

Lemma uniform_limit_continuous_subspaceUsed by
  • mathcomp.analysis.lebesgue_integral_theory.measurable_fun_approximation

Source code
{USource code : topologicalType} {VSource code : puniformType}
    (KSource code : set U) (FSource code : set_system (U -> V)) (fSource code : subspace K -> V) :
  ProperFilter F -> (\forall gSource code \near F, continuous (g : subspace K -> V)) ->
  {uniform K, F --> f} -> {within K, continuous f}.
Proof.
move=> PF ctsF Ff; apply: (@subspace_eq_continuous _ _ _ (restrict K f)).
  by rewrite /restrict => ? ->.
apply: (@uniform_limit_continuous (subspace K) _ (restrict K @ F) _).
  apply: (filterS _ ctsF) => g; apply: subspace_eq_continuous.
  by rewrite /restrict => ? ->.
by apply (@uniform_restrict_cvg _ _ F ) => //; exact: PF.
Qed.

End UniformContinuousLimits.

Section UniformPointwise.
Context {USource code : topologicalType} {VSource code : uniformType}.

Definition singletons

compactly_in : forall {U : topologicalType}, set U -> set (set U) compactly_in is not universe polymorphic Arguments compactly_in {U} A%_classical_set_scope _ compactly_in is transparent Expands to: Constant mathcomp.analysis.topology_theory.function_spaces.compactly_in Declared in library mathcomp.analysis.topology_theory.function_spaces, line 1080, characters 11-23


Source code
{TSource code : Type} := [set [set x] | xSource code in [set: T]].

Lemma pointwise_cvg_family_singletonSource code FSource code (fSource code: U -> V):
  Filter F -> {ptws, F --> f} = {family @singletons U, F --> f}.
Proof.
move=> FF; apply/propext.
rewrite (@fam_cvgP _ _ singletons). (* BUG: slowdown if no arguments *)
rewrite cvg_sup; split.
  move=> + A [x _ <-] => /(_ x); rewrite uniform_set1.
  rewrite cvg_image; first by rewrite eqEsubset; split=> v // _; exists (cst v).
  apply: cvg_trans => W /=; rewrite ?nbhs_simpl /fmap /= => [[W' + <-]].
  by apply: filterS => g W'g /=; exists g.
move=> + i; have /[swap] /[apply] : singletons [set i] by exists i.
rewrite uniform_set1.
rewrite cvg_image; first by rewrite eqEsubset; split=> v // _; exists (cst v).
move=> + W //=; rewrite ?nbhs_simpl => Q => /Q Q'; exists (@^~ i @^-1` W) => //.
by rewrite eqEsubset; split => [j [? + <-//]|j Wj]; exists (fun _ => j).
Qed.

Lemma pointwise_cvg_compact_familySource code FSource code (fSource code : U -> V) :
  Filter F -> {family compact, F --> f} -> {ptws, F --> f}.
Proof.
move=> PF; rewrite pointwise_cvg_family_singleton; apply: family_cvg_subset.
by move=> A [x _ <-]; exact: compact_set1.
Qed.

Lemma pointwise_cvgPUsed by
  • mathcomp.analysis.numfun

Source code
FSource code (fSource code: U -> V):
  Filter F -> {ptws, F --> f} <-> forall (tSource code : U), (fun gSource code => g t) @ F --> f t.
Proof.
move=> Ff; rewrite pointwise_cvg_family_singleton; split.
  move/fam_cvgP => + t A At => /(_ [set t]); rewrite uniform_set1; apply => //.
  by exists t.
by move=> pf; apply/fam_cvgP => ? [t _ <-]; rewrite uniform_set1; exact: pf.
Qed.

End UniformPointwise.

Section ArzelaAscoli.
Context {XSource code : topologicalType} {YSource code : puniformType} {hsdfSource code : hausdorff_space Y}.
Implicit Types (I : Type).

The key condition in Arzela-Ascoli that, like uniform continuity, moves a quantifier around so all functions have the same "deltas":
Definition equicontinuous

singletons : forall {T : Type}, set (set T) singletons is not universe polymorphic Arguments singletons {T}%_type_scope _ singletons is transparent Expands to: Constant mathcomp.analysis.topology_theory.function_spaces.singletons Declared in library mathcomp.analysis.topology_theory.function_spaces, line 1128, characters 11-21


Source code
{ISource code} (WSource code : set I) (dSource code : I -> (X -> Y)) :=
  forall xSource code (ESource code : set (Y * Y)), entourage E ->
    \forall ySource code \near x, forall iSource code, W i -> E (d i x, d i y).

Lemma equicontinuous_subsetSource code {ISource code JSource code} (WSource code : set I) (VSource code : set J)
    {fWSource code : I -> X -> Y} {fVSource code : J -> X -> Y} :
  fW @`W `<=` fV @` V -> equicontinuous V fV -> equicontinuous W fW.
Proof.
move=> WsubV + x E entE => /(_ x E entE); apply: filterS => y VE i Wi.
by case: (WsubV (fW i)); [exists i | move=> j Vj <-; exact: VE].
Qed.

Lemma equicontinuous_subset_idSource code (WSource code VSource code : set (X -> Y)) :
  W `<=` V -> equicontinuous V id -> equicontinuous W id.
Proof.
move=> WsubV; apply: equicontinuous_subset => ? [y ? <- /=]; exists y => //.
exact: WsubV.
Qed.

Lemma equicontinuous_continuous_forSource code {ISource code} (WSource code : set I) (fWSource code : I -> X -> Y) iSource code xSource code :
  {for x, equicontinuous W fW} -> W i -> {for x, continuous (fW i)}.
Proof.
move=> ectsW Wf; apply/cvg_entourageP => E entE; near_simpl.
by near=> y; apply: (near (ectsW _ entE) y).
Unshelve. end_near. Qed.

Lemma equicontinuous_continuousSource code {ISource code} (WSource code : set I) (fWSource code : I -> (X -> Y)) (iSource code : I) :
  equicontinuous W fW -> W i -> continuous (fW i).
Proof.
move=> ectsW Wf x; apply: equicontinuous_continuous_for; last exact: Wf.
by move=> ?; exact: ectsW.
Qed.

A convenient notion that is in between compactness in `{family compact, X -> y}` and compactness in `{ptws X -> y}`:
Definition pointwise_precompact

equicontinuous : forall {X : topologicalType} {Y : puniformType} {I : Type}, set I -> (I -> X -> Y) -> Prop equicontinuous is not universe polymorphic Arguments equicontinuous {X Y} {I}%_type_scope W%_classical_set_scope d%_function_scope equicontinuous is transparent Expands to: Constant mathcomp.analysis.topology_theory.function_spaces.equicontinuous Declared in library mathcomp.analysis.topology_theory.function_spaces, line 1171, characters 11-25


Source code
{ISource code} (WSource code : set I) (dSource code : I -> X -> Y) :=
  forall xSource code, precompact [set d i x | iSource code in W].

Lemma pointwise_precompact_subsetSource code {ISource code JSource code} (WSource code : set I) (VSource code : set J)
    {fWSource code : I -> X -> Y} {fVSource code : J -> X -> Y} :
  fW @` W `<=` fV @` V -> pointwise_precompact V fV ->
  pointwise_precompact W fW.
Proof.
move=> WsubV + x => /(_ x) pcptV; apply: precompact_subset pcptV => y [i Wi <-].
by case: (WsubV (fW i)); [exists i | move=> j Vj <-; exists j].
Qed.

Lemma pointwise_precompact_precompactSource code {ISource code} (WSource code : set I) (fWSource code : I -> (X -> Y)) :
  pointwise_precompact W fW -> precompact ((fW @` W) : set {ptws X -> Y}).
Proof.
rewrite precompactE => ptwsPreW.
pose K := fun xSource code => closure [set fW i x | iSource code in W].
set R := [set fSource code : {ptws X -> Y} | forall xSource code : X, K x (f x)].
have C : compact R.
  by apply: tychonoff => x; rewrite -precompactE; move: ptwsPreW; exact.
apply: (subclosed_compact _ C); first exact: closed_closure.
have WsubR : (fW @` W) `<=` R.
  by move=> f [i Wi <-] x; rewrite /K; apply: subset_closure; exists i.
rewrite closureE; apply: smallest_sub => //.
by apply: compact_closed => //=; exact: hausdorff_product.
Qed.

Lemma uniform_pointwise_compactSource code (WSource code : set (X -> Y)) :
  compact (W : set (@uniform_fun_family X Y compact)) ->
  compact (W : set {ptws X -> Y}).
Proof.
rewrite [x in x _ -> _]compact_ultra [x in _ -> x _]compact_ultra.
move=> + F UF FW => /(_ F UF FW) [h [Wh Fh]]; exists h; split => //.
by move=> Q Fq; apply: (pointwise_cvg_compact_family _ Fh).
Qed.

Lemma precompact_pointwise_precompactSource code (WSource code : set {family compact, X -> Y}) :
  precompact W -> pointwise_precompact W id.
Proof.
move=> + x; rewrite ?precompactE => pcptW.
have : compact (proj x @` (closure W)).
  apply: continuous_compact => //; apply: continuous_subspaceT=> g.
  move=> E nbhsE; have := (@proj_continuous _ _ x g E nbhsE).
  exact: (@pointwise_cvg_compact_family _ _ (nbhs g)).
move=> /[dup]/(compact_closed hsdf)/closure_id -> /subclosed_compact.
apply; first exact: closed_closure.
by apply/closureS/image_subset; exact: (@subset_closure _ W).
Qed.

Lemma pointwise_cvg_entourageSource code (xSource code : X) (fSource code : {ptws X -> Y}) ESource code :
  entourage E -> \forall gSource code \near f, E (f x, g x).
Proof.
move=> entE; have : ({ptws, nbhs f --> f}) by [].
have ? : Filter (nbhs f) by exact: nbhs_pfilter. (* NB: This Filter (nbhs f) used to infer correctly. *)
rewrite pointwise_cvg_family_singleton => /fam_cvgP /(_ [set x]).
rewrite uniform_set1 => /(_ _ [set ySource code | E (f x, y)]); apply; first by exists x.
by move: E entE; exact/cvg_entourageP.
Qed.

Lemma equicontinuous_closureSource code (WSource code : set {ptws X -> Y}) :
  equicontinuous W id -> equicontinuous (closure W) id.
Proof.
move=> ectsW x E entE; near=> y => f clWf.
have ? : ProperFilter (within W (nbhs (f : {ptws X -> Y}))).
  exact: within_nbhs_proper. (* TODO: This ProperFilter _ also used to infer correctly. *)
near (within W (nbhs (f : {ptws X -> Y}))) => g.
near: g; rewrite near_withinE; near_simpl; near=> g => Wg.
apply: (@entourage_split _ (g x)) => //.
  exact: (near (pointwise_cvg_entourage _ _ _)).
apply: (@entourage_split _ (g y)) => //; first exact: (near (@ectsW x _ _)).
by apply/entourage_sym; exact: (near (pointwise_cvg_entourage _ _ _)).
Unshelve. all: by end_near. Qed.

Definition small_ent_sub

pointwise_precompact : forall {X : topologicalType} {Y : puniformType} {I : Type}, set I -> (I -> X -> Y) -> Prop pointwise_precompact is not universe polymorphic Arguments pointwise_precompact {X Y} {I}%_type_scope W%_classical_set_scope d%_function_scope pointwise_precompact is transparent Expands to: Constant mathcomp.analysis.topology_theory.function_spaces.pointwise_precompact Declared in library mathcomp.analysis.topology_theory.function_spaces, line 1206, characters 11-31


Source code
:= @small_set_sub _ (@entourage Y).

Lemma pointwise_compact_cvgSource code (FSource code : set_system {ptws X -> Y}) (fSource code : {ptws X -> Y}) :
  ProperFilter F ->
  (\forall WSource code \near powerset_filter_from F, equicontinuous W id) ->
  {ptws, F --> f} <-> {family compact, F --> f}.
Proof.
move=> PF /near_powerset_filter_fromP; case.
  exact: equicontinuous_subset_id.
move=> W; wlog Wf : f W / W f.
  move=> + FW /equicontinuous_closure => /(_ f (closure (W : set {ptws X -> Y}))) Q.
  split => Ff; last by apply: pointwise_cvg_compact_family.
  apply/Q => //.
    by (rewrite closureEcvg; exists F; [|split]) => // ? /= /filterS; apply.
  by apply: (filterS _ FW) => z Wz; apply: subset_closure.
move=> FW ectsW; split=> [ptwsF|]; last exact: pointwise_cvg_compact_family.
apply/fam_cvgP => K ? U /=; rewrite uniform_nbhs => [[E [eE EsubU]]].
suff : \forall gSource code \near within W (nbhs (f : {ptws X -> Y})),
    forall ySource code, K y -> E (f y, g y).
  rewrite near_withinE; near_simpl => N; apply: (filter_app _ _ FW).
  by apply: ptwsF; near=> g => ?; apply: EsubU; apply: (near N g).
near (powerset_filter_from (@entourage Y)) => E'.
have entE' : entourage E' by exact: (near (near_small_set _)).
pose Q := fun (hSource code : X -> Y) xSource code => E' (f x, h x).
apply: (iffLR (compact_near_coveringP K)) => // x Kx.
near=> y g => /=.
apply: (entourage_split (f x) eE).
  apply entourage_sym; apply: (near (small_ent_sub _) E') => //.
  exact: (near (ectsW x E' entE') y).
apply: (@entourage_split _ (g x)) => //.
  apply: (near (small_ent_sub _) E') => //.
  near: g; near_simpl; apply: (@cvg_within _ (nbhs (f : {ptws X -> Y}))).
  exact: pointwise_cvg_entourage.
apply: (near (small_ent_sub _) E') => //.
apply: (near (ectsW x E' entE')) => //.
exact: (near (withinT _ (nbhs_filter (f : {ptws X -> Y})))).
Unshelve. all: end_near. Qed.

Lemma pointwise_compact_closureSource code (WSource code : set (X -> Y)) :
  equicontinuous W id ->
  closure (W : set {family compact, X -> Y}) =
  closure (W : set {ptws X -> Y}).
Proof.
rewrite ?closureEcvg // predeqE => ? ?.
split; move=> [F PF [Fx WF]]; (exists F; last split) => //.
  apply/@pointwise_compact_cvg => //; apply/near_powerset_filter_fromP.
    exact: equicontinuous_subset_id.
  by exists W => //; exact: WF.
apply/@pointwise_compact_cvg => //; apply/near_powerset_filter_fromP.
  exact: equicontinuous_subset_id.
by exists W => //; exact: WF.
Qed.

Lemma pointwise_precompact_equicontinuousSource code (WSource code : set (X -> Y)) :
  pointwise_precompact W id ->
  equicontinuous W id ->
  precompact (W : set {family compact, X -> Y }).
Proof.
move=> /pointwise_precompact_precompact + ectsW.
rewrite ?precompactE compact_ultra compact_ultra pointwise_compact_closure //.
move=> /= + F UF FcW => /(_ F UF); rewrite image_id => /(_ FcW)[p [cWp Fp]].
exists p; split => //; apply/pointwise_compact_cvg => //.
apply/near_powerset_filter_fromP; first exact: equicontinuous_subset_id.
exists (closure (W : set {ptws X -> Y })) => //.
exact: equicontinuous_closure.
Qed.

Section precompact_equicontinuous.
Hypothesis lcptXSource code : locally_compact [set: X].

Lemma compact_equicontinuousSource code (WSource code : set {family compact, X -> Y}) :
  (forall fSource code, W f -> continuous f) ->
  compact (W : set {family compact, X -> Y}) ->
  equicontinuous W id.
Proof.
move=> ctsW cptW x E entE.
have [//|U UWx [cptU clU]] := @lcptX x; rewrite withinET in UWx.
near (powerset_filter_from (@entourage Y)) => E'.
have entE' : entourage E' by exact: (near (near_small_set _)).
pose Q := fun (ySource code : X) (fSource code : {family compact, X -> Y}) => E' (f x, f y).
apply: (iffLR (compact_near_coveringP W)) => // f Wf; near=> g y => /=.
apply: (entourage_split (f x) entE).
  apply/entourage_sym; apply: (near (small_ent_sub _) E') => //.
  exact: (near (fam_nbhs _ entE' (@compact_set1 _ x)) g).
apply: (entourage_split (f y) (entourage_split_ent entE)).
  apply: (near (small_ent_sub _) E') => //.
  by apply/xsectionP; near: y; apply: (@ctsW f Wf x); exact: nbhs_entourage.
apply: (near (small_ent_sub _) E') => //.
by apply: (near (fam_nbhs _ entE' cptU) g) => //; exact: (near UWx y).
Unshelve. all: end_near. Qed.

Lemma precompact_equicontinuousSource code (WSource code : set {family compact, X -> Y}) :
  (forall fSource code, W f -> continuous f) ->
  precompact (W : set {family compact, X -> Y}) ->
  equicontinuous W id.
Proof.
move=> pcptW ctsW; apply: (equicontinuous_subset_id (@subset_closure _ W)).
apply: compact_equicontinuous; last by rewrite -precompactE.
move=> f; rewrite closureEcvg => [[G PG [Gf GW]]] x B /=.
rewrite -nbhs_entourageE => -[E entE] /filterS; apply; near_simpl.
suff ctsf : continuous f.
  near=> x0; apply/xsectionP; near: x0.
  by move: E entE; apply/cvg_app_entourageP; exact: ctsf.
apply/continuous_localP => x'; apply/near_powerset_filter_fromP.
  by move=> ? ?; exact: continuous_subspaceW.
case: (@lcptX x') => // U; rewrite withinET => nbhsU [cptU _].
exists U => //; apply: (uniform_limit_continuous_subspace PG _ _).
  by near=> g; apply: continuous_subspaceT; near: g; exact: GW.
by move/fam_cvgP/(_ _ cptU) : Gf.
Unshelve. all: end_near. Qed.

End precompact_equicontinuous.

Theorem AscoliSource code (WSource code : set {family compact, X -> Y}) :
    locally_compact [set: X] ->
  pointwise_precompact W id /\ equicontinuous W id <->
    (forall fSource code, W f -> continuous f) /\
    precompact (W : set {family compact, X -> Y}).
Proof.
move=> lcpt; split => [[Wid ectsW]|[fWf]pcptW].
  split=> [?|]; first exact: equicontinuous_continuous.
  exact: pointwise_precompact_equicontinuous.
split; last exact: precompact_equicontinuous.
exact: precompact_pointwise_precompact.
Qed.

End ArzelaAscoli.

Section currying.
Local Import ArrowAsCompactOpen.

Section cartesian_closed.
Context {USource code VSource code WSource code : topologicalType}.

In this section, we consider under what conditions \ `[f in U ~> V ~> W | continuous f /\ forall u, continuous (f u)]` \ and \ `[f in U * V ~> W | continuous f]` \ are homeomorphic. - Always: \ `curry` sends continuous functions to continuous functions. - `V` locally_compact + regular or Hausdorff: \ `uncurry` sends continuous functions to continuous functions. - `U` regular or Hausdorff: \ `curry` itself is a continuous map. - `U` regular or Hausdorff AND `V` locally_compact + regular or Hausdorff \ `uncurry` itself is a continuous map. \ Therefore `curry`/`uncurry` are homeomorphisms. So the category of locally compact regular spaces is cartesian closed.

Lemma continuous_currySource code (fSource code : U * V -> W) :
  continuous f ->
    continuous (curry f) /\ forall uSource code, continuous (curry f u).
Proof.
move=> ctsf; split; first last.
  by move=> u z; apply: (continuous_comp _ (ctsf (u, z))); exact: cvg_pair.
move=> x; apply/compact_open_cvgP => K O /= cptK oO fKO.
near=> z => w /= [+ + <-]; near: z.
move/compact_near_coveringP/near_covering_withinP : cptK; apply.
move=> v Kv; have [[P Q] [Px Qv] PQfO] : nbhs (x, v) (f @^-1` O).
  by apply: ctsf; move: oO; rewrite openE; apply; apply: fKO; exists v.
by exists (Q, P) => // -[b a] /= [Qb Pa] Kb; exact: PQfO.
Unshelve. all: by end_near. Qed.

Lemma continuous_curry_funSource code (fSource code : U * V -> W) :
  continuous f -> continuous (curry f).
Proof.
by case/continuous_curry. Qed.

Lemma continuous_curry_cvgSource code (fSource code : U * V -> W) (uSource code : U) (vSource code : V) :
  continuous f -> curry f z.1 z.2 @[zSource code --> (u, v)] --> curry f u v.
Proof.
move=> cf D /cf; rewrite !nbhs_simpl /curry /=; apply: filterS => z ? /=.
by rewrite -surjective_pairing.
Qed.

Lemma continuous_uncurry_regularSource code (fSource code : U -> V -> W) :
  locally_compact [set: V] -> @regular_space V -> continuous f ->
  (forall uSource code, continuous (f u)) -> continuous (uncurry f).
Proof.
move=> lcV reg cf cfp /= [u v] D; rewrite /= nbhsE => -[O [oO Ofuv]] /filterS.
apply; have [B] := @lcV v I; rewrite withinET => Bv [cptB clB].
have [R Rv RO] : exists2 RSource code, nbhs v R & forall zSource code, closure R z -> O (f u z).
  have [] := reg v (f u @^-1` O); first by apply: cfp; exact: open_nbhs_nbhs.
  by move=> R ? ?; exists R.
exists (f @^-1` [set gSource code | g @` (B `&` closure R) `<=` O], B `&` closure R).
  (split; [apply/cf/open_nbhs_nbhs; split | apply: filterI]) => //.
  - apply: compact_open_open => //; apply: compact_closedI => //.
    exact: closed_closure.
  - by move=> ? [x [? + <-]]; apply: RO.
  - by apply: filterS; first exact: subset_closure.
by case=> a r /= [fBMO [Br] cmR]; apply: fBMO; exists r.
Qed.

Lemma continuous_uncurrySource code (fSource code : U -> V -> W) :
  locally_compact [set: V] -> hausdorff_space V -> continuous f ->
  (forall uSource code, continuous (f u)) -> continuous (uncurry f).
Proof.
move=> lcV hsdf ctsf cf; apply: continuous_uncurry_regular => //.
move=> v; have [B] := @lcV v I; rewrite withinET => Bv [cptB clB].
by move=> z; exact: (compact_regular _ cptB).
Qed.

Lemma curry_continuousSource code (fSource code : (U * V)%type -> W) : continuous f -> @regular_space U ->
  {for f, continuous curry}.
Proof.
move=> ctsf regU; apply/compact_open_cvgP.
  by apply: fmap_filter; exact: nbhs_filter.
move=> K ? cptK [D OfinIo <-] fKD /=; near=> z => w [+ + <-]; near: z.
move/compact_near_coveringP/near_covering_withinP : (cptK); apply => u Ku.
have [] := fKD (curry f u); first by exists u.
move=> E /[dup] /[swap] /OfinIo [N Asub <- DIN INf].
suff : \forall x'Source code \near u & iSource code \near nbhs f, K x' ->
    (\bigcap_(iSource code in [set` N]) i) (curry i x').
  apply: filter_app; near=> a b => /[apply] ?.
  by exists (\bigcap_(iSource code in [set` N]) i).
apply: filter_bigI_within => R RN; have /set_mem [[M cptM _]] := Asub _ RN.
have Rfu : R (curry f u) by exact: INf.
move/(_ _ Rfu) => [O [fMO oO] MOR]; near=> p => /= Ki; apply: MOR => + [+ + <-].
move=> _ v Mv; move: v Mv Ki; near: p.
have umb : \forall ySource code \near u, (forall bSource code, M b -> nbhs (y, b) (f @^-1` O)).
  move/compact_near_coveringP/near_covering_withinP : (cptM); apply => v Mv.
  have [[P Q] [Pu Qv] PQO] : nbhs (u, v) (f @^-1` O).
    by apply: ctsf; apply: open_nbhs_nbhs; split => //; apply: fMO; exists v.
  exists (Q, P); [by []| move=> [b a [/= Qb Pa Mb]]].
  by apply: ctsf; apply: open_nbhs_nbhs; split => //; exact: PQO.
move/compact_near_coveringP/near_covering_withinP : (cptM); apply => v Mv.
have [P' P'u cPO] := regU u _ umb.
pose L := [set hSource code | h @` ((K `&` closure P') `*` M) `<=` O].
exists (setT, P' `*` L).
  split => //; [exact: filterT|]; exists (P', L) => //; split => //.
  apply: open_nbhs_nbhs; split; first apply: compact_open_open => //.
    apply: compact_setX => //; apply: compact_closedI => //.
    exact: closed_closure.
  by move=> ? [[a b] [[Ka /cPO +] Mb <-]] => /(_ _ Mb)/nbhs_singleton.
move=> [b [a h]] [/= _ [Pa] +] Ma Ka; apply.
by exists (a, b); split => //; split => //; exact/subset_closure.
Unshelve. all: by end_near. Qed.

Lemma uncurry_continuousSource code (fSource code : U -> V -> W) :
  locally_compact [set: V] -> @regular_space V -> @regular_space U ->
  continuous f -> (forall uSource code, continuous (f u)) ->
  {for f, continuous uncurry}.
Proof.
move=> lcV regV regU ctsf ctsfp; apply/compact_open_cvgP.
  by apply: fmap_filter; exact:nbhs_filter.
move=> /= K O cptK oO fKO; near=> h => ? [+ + <-]; near: h.
move/compact_near_coveringP/near_covering_withinP: (cptK); apply.
case=> u v Kuv.
have : exists PSource code QSource code, [/\ closed P, compact Q, nbhs u P,
    nbhs v Q & P `*` Q `<=` uncurry f @^-1` O].
  have : continuous (uncurry f) by exact: continuous_uncurry_regular.
  move/continuousP/(_ _ oO); rewrite openE => /(_ (u, v))[].
    by apply: fKO; exists (u, v).
  case=> /= P' Q' [P'u Q'v] PQO.
  have [B] := @lcV v I; rewrite withinET; move=> Bv [cptB clB].
  have [P Pu cPP'] := regU u P' P'u; have [Q Qv cQQ'] := regV v Q' Q'v.
  exists (closure P), (B `&` closure Q); split.
  - exact: closed_closure.
  - by apply: compact_closedI => //; exact: closed_closure.
  - by apply: filterS; first exact: subset_closure.
  - by apply: filterI=> //; apply: filterS; first exact: subset_closure.
  - by case => a b [/cPP' ?] [_ /cQQ' ?]; exact: PQO.
case=> P [Q [clP cptQ Pu Qv PQfO]]; pose R := [set gSource code : V -> W | g @` Q `<=` O].
(have oR : open R by exact: compact_open_open); pose P' := f @^-1` R.
pose L := [set hSource code : U -> V -> W | h @` (fst @` K `&` P) `<=` R].
exists ((P `&` P') `*` Q, L); first split => /=.
- exists (P `&` P', Q) => //; split => //=; apply: filterI => //.
  apply: ctsf; apply: open_nbhs_nbhs; split => // _ [b Qb <-].
  by apply: (PQfO (u, b)); split => //; exact: nbhs_singleton.
- rewrite nbhs_simpl /=; apply: open_nbhs_nbhs; split.
    apply: compact_open_open => //; apply: compact_closedI => //.
    apply: continuous_compact => //; apply: continuous_subspaceT => x.
    exact: cvg_fst.
  move=> /= _ [a [Kxa Pa] <-] _ [b Qb <-].
  by apply: (PQfO (a, b)); split => //; exact: nbhs_singleton.
move=> [[a b h]] [/= [[Pa P'a] Qb Lh] Kab].
apply: (Lh (h a)); first by exists a => //; split => //; exists (a, b).
by exists b.
Unshelve. all: by end_near. Qed.

End cartesian_closed.

End currying.

Section big_continuous.
Context {USource code : topologicalType} {ISource code : Type}
  (opSource code : U -> U -> U) (x0Source code : U) (PSource code : pred I).
Hypothesis cont_opSource code : continuous (fun xSource code : U * U => op x.1 x.2).

Lemma cvg_bigUsed by
  • mathcomp.analysis.normedtype_theory.pseudometric_normed_Zmodule

Source code
{TSource code : Type} (FSource code : set_system T) (rSource code : seq I)
    (FfSource code : I -> T -> U) (FaSource code : I -> U) :
  Filter F ->
  (forall iSource code, P i -> Ff i x @[xSource code --> F] --> Fa i) ->
  \big[op/x0]_(iSource code <- r | P i) (Ff i x) @[xSource code --> F] -->
    \big[op/x0]_(iSource code <- r | P i) Fa i.
Proof.
move=> FF cvg_f.
elim: r => [|i r IHr].
  rewrite big_nil [X in X @ _](_ : _ = cst x0)//.
  by apply/funext => t; rewrite big_nil.
rewrite big_cons.
under eq_cvg do rewrite big_cons.
case: ifPn => // Pi.
apply: (@cvg_comp _ _ _
  (fun x1Source code => (Ff i x1, \big[op/x0]_(jSource code <- r | P j) Ff j x1)) _ _
  (nbhs (Fa i, \big[op/x0]_(jSource code <- r | P j) Fa j)) _ _
  (continuous_curry_cvg cont_op)).
by apply: cvg_pair => //; exact: cvg_f.
Qed.

Lemma continuous_bigUsed by
  • mathcomp.analysis.normedtype_theory.pseudometric_normed_Zmodule

Source code
{TSource code : topologicalType} (rSource code : seq I)
    (FSource code : I -> T -> U) :
  (forall iSource code, P i -> continuous (F i)) ->
  continuous (fun xSource code => \big[op/x0]_(iSource code <- r | P i) F i x).
Proof.
by move=> F_cont x; apply: cvg_big => // i /F_cont; exact.
Qed.

Lemma within_continuous_bigSource code {TSource code : topologicalType} (ASource code : set T) (rSource code : seq I)
    (FSource code : I -> T -> U) :
  (forall iSource code, P i -> {within A, continuous (F i)}) ->
  {within A, continuous (fun xSource code => \big[op/x0]_(iSource code <- r | P i) F i x)}.
Proof.
by move=> ? ?; exact: continuous_big. Qed.

End big_continuous.

Definition eval

small_ent_sub : forall {Y : puniformType} [E : set (Y * Y)], entourage E -> \forall E' \near powerset_filter_from entourage, (E' `<=` E)%classic small_ent_sub is not universe polymorphic Arguments small_ent_sub {Y} [E]%_classical_set_scope _ small_ent_sub is transparent Expands to: Constant mathcomp.analysis.topology_theory.function_spaces.small_ent_sub Declared in library mathcomp.analysis.topology_theory.function_spaces, line 1279, characters 11-24


Source code
{XSource code YSource code : topologicalType} : continuousType X Y * X -> Y :=
  uncurry (id : continuousType X Y -> (X -> Y)).

Section composition.

Local Import ArrowAsCompactOpen.

Lemma eval_continuousSource code {XSource code YSource code : topologicalType} :
  locally_compact [set: X] -> regular_space X -> continuous (@eval X Y).
Proof.
move=> lcX rsX; apply: continuous_uncurry_regular => //.
  exact: initial_continuous.
by move=> ?; exact: continuous_fun.
Qed.

Lemma compose_continuousSource code {XSource code YSource code ZSource code : topologicalType} :
  locally_compact [set: X] -> @regular_space X ->
  locally_compact [set: Y] -> @regular_space Y ->
  continuous (uncurry
    (comp : continuousType Y Z -> continuousType X Y -> continuousType X Z)).
Proof.
move=> lX rX lY rY; apply: continuous_comp_initial.
set F := _ \o _.
rewrite -[F]uncurryK; apply: continuous_curry_fun.
pose g := uncurry F \o prodAr \o swap; rewrite /= in g *.
have -> : uncurry F = uncurry F \o prodAr \o prodA by rewrite funeqE => -[[]].
move=> z; apply: continuous_comp; first exact: prodA_continuous.
have -> : uncurry F \o prodAr = uncurry F \o prodAr \o swap \o swap.
  by rewrite funeqE => -[[]].
apply: continuous_comp; first exact: swap_continuous.
pose h (fxgSource code : continuousType X Y * X * continuousType Y Z) : Z :=
  eval (fxg.2, (eval fxg.1)).
have <- : h = uncurry F \o prodAr \o swap.
  by rewrite /h/g/uncurry/swap/F funeqE => -[[]].
rewrite /h.
apply: (@continuous2_cvg _ _ _ _ _ _ snd (eval \o fst) (curry eval)).
- by apply: continuous_curry_cvg; exact: eval_continuous.
- exact: cvg_snd.
- by apply: cvg_comp; [exact: cvg_fst | exact: eval_continuous].
Qed.

End composition.