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

gauge.gauge : forall {T : uniformType}, set (T * T) -> set_system (T * T) gauge.gauge is not universe polymorphic Arguments gauge.gauge {T} E%_classical_set_scope _ gauge.gauge is transparent Expands to: Constant mathcomp.analysis.topology_theory.separation_axioms.gauge.gauge Declared in library mathcomp.analysis.topology_theory.separation_axioms, line 1009, characters 11-16


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

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

Variable : Type.

Definition
product_topology_def

gauge.type : forall {T : uniformType} [E : set (T * T)], entourage E -> Type gauge.type is not universe polymorphic Arguments gauge.type {T} [E]%_classical_set_scope entE gauge.type is transparent Expands to: Constant mathcomp.analysis.topology_theory.separation_axioms.gauge.type Declared in library mathcomp.analysis.topology_theory.separation_axioms, line 1068, characters 11-15


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

.
instanceSource code
DefinitionSource code
 ( -> topologicalType) :=
  Topological.copy (prod_topology T) (product_topology_def T).

.
instanceSource code
DefinitionSource code
 ( -> uniformType) :=
  Uniform.copy (prod_topology T)
    (sup_topology (fun => Uniform.class (initial_topology (@proj _ T i)))).

.
instanceSource code
DefinitionSource code
 (
realTypeSource code
) (Ii : countType)
    (Tc : Ii -> pseudoMetricType R) := PseudoMetric.copy (prod_topology Tc)
  (sup_pseudometric (fun => 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
.
.
instanceSource code
DefinitionSource code
 () ( -> topologicalType) :=
  Topological.copy (forall : U, T x) (prod_topology T).

.
instanceSource code
DefinitionSource code
 () ( -> uniformType) :=
  Uniform.copy (forall : U, T x) (prod_topology T).

.
instanceSource code
DefinitionSource code
 (
topologicalTypeSource code
) :=
  Topological.copy
    (continuousType U T)
    (initial_topology (id : continuousType U T -> (U -> T))).

.
instanceSource code
DefinitionSource 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 { : eqType} { : I -> topologicalType}.

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

Source 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
 ( : 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
 ( : 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 , hausdorff_space (K x)) -> hausdorff_space (forall , 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.normed_module
  • mathcomp.analysis.normedtype_theory.matrix_normedtype

Source code
 ( : eqType) ( : I -> topologicalType)
  ( : forall , set (T i)) :
  (forall , compact (A i)) ->
  compact [set : forall , T i | forall , A i (f i)].
Proof.
have [-> _|] := eqVneq [set : forall , T i | forall , A i (f i)] set0.
  exact: compact0.
case/set0P => a0 Aa0 Aco; rewrite compact_ultra => F FU FA.
set subst_coord := fun ( : I) ( : T i) ( : forall : I, T x) ( : I) =>
  if eqP is ReflectT e then ecast  (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 , T i] = setT.
  rewrite predeqE => pi; split=> // _.
  by exists (subst_coord i pi a0) => //; rewrite subst_coordT.
pose pF : set_system _ := [set @^~ i @` B | in F].
have pFultra i : UltraFilter (pF i) by exact: ultra_image (pr_surj i).
have pFA i : pF i (A i).
  exists [set | forall , 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 | pF i --> p] !=set0.
  by rewrite -ultra_cvg_clusterE; apply: Aco.
exists (fun => xget (a0 i) (A i `&` [set | 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
{ : Type} ( : I) ( : I -> topologicalType) :
  perfect_set [set: K i] -> perfect_set [set: forall , 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
 ( : nat -> topologicalType) :
  (forall , exists : K i * K i, xy.1 != xy.2) ->
  perfect_set [set: forall , K i].
Proof.
move=> npts; split; first exact: closedT.
rewrite eqEsubset; split => f // _.
pose distincts ( : nat) := projT1 (sigW (npts i)).
pose derange  ( : K i) :=
  if z == (distincts i).1 then (distincts i).2 else (distincts i).1.
pose g ( : 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
 ( : choiceType) ( : I -> topologicalType) :
  (forall , zero_dimensional (T i)) ->
  zero_dimensional (forall , T i).
Proof.
move=> dctTI x y /eqP xneqy.
have [i/eqP/dctTI [U [clU Ux nUy]]] : exists , 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
 ( : choiceType)
  ( : I -> topologicalType) ( : forall , set (T i)) :
  (forall , totally_disconnected (A i)) ->
  @totally_disconnected (forall , T i) (fun => forall , 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 { : choiceType} { : topologicalType} { : I -> topologicalType}.
Variable ( : forall , T -> U_ i).

Definition
separate_points_from_closed

perfect_set : forall {T : topologicalType}, set T -> Prop perfect_set is not universe polymorphic Arguments perfect_set {T} A%_classical_set_scope perfect_set is transparent Expands to: Constant mathcomp.analysis.topology_theory.separation_axioms.perfect_set Declared in library mathcomp.analysis.topology_theory.separation_axioms, line 1096, characters 11-22


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

Hypothesis : separate_points_from_closed.
Hypothesis : forall , continuous (f_ i).

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

Let : 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
 ( : set_system T) ( : 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 | 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
: @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
Source 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
 ( : 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
 ( : Type) ( : U -> ptopologicalType)
  ( : 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 ( : choiceType) ( : uniformType).

Definition := filter_from (@entourage U)
  (fun => [set | forall : 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
: 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
: 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
: fct_ent A -> exists2 , fct_ent B & B \; B `<=` A.
Proof.
move=> [B entB sBA].
exists [set | forall , 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
Used by
  • mathcomp.analysis.numfun

Source code
: Type := T -> U.

#[export]Source code
.
instanceSource code
DefinitionSource code
.on arrow_uniform_type.
#[export]Source code
.
instanceSource code
DefinitionSource 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
.
instanceSource code
DefinitionSource code
choiceType}Source code
{U : puniformType} :=
  Pointed.on (arrow_uniform_type T U).

Lemma
cvg_fct_entouragePSource code
 ( : choiceType) ( : uniformType)
    ( : set_system (arrow_uniform_type T U)) ( : Filter F)
    ( : arrow_uniform_type T U) :
  F --> f <-> forall , entourage A ->
              \forall \near F, forall , A (f t, g t).
Proof.
split => [/cvg_entourageP Ff A entA|Ff].
  by apply: (Ff [set | forall : 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 { : choiceType} { : completeType}.

Lemma
fun_completeSource code
 ( : set_system (arrow_uniform_type T U))
  { :  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 => 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.

.
instanceSource code
DefinitionSource code
Uniform_isCompleteSource code
.Build
  (arrow_uniform_type T U) fun_complete.


End fun_Complete.

Functional metric spaces
Section fct_PseudoMetric.
Variable ( : choiceType) ( : numFieldType) ( : pseudoMetricType R).
Definition
fct_ball
Source code
 ( : arrow_uniform_type T U) ( : R)
  ( : arrow_uniform_type T U) := forall : T, ball (x t) eps (y t).
Lemma
fct_ball_centerSource code
 ( : T -> U) ( : R) : 0 < e -> fct_ball x e x.
Proof.
by move=> /posnumP[{}e] ?. Qed.

Lemma
fct_ball_symSource code
 ( : T -> U) ( : 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
 ( : T -> U) ( : 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 | 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.

.
instanceSource code
DefinitionSource 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
.
.
instanceSource code
DefinitionSource code
 (
choiceTypeSource code
) (V : uniformType) :=
  Uniform.copy (U -> V) (arrow_uniform_type U V).

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

.
instanceSource code
DefinitionSource 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 { : choiceType}.
Local Import ArrowAsUniformType.

Lemma
cvg_switch_1Source code
{ : uniformType}
   { : ProperFilter F1} { : Filter F2}
  ( : T1 -> T2 -> U) ( : T2 -> U) ( : T1 -> U) ( : U) :
  f @ F1 --> g -> (forall , 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
{ : completeType}
   { : ProperFilter F1} { : ProperFilter F2}
  ( : T1 -> T2 -> U) ( : T2 -> U) ( : T1 -> U) :
  f @ F1 --> g -> (forall , 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
{ : completeType}
   ( : ProperFilter F1)  ( : ProperFilter F2)
  ( : T1 -> T2 -> U) ( : T2 -> U) ( : T1 -> U) :
  f @ F1 --> g -> (forall , f x1 @ F2 --> h x1) ->
  exists : 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
Source code
{ : Type} ( : set U) ( : 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
Source code
{ : choiceType} ( : set U) ( : uniformType) :
  (U -> V) -> arrow_uniform_type A V := @sigL _ V A.

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

Section RestrictedUniformTopology.
Context { : choiceType} ( : set U) { : uniformType} .

Lemma
uniform_nbhsSource code
 ( : {uniform` A -> V}) :
  nbhs f P <-> (exists , entourage E /\
    [set | forall , 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 ( : 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 | forall , E (sigL A f y, h y)].
case.
  exists [set | forall , 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 => [set | forall : 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 | forall , 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 => in_mem x (mem A)) _ At)).
Qed.

End RestrictedUniformTopology.

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

Lemma
pointwise_cvgESource code
{ : Type} { : topologicalType}
    ( : set_system (U -> V)) ( : set U) ( : 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
Source 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.

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

Section UniformCvgLemmas.
Context { : choiceType} { : uniformType}.

Lemma
uniform_set1Source code
 ( : U -> V) ( : U) :
  Filter F -> {uniform [set x], F --> f} = (g x @[ --> F] --> f x).
Proof.
move=> FF; rewrite propeqE; split.
  move=> + W => /(_ [set | 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
 ( : U -> V) ( : 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
 ( : U -> V) ( : set U) :
  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
  ( : U -> V) ( : 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
 ( : set U) ( : U -> V) ( : 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 | forall , 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 | (forall , 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
 ( : set U) ( : {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
 ( : set U) ( : {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 | forall , A y -> X' (fg.1 y, fg.2 y)]) => //=.
by rewrite uniform_entourage; exists X'.
Qed.

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

Source 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 | forall , 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
 ( : U -> V) ( : set_system (U -> V)) : 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 | (forall : U, (A `|` B) y -> E (f y, h y))] =
    [set | forall , A y -> E (f y, h y)] `&`
    [set | forall , 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
 ( : set_system (U -> V)) ( : 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
 ( : set U -> Prop) ( : set_system (U -> V)) ( : U -> V) :
  Filter F -> {family fam, F --> f} <->
  (forall : 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
 ( : set U -> Prop) ( : set_system (U -> V))
    ( : 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
 ( : set U -> Prop)
  ( : set_system (U -> V)) ( : U -> V) : Filter F ->
  (forall , famA P ->
    exists ( : choiceType) ,
      (forall , 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.measurable_realfun

Source code
{ : choiceType} { : puniformType}
    ( : set_system (U -> V)) ( : U -> V) : 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
{ : choiceType} { : uniformType} ( : set_system (U -> V))
    ( : U -> V) :
  {family fam, F --> f} = (F --> (f : {family fam, U -> V})).
Proof.
by []. Qed.

Lemma
fam_nbhsSource code
{ : choiceType} { : uniformType} ( : set U -> Prop)
    ( : set U) ( : set (V * V)) ( : {family fam, U -> V}) :
  entourage E -> fam A -> nbhs f [set | forall , 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
{ : topologicalType} { : uniformType}
    ( : set U) ( : set V) ( : {family compact, U -> V}) :
  open O -> f @` A `<=` O -> compact A -> continuous f ->
  nbhs (f : {family compact, U -> V}) [set | forall , A y -> O (g y)].
Proof.
move=> oO fAO /[dup] cA /compact_near_coveringP/near_covering_withinP cfA ctsf.
near=> z => /=; (suff: A `<=` [set | 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 | forall , 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 { : topologicalType}.

Definition
compact_open
Source code
: Type := T -> U.

Section compact_open_setwise.
Context { : set T}.

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

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

Global Instance
compact_openK_nbhs_filterSource 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.

.
instanceSource code
DefinitionSource code
.on compact_openK.

.
instanceSource code
DefinitionSource code
hasNbhsSource code
.Build compact_openK compact_openK_nbhs.

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

Lemma
compact_openK_nbhsE_subproofSource code
 ( : compact_openK) :
  compact_openK_nbhs p =
    [set | exists : set compact_openK,
      [/\ compact_open_of_nbhs B, B p & B `<=` A]].
Proof.
rewrite eqEsubset; split => A /=.
  case=> B /= [fKB oB gKBA]; exists [set | 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 | A `<=` compact_openK_nbhs^~ A].
Proof.
by []. Qed.

.
instanceSource code
DefinitionSource 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

sigT_nbhs : forall {I : choiceType} {X : I -> topologicalType}, {i : I & X i} -> set_system {i : I & X i} sigT_nbhs is not universe polymorphic Arguments sigT_nbhs {I} {X}%_function_scope x _ sigT_nbhs is transparent Expands to: Constant mathcomp.analysis.topology_theory.sigT_topology.sigT_nbhs Declared in library mathcomp.analysis.topology_theory.sigT_topology, line 26, characters 11-20


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

.
instanceSource code
DefinitionSource code
.copy compact_open compact_open_def.

.
instanceSource code
DefinitionSource code
Nbhs_isTopologicalSource code
compact_open :=
  Topological.copy compact_open compact_open_def.

Lemma
compact_open_cvgPSource code
 ( : set_system compact_open)
    ( : compact_open) :
  Filter F ->
  F --> f <-> forall , @compact T K -> @open U O -> f @` K `<=` O ->
    F [set | 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
 ( : set T) ( : set U) :
  compact K -> open O -> open ([set | g @` K `<=` O] : set compact_open).
Proof.
pose C := [set | 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.

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

.
instanceSource code
DefinitionSource 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 { : topologicalType} { : puniformType}.

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

Lemma
compact_open_fam_compactPSource code
 ( : U -> V) ( : 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_( 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 | [set g x | 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
.
.
instanceSource code
DefinitionSource code
 (
topologicalTypeSource code
) (V : topologicalType) :=
  Topological.copy (U -> V) {compact-open, U -> V}.

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

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

Lemma
compact_cvg_within_compactSource code
{ : topologicalType} { : uniformType}
    ( : set U) ( : set_system (U -> V)) ( : 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
{ : topologicalType} { : uniformType}
    ( : set_system (U -> V)) ( : U -> V) :
  ProperFilter F -> (\forall \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
{ : topologicalType} { : puniformType}
    ( : set U) ( : set_system (U -> V)) ( : subspace K -> V) :
  ProperFilter F -> (\forall \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 { : topologicalType} { : uniformType}.

Definition
singletons
Source code
{ : Type} := [set [set x] | in [set: T]].

Lemma
pointwise_cvg_family_singletonSource 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
 ( : 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
 (: U -> V):
  Filter F -> {ptws, F --> f} <-> forall ( : U), (fun => 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 { : topologicalType} { : puniformType} { : 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
Source code
{} ( : set I) ( : I -> (X -> Y)) :=
  forall  ( : set (Y * Y)), entourage E ->
    \forall \near x, forall , W i -> E (d i x, d i y).

Lemma
equicontinuous_subsetSource code
{ } ( : set I) ( : set J)
    { : I -> X -> Y} { : 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
 ( : 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
{} ( : set I) ( : I -> X -> Y) :
  {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
{} ( : set I) ( : I -> (X -> Y)) ( : 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
Source code
{} ( : set I) ( : I -> X -> Y) :=
  forall , precompact [set d i x | in W].

Lemma
pointwise_precompact_subsetSource code
{ } ( : set I) ( : set J)
    { : I -> X -> Y} { : 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
{} ( : set I) ( : I -> (X -> Y)) :
  pointwise_precompact W fW -> precompact ((fW @` W) : set {ptws X -> Y}).
Proof.
rewrite precompactE => ptwsPreW.
pose K := fun => closure [set fW i x | in W].
set R := [set : {ptws X -> Y} | forall : 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
 ( : 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
 ( : 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
 ( : X) ( : {ptws X -> Y}) :
  entourage E -> \forall \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 | E (f x, y)]); apply; first by exists x.
by move: E entE; exact/cvg_entourageP.
Qed.

Lemma
equicontinuous_closureSource 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
Source code
:= @small_set_sub _ (@entourage Y).

Lemma
pointwise_compact_cvgSource code
 ( : set_system {ptws X -> Y}) ( : {ptws X -> Y}) :
  ProperFilter F ->
  (\forall \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 \near within W (nbhs (f : {ptws X -> Y})),
    forall , 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 ( : X -> Y) => 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
 ( : 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
 ( : 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 : locally_compact [set: X].

Lemma
compact_equicontinuousSource code
 ( : set {family compact, X -> Y}) :
  (forall , 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 ( : X) ( : {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
 ( : set {family compact, X -> Y}) :
  (forall , 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  ( : set {family compact, X -> Y}) :
    locally_compact [set: X] ->
  pointwise_precompact W id /\ equicontinuous W id <->
    (forall , 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 { : 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
 ( : U * V -> W) :
  continuous f ->
    continuous (curry f) /\ forall , 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
 ( : U * V -> W) :
  continuous f -> continuous (curry f).
Proof.
by case/continuous_curry. Qed.

Lemma
continuous_curry_cvgSource code
 ( : U * V -> W) ( : U) ( : V) :
  continuous f -> curry f z.1 z.2 @[ --> (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
 ( : U -> V -> W) :
  locally_compact [set: V] -> @regular_space V -> continuous f ->
  (forall , 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 , nbhs v R & forall , 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 | 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
 ( : U -> V -> W) :
  locally_compact [set: V] -> hausdorff_space V -> continuous f ->
  (forall , 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
 ( : (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 \near u & \near nbhs f, K x' ->
    (\bigcap_( in [set` N]) i) (curry i x').
  apply: filter_app; near=> a b => /[apply] ?.
  by exists (\bigcap_( 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 \near u, (forall , 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 | 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
 ( : U -> V -> W) :
  locally_compact [set: V] -> @regular_space V -> @regular_space U ->
  continuous f -> (forall , 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 , [/\ 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 : V -> W | g @` Q `<=` O].
(have oR : open R by exact: compact_open_open); pose P' := f @^-1` R.
pose L := [set : 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 { : topologicalType} { : Type}
  ( : U -> U -> U) ( : U) ( : pred I).
Hypothesis : continuous (fun : U * U => op x.1 x.2).

Lemma
cvg_bigUsed by
  • mathcomp.analysis.normedtype_theory.pseudometric_normed_Zmodule

Source code
{ : Type} ( : set_system T) ( : seq I)
    ( : I -> T -> U) ( : I -> U) :
  Filter F ->
  (forall , P i -> Ff i x @[ --> F] --> Fa i) ->
  \big[op/x0]_( <- r | P i) (Ff i x) @[ --> F] -->
    \big[op/x0]_( <- 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 => (Ff i x1, \big[op/x0]_( <- r | P j) Ff j x1)) _ _
  (nbhs (Fa i, \big[op/x0]_( <- 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
{ : topologicalType} ( : seq I)
    ( : I -> T -> U) :
  (forall , P i -> continuous (F i)) ->
  continuous (fun => \big[op/x0]_( <- 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
{ : topologicalType} ( : set T) ( : seq I)
    ( : I -> T -> U) :
  (forall , P i -> {within A, continuous (F i)}) ->
  {within A, continuous (fun => \big[op/x0]_( <- r | P i) F i x)}.
Proof.
by move=> ? ?; exact: continuous_big. Qed.

End big_continuous.

Definition { : topologicalType} : continuousType X Y * X -> Y :=
  uncurry (id : continuousType X Y -> (X -> Y)).

Section composition.

Local Import ArrowAsCompactOpen.

Lemma
eval_continuousSource 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
{ : 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 ( : 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.