Module mathcomp.analysis.topology_theory.metric_structure
From HB Require Import structures.From mathcomp Require Import boot order ssralg ssrint ssrnum matrix.
From mathcomp Require Import interval_inference rat interval zmodp vector.
From mathcomp Require Import fieldext falgebra archimedean finmap.
#[warning="-warn-library-file-internal-analysis"]
From mathcomp Require Import unstable.
From mathcomp Require Import mathcomp_extra boolp classical_sets.
From mathcomp Require Import contra reals topology_structure.
From mathcomp Require Import uniform_structure pseudometric_structure.
From mathcomp Require Import num_topology product_topology separation_axioms.
# Metric spaces
```
metricType K == metric structure with distance mdist
The HB class is Metric.
R^o with R : numFieldType is shown to be a metric space.
The mixin PseudoMetric_isMetric extends PseudoMetric.
The factor isMetric just requires a distance.
```
Unset SsrOldRewriteGoalsOrder.
Set Implicit Arguments.
Unset Strict Implicit.
Unset Printing Implicit Defensive.
Import Order.TTheory GRing.Theory Num.Def Num.Theory.
Import numFieldTopology.Exports.
Local Open Scope classical_set_scope.
Local Open Scope ring_scope.
.
mixin
Source code
Source code
Record
Source code
Source code
PseudoMetric_isMetric
Source code
(Source code
numDomainType
Source code
) M & PseudoMetric K M := {Source code
mdist : M -> M -> K ;
mdist_ge0 : forall , 0 <= mdist x y ;
mdist_positivity : forall , mdist x y = 0 -> x = y;
ballEmdist : forall , ball x d = [set | mdist x y < d]
}.
#[short
Source code
(Source code
type=
Source code
Source code
"metricType"
Source code
)Source code
.
structure
Source code
Source code
Definition
Source code
Source code
Metric
Source code
(Source code
numDomainType
Source code
) :=Source code
{ of PseudoMetric K M & PseudoMetric_isMetric K M }.
Section metric_lemmas.
Context { : realFieldType} ( : metricType R).
Let
dist
Source code
:= @mdist R T.Source code
Lemma
metric_sym
Source code
: dist x y = dist y x.Source code
Proof.
Lemma
mdistxx
Source code
: dist x x = 0.Source code
Proof.
apply/eqP; rewrite eq_le mdist_ge0 andbT; apply/ler_addgt0Pl => /= e e0.
rewrite addr0 leNgt; apply/negP => exx.
by have := @ball_center _ _ x (PosNum e0); rewrite ballEmdist/= ltNge (ltW exx).
Qed.
rewrite addr0 leNgt; apply/negP => exx.
by have := @ball_center _ _ x (PosNum e0); rewrite ballEmdist/= ltNge (ltW exx).
Qed.
Lemma
mdist_gt0
Source code
: (0 < dist x y) = (x != y).Source code
Proof.
Lemma
metric_triangle
Source code
: dist x z <= dist x y + dist y z.Source code
Proof.
Lemma
metric_hausdorff
Source code
: hausdorff_space T.Source code
Proof.
move=> p q pq; absurd_not => qp; move: pq.
pose D := dist p q / 2; have D0 : 0 < D.
by rewrite divr_gt0// mdist_gt0.
have p2Dq : ~ ball p (dist p q) q by rewrite ballEmdist/= ltxx.
move=> /(_ (ball p _) (ball q _) (nbhsx_ballx _ _ D0) (nbhsx_ballx _ _ D0)).
move/set0P/eqP; apply; rewrite -subset0 => x [pDx /ball_sym qDx].
by have := ball_triangle pDx qDx; rewrite -splitr.
Qed.
pose D := dist p q / 2; have D0 : 0 < D.
by rewrite divr_gt0// mdist_gt0.
have p2Dq : ~ ball p (dist p q) q by rewrite ballEmdist/= ltxx.
move=> /(_ (ball p _) (ball q _) (nbhsx_ballx _ _ D0) (nbhsx_ballx _ _ D0)).
move/set0P/eqP; apply; rewrite -subset0 => x [pDx /ball_sym qDx].
by have := ball_triangle pDx qDx; rewrite -splitr.
Qed.
End metric_lemmas.
.
factory
Source code
Source code
Record
Source code
Source code
isMetric
Source code
(Source code
numFieldType
Source code
) (M : Type) & Choice M := {Source code
mdist : M -> M -> K ;
mdistxx : forall , mdist x x = 0 ;
mdist_positivity : forall , mdist x y = 0 -> x = y ;
mdist_sym : forall , mdist x y = mdist y x ;
mdist_triangle : forall , mdist x z <= mdist x y + mdist y z
}.
.
builders
Source code
Source code
Context
Source code
Source code
isMetric
Source code
K M.Source code
Let
ball
Source code
( : M) : set M := [set | mdist x y < e].Source code
Let
ent
Source code
: set_system (M * M) := entourage_ ball.Source code
Let
nbhs
Source code
( : M) : set_system M := nbhs_ ent x.Source code
Let
nbhsE
Source code
: nbhs = nbhs_ entSource code
Proof.
by []. Qed.
.
instance
Source code
Source code
Definition
Source code
Source code
hasNbhs
Source code
.Build M nbhs.Source code
Let
ball_center
Source code
( : K) : 0 < e -> ball x e x.Source code
Let
ball_sym
Source code
( : K) : ball x e y -> ball y e x.Source code
Let
ball_triangle
Source code
: ball x e1 y -> ball y e2 z ->Source code
ball x (e1 + e2) z.
Proof.
Let
entourageE
Source code
: ent = entourage_ ballSource code
Proof.
by []. Qed.
.
instance
Source code
Source code
Definition
Source code
Source code
@Nbhs_isPseudoMetric
Source code
.Build K MSource code
ent nbhsE ball ball_center ball_sym ball_triangle entourageE.
Let
mdist_ge0
Source code
: 0 <= mdist x y.Source code
Proof.
rewrite -(@pmulrn_lge0 _ _ 2)// -(mdistxx x).
by rewrite (le_trans (mdist_triangle y _ _))// mdist_sym -mulr2n.
Qed.
by rewrite (le_trans (mdist_triangle y _ _))// mdist_sym -mulr2n.
Qed.
Let
ballEmdist
Source code
: ball x d = [set | mdist x y < d]Source code
Proof.
by []. Qed.
.
instance
Source code
Source code
Definition
Source code
Source code
PseudoMetric_isMetric
Source code
.Build K MSource code
mdist_ge0 mdist_positivity ballEmdist.
.
end
Source code
.Source code
Section numFieldType_metric.
Context { : numFieldType}.
Implicit Type x y : R.
Let
dist
Source code
:= `|y - x|.Source code
Let
dist_ge0
Source code
: 0 <= dist x y.Source code
Proof.
Let
dist_positivity
Source code
: dist x y = 0 -> x = y.Source code
Proof.
Let
ballEmdist
Source code
: ball x d = [set | dist x y < d].Source code
.
instance
Source code
Source code
Definition
Source code
Source code
@PseudoMetric_isMetric
Source code
.Build R R^o dist dist_ge0 dist_positivity ballEmdist.Source code
End numFieldType_metric.
Module
metricType_numDomainType
Source code
.Source code
Section metricType_numDomainType.
Context { : numDomainType} { : metricType K}.
Local Notation
ball_mdist
Source code
:= (fun => [set : V | mdist x y < d]).Source code
Lemma
ball_mdistE
Source code
: ball_mdist = ball.Source code
Proof.
Local Notation
nbhs_mdist
Source code
:= (nbhs_ball_ ball_mdist).Source code
Lemma
nbhs_nbhs_mdist
Source code
: nbhs_mdist = nbhs.Source code
Proof.
Lemma
nbhs_mdistP
Source code
( : V -> Prop) : (\near , P x) <-> nbhs_mdist x P.Source code
Proof.
Lemma
filter_from_mdist_nbhs
Source code
( : V) :Source code
filter_from (fun : K => 0 < i) (fun ( : K) ( : V) => mdist y y' < i)
= nbhs y.
Proof.
rewrite -filter_from_ballE; apply/seteqP; split => [A|A]/=.
by move=> [x x0 yxA]; exists x => //; rewrite ballEmdist.
by move=> [x x0 yxA]; exists x => //; rewrite ballEmdist in yxA.
Qed.
by move=> [x x0 yxA]; exists x => //; rewrite ballEmdist.
by move=> [x x0 yxA]; exists x => //; rewrite ballEmdist in yxA.
Qed.
Let
nbhs_simpl
Source code
:= (nbhs_simpl,@nbhs_nbhs_mdist,@filter_from_mdist_nbhs).Source code
Lemma
fcvgrPdist_lt
Source code
{ : set_system V} { : Filter F} ( : V) :Source code
F --> y <-> forall
eps
Source code
, 0 < eps -> \forall \near F, mdist y y' < eps.Source code
Proof.
Lemma
cvgrPdist_lt
Source code
{} { : set_system T} { : Filter F} ( : T -> V) ( : V) :Source code
f @ F --> y <-> forall
eps
Source code
, 0 < eps -> \forall \near F, mdist y (f t) < eps.Source code
Proof.
Lemma
cvgr_dist_lt
Source code
{} { : set_system T} { : Filter F} ( : T -> V) ( : V) :Source code
f @ F --> y -> forall
eps
Source code
, eps > 0 -> \forall \near F, mdist y (f t) < eps.Source code
Proof.
Lemma
cvgr_dist_le
Source code
{} { : set_system T} { : Filter F} ( : T -> V) ( : V) :Source code
f @ F --> y -> forall
eps
Source code
, eps > 0 -> \forall \near F, mdist y (f t) <= eps.Source code
Proof.
End metricType_numDomainType.
Section at_left_right_metricType.
Variables ( : numFieldType) ( : metricType R).
Lemma
nbhsr0P
Source code
( : set V) :Source code
(\forall \near x, P y) <->
(\forall \near 0^'+, forall , mdist x y <= e -> P y).
Proof.
rewrite (*nbhs0P*)/= near_withinE !near_simpl.
split.
move => /nbhs_mdistP[/= _/posnumP[e] /(_ _) Px].
apply/(@nbhs_mdistP R R^o).
exists e%:num => //= r /= re yr y xyr.
apply: Px => /=.
rewrite (le_lt_trans _ re)//.
rewrite (le_trans xyr)//.
by rewrite /mdist/= subr0 real_ler_norm// gtr0_real.
move => /(@nbhs_mdistP R R^o)[/= _/posnumP[e] /(_ _) Px].
apply/(@nbhs_mdistP R V).
exists (e%:num / 2) => //= r /= re; apply: (Px (e%:num / 2)) => //=.
by rewrite /mdist/= subr0 gtr0_norm// ltr_pdivrMr// ltr_pMr// ltr1n.
by rewrite ltW.
Qed.
split.
move => /nbhs_mdistP[/= _/posnumP[e] /(_ _) Px].
apply/(@nbhs_mdistP R R^o).
exists e%:num => //= r /= re yr y xyr.
apply: Px => /=.
rewrite (le_lt_trans _ re)//.
rewrite (le_trans xyr)//.
by rewrite /mdist/= subr0 real_ler_norm// gtr0_real.
move => /(@nbhs_mdistP R R^o)[/= _/posnumP[e] /(_ _) Px].
apply/(@nbhs_mdistP R V).
exists (e%:num / 2) => //= r /= re; apply: (Px (e%:num / 2)) => //=.
by rewrite /mdist/= subr0 gtr0_norm// ltr_pdivrMr// ltr_pMr// ltr1n.
by rewrite ltW.
Qed.
Let
cvgrP
Source code
{ : set_system V} { : Filter F} ( : V) : [<->Source code
F --> y;
forall
eps
Source code
, 0 < eps -> \forall \near F, mdist y t <= eps;Source code
\forall
eps
Source code
\near 0^'+, \forall \near F, mdist y t <= eps;Source code
\forall
eps
Source code
\near 0^'+, \forall \near F, mdist y t < eps].Source code
Proof.
tfae; first by move=> *; apply: cvgr_dist_le.
- by move=> Fy; near do apply: Fy; apply: nbhs_right_gt.
- move=> Fy; near=> e; near (0:R)^'+ => d; near=> x.
rewrite (@le_lt_trans _ _ d)//; first by near: x; near: d.
by near: d; apply: nbhs_right_lt; near: e; apply: nbhs_right_gt.
- move=> Fy; apply/cvgrPdist_lt => e e_gt0; near (0:R)^'+ => d.
near=> x; rewrite (@lt_le_trans _ _ d)//; first by near: x; near: d.
by near: d; apply: nbhs_right_le.
Unshelve. all: by end_near. Qed.
- by move=> Fy; near do apply: Fy; apply: nbhs_right_gt.
- move=> Fy; near=> e; near (0:R)^'+ => d; near=> x.
rewrite (@le_lt_trans _ _ d)//; first by near: x; near: d.
by near: d; apply: nbhs_right_lt; near: e; apply: nbhs_right_gt.
- move=> Fy; apply/cvgrPdist_lt => e e_gt0; near (0:R)^'+ => d.
near=> x; rewrite (@lt_le_trans _ _ d)//; first by near: x; near: d.
by near: d; apply: nbhs_right_le.
Unshelve. all: by end_near. Qed.
Lemma
cvgrPdist_le
Source code
{} { : set_system T} { : Filter F} ( : T -> V) ( : V) :Source code
f @ F --> y <-> forall
eps
Source code
, 0 < eps -> \forall \near F, mdist y (f t) <= eps.Source code
Proof.
End at_left_right_metricType.
End metricType_numDomainType.
Section cvg_nbhsP.
Variables ( : realType) ( : metricType R).
Import metricType_numDomainType.
Lemma
cvg_nbhsP
Source code
( : V -> V) ( : V) : f x @[ --> p] --> l <->Source code
(forall : nat -> V, (u n @[ --> \oo] --> p) -> f (u n) @[ --> \oo] --> l).
Proof.
split=> [/cvgrPdist_le /= fpl u /cvgrPdist_lt /= uyp|pfl].
apply/cvgrPdist_le => e /fpl.
rewrite -filter_from_mdist_nbhs => -[d d0 pdf].
by apply: filterS (uyp d d0) => t /pdf.
apply: contrapT => fpl; move: pfl; apply/existsNP.
suff: exists2 : nat -> V,
x n @[ --> \oo] --> p & ~ f (x n) @[ --> \oo] --> l.
by move=> [x_] hp; exists x_; exact/not_implyP.
have [e He] : exists : {posnum R}, forall : {posnum R},
exists , mdist xn p < d%:num /\ mdist (f xn) l >= e%:num.
apply: contrapT; apply: contra_not fpl => /forallNP h.
apply/cvgrPdist_le => e e0; have /existsNP[d] := h (PosNum e0).
move/forallNP => {}h; near=> t.
have /not_andP[abs|/negP] := h t.
- absurd: abs.
near: t.
rewrite !near_simpl /prop_near1 -nbhs_nbhs_mdist.
by exists d%:num => //= z/=; rewrite metric_sym.
- by rewrite -ltNge metric_sym => /ltW.
exists (fun => sval (cid (He n.+1%:R^-1%:pos))).
apply/cvgrPdist_lt => r r0; near=> t.
rewrite /sval/=; case: cid => x [xpt _].
rewrite metric_sym (lt_le_trans xpt)//.
rewrite -[leRHS]invrK lef_pV2 ?posrE ?invr_gt0//.
near: t; exists (truncn r^-1) => // s /= rs.
by apply/ltW; rewrite -truncn_le_nat.
move=> /cvgrPdist_lt/(_ e%:num (ltac:(by [])))[] n _ /(_ _ (leqnn _)).
rewrite /sval/=; case: cid => // x [px xpn].
by rewrite ltNge metric_sym => /negP.
Unshelve. all: end_near. Qed.
apply/cvgrPdist_le => e /fpl.
rewrite -filter_from_mdist_nbhs => -[d d0 pdf].
by apply: filterS (uyp d d0) => t /pdf.
apply: contrapT => fpl; move: pfl; apply/existsNP.
suff: exists2 : nat -> V,
x n @[ --> \oo] --> p & ~ f (x n) @[ --> \oo] --> l.
by move=> [x_] hp; exists x_; exact/not_implyP.
have [e He] : exists : {posnum R}, forall : {posnum R},
exists , mdist xn p < d%:num /\ mdist (f xn) l >= e%:num.
apply: contrapT; apply: contra_not fpl => /forallNP h.
apply/cvgrPdist_le => e e0; have /existsNP[d] := h (PosNum e0).
move/forallNP => {}h; near=> t.
have /not_andP[abs|/negP] := h t.
- absurd: abs.
near: t.
rewrite !near_simpl /prop_near1 -nbhs_nbhs_mdist.
by exists d%:num => //= z/=; rewrite metric_sym.
- by rewrite -ltNge metric_sym => /ltW.
exists (fun => sval (cid (He n.+1%:R^-1%:pos))).
apply/cvgrPdist_lt => r r0; near=> t.
rewrite /sval/=; case: cid => x [xpt _].
rewrite metric_sym (lt_le_trans xpt)//.
rewrite -[leRHS]invrK lef_pV2 ?posrE ?invr_gt0//.
near: t; exists (truncn r^-1) => // s /= rs.
by apply/ltW; rewrite -truncn_le_nat.
move=> /cvgrPdist_lt/(_ e%:num (ltac:(by [])))[] n _ /(_ _ (leqnn _)).
rewrite /sval/=; case: cid => // x [px xpn].
by rewrite ltNge metric_sym => /negP.
Unshelve. all: end_near. Qed.
End cvg_nbhsP.
Section cvg_at_right_left_dnbhs.
Variables ( : realFieldType) ( : metricType R).
Import metricType_numDomainType.
Lemma
cvg_at_right_left_dnbhs
Source code
( : R -> T) ( : R) ( : T) :Source code
f x @[ --> p^'+] --> l -> f x @[ --> p^'-] --> l ->
f x @[ --> p^'] --> l.
Proof.
move=> /cvgrPdist_le fppl /cvgrPdist_le fpnl; apply/cvgrPdist_le => e e0.
have {fppl}[a /= a0 fppl] := fppl (at_right_proper_filter p) _ e0.
have {fpnl}[b /= b0 fpnl] := fpnl (at_left_proper_filter p) _ e0.
near=> t.
have : t != p by near: t; exact: nbhs_dnbhs_neq.
rewrite neq_lt => /orP[tp|pt].
- apply: fpnl => //=; near: t.
exists (b / 2) => //=; first by rewrite divr_gt0.
move=> z/= + _ => /lt_le_trans; apply.
by rewrite ler_pdivrMr// ler_pMr// ler1n.
- apply: fppl =>//=; near: t.
exists (a / 2) => //=; first by rewrite divr_gt0.
move=> z/= + _ => /lt_le_trans; apply.
by rewrite ler_pdivrMr// ler_pMr// ler1n.
Unshelve. all: by end_near. Qed.
have {fppl}[a /= a0 fppl] := fppl (at_right_proper_filter p) _ e0.
have {fpnl}[b /= b0 fpnl] := fpnl (at_left_proper_filter p) _ e0.
near=> t.
have : t != p by near: t; exact: nbhs_dnbhs_neq.
rewrite neq_lt => /orP[tp|pt].
- apply: fpnl => //=; near: t.
exists (b / 2) => //=; first by rewrite divr_gt0.
move=> z/= + _ => /lt_le_trans; apply.
by rewrite ler_pdivrMr// ler_pMr// ler1n.
- apply: fppl =>//=; near: t.
exists (a / 2) => //=; first by rewrite divr_gt0.
move=> z/= + _ => /lt_le_trans; apply.
by rewrite ler_pdivrMr// ler_pMr// ler1n.
Unshelve. all: by end_near. Qed.
End cvg_at_right_left_dnbhs.
Section at_left_rightR.
Variable ( : numFieldType).
`cvgrPdistC_lt` is also defined in `pseudometric_normed_Zmodule.v` where it only needs `numDomainType`
Let cvgrPdistC_lt
Source code
{} { : set_system T} { : Filter F} ( : T -> R^o) ( : R) :Source code
f @ F --> y <-> forall
eps
Source code
, 0 < eps -> \forall \near F, mdist (f t) y < eps.Source code
Proof.
rewrite metricType_numDomainType.cvgrPdist_lt.
by under eq_forall do under eq_near do rewrite /mdist/= (@distrC _ R^o).
Qed.
by under eq_forall do under eq_near do rewrite /mdist/= (@distrC _ R^o).
Qed.
`cvgr_distC_lt` is also defined in `pseudometric_normed_Zmodule.v` where it only needs `numDomainType`
Let cvgr_distC_lt
Source code
{} { : set_system T} { : Filter F} ( : T -> R^o) ( : R) :Source code
f @ F --> y -> forall
eps
Source code
, eps > 0 -> \forall \near F, mdist (f t) y < eps.Source code
Proof.
Lemma
real_cvgr_lt
Source code
{} { : set_system T} { : Filter F} ( : T -> R) ( : R) :Source code
y \is Num.real -> f @ F --> y ->
forall , z > y -> \forall \near F, f t \is Num.real -> f t < z.
Proof.
move=> yr Fy z zy; near=> x => fxr.
rewrite -(ltrD2r (- y)) real_ltr_normlW// ?rpredB// distrC.
by near: x; apply: cvgr_distC_lt => //; rewrite subr_gt0.
Unshelve. all: by end_near. Qed.
rewrite -(ltrD2r (- y)) real_ltr_normlW// ?rpredB// distrC.
by near: x; apply: cvgr_distC_lt => //; rewrite subr_gt0.
Unshelve. all: by end_near. Qed.
Lemma
real_cvgr_le
Source code
{} { : set_system T} { : Filter F} ( : T -> R) ( : R) :Source code
y \is Num.real -> f @ F --> y ->
forall , z > y -> \forall \near F, f t \is Num.real -> f t <= z.
Proof.
Lemma
real_cvgr_gt
Source code
{} { : set_system T} { : Filter F} ( : T -> R) ( : R) :Source code
y \is Num.real -> f @ F --> y ->
forall , y > z -> \forall \near F, f t \is Num.real -> f t > z.
Proof.
move=> yr Fy z zy; near=> x => fxr.
rewrite -ltrN2 -(ltrD2l y) real_ltr_normlW// ?rpredB// distrC.
by near: x; apply: (@metricType_numDomainType.cvgr_dist_lt _ R^o) => //; rewrite subr_gt0.
Unshelve. all: by end_near. Qed.
rewrite -ltrN2 -(ltrD2l y) real_ltr_normlW// ?rpredB// distrC.
by near: x; apply: (@metricType_numDomainType.cvgr_dist_lt _ R^o) => //; rewrite subr_gt0.
Unshelve. all: by end_near. Qed.
Lemma
real_cvgr_ge
Source code
{} { : set_system T} { : Filter F} ( : T -> R) ( : R) :Source code
y \is Num.real -> f @ F --> y ->
forall , z < y -> \forall \near F, f t \is Num.real -> f t >= z.
Proof.
End at_left_rightR.
Arguments real_cvgr_le {R T F FF f}.
Arguments real_cvgr_lt {R T F FF f}.
Arguments real_cvgr_ge {R T F FF f}.
Arguments real_cvgr_gt {R T F FF f}.
Section squeeze_cvgr.
Context { : Type} { : set_system T} { : Filter F} { : realFieldType}.
Implicit Types f g h : T -> R.
Lemma
cvgr_lt
Source code
( : R) :Source code
f @ F --> y -> forall , z > y -> \forall \near F, f t < z.
Proof.
move=> Fy z zy; near=> x; rewrite -(ltrD2r (- y)) ltr_normlW//.
by near: x; apply: (@metricType_numDomainType.cvgr_dist_lt _ R^o) => //; rewrite subr_gt0.
Unshelve. all: by end_near. Qed.
by near: x; apply: (@metricType_numDomainType.cvgr_dist_lt _ R^o) => //; rewrite subr_gt0.
Unshelve. all: by end_near. Qed.
Lemma
cvgr_gt
Source code
( : R) :Source code
f @ F --> y -> forall , y > z -> \forall \near F, f t > z.
Proof.
move=> Fy z zy; near=> x; rewrite -ltrN2 -(ltrD2l y) ltr_normlW// distrC.
by near: x; apply: (@metricType_numDomainType.cvgr_dist_lt _ R^o) => //; rewrite subr_gt0.
Unshelve. all: by end_near. Qed.
by near: x; apply: (@metricType_numDomainType.cvgr_dist_lt _ R^o) => //; rewrite subr_gt0.
Unshelve. all: by end_near. Qed.
Lemma
cvgr_le
Source code
( : R) :Source code
f @ F --> y -> forall , z > y -> \forall \near F, f t <= z.
Lemma
cvgr_ge
Source code
( : R) :Source code
f @ F --> y -> forall , z < y -> \forall \near F, f t >= z.
Lemma
squeeze_cvgr
Source code
: (\near , f F <= g F <= h F) ->Source code
forall ( : R), f @ F --> l -> h @ F --> l -> g @ F --> l.
Proof.
move=> fgh l lfa lga.
apply/(@metricType_numDomainType.cvgrPdist_lt R R^o) => e e_gt0.
near=> x; have /(_ _)/andP[//|fg gh] := near fgh x.
rewrite ltr_distl (lt_le_trans _ fg) ?(le_lt_trans gh)//=.
by near: x; apply: (cvgr_gt lfa); rewrite // gtrDl oppr_lt0.
by near: x; apply: (cvgr_lt lga); rewrite // ltrDl.
Unshelve. all: end_near. Qed.
apply/(@metricType_numDomainType.cvgrPdist_lt R R^o) => e e_gt0.
near=> x; have /(_ _)/andP[//|fg gh] := near fgh x.
rewrite ltr_distl (lt_le_trans _ fg) ?(le_lt_trans gh)//=.
by near: x; apply: (cvgr_gt lfa); rewrite // gtrDl oppr_lt0.
by near: x; apply: (cvgr_lt lga); rewrite // ltrDl.
Unshelve. all: end_near. Qed.
End squeeze_cvgr.
Arguments cvgr_lt {T F FF R f}.
Arguments cvgr_gt {T F FF R f}.
Arguments cvgr_le {T F FF R f}.
Arguments cvgr_ge {T F FF R f}.