Require Export Reals.
Require Export TopologicalSpaces.
Require Export NeighborhoodBases.
From ZornsLemma Require Export EnsemblesSpec.
Open Scope R_scope.
Section metric.
Variable X:Type.
Variable d:X->X->R.
Record metric : Prop := {
metric_nonneg: forall x y:X, d x y >= 0;
metric_sym: forall x y:X, d x y = d y x;
triangle_inequality: forall x y z:X, d x z <= d x y + d y z;
metric_zero: forall x:X, d x x = 0;
metric_strict: forall x y:X, d x y = 0 -> x = y
}.
End metric.
Arguments metric {X}.
Section metric_topology.
Variable X:Type.
Variable d:X->X->R.
Hypothesis d_is_metric: metric d.
Definition open_ball (x0:X) (r:R) : Ensemble X :=
[ x:X | d x0 x < r ].
Inductive metric_topology_neighborhood_basis (x:X) : Family X :=
| intro_open_ball: forall r:R, r > 0 ->
In (metric_topology_neighborhood_basis x) (open_ball x r).
Definition MetricTopology : TopologicalSpace.
refine (Build_TopologicalSpace_from_open_neighborhood_bases
X metric_topology_neighborhood_basis _ _ _ _).
intros.
destruct H as [r1].
destruct H0 as [r2].
exists (open_ball x (Rmin r1 r2)); split.
constructor.
apply Rmin_Rgt_r; split; trivial.
red; intros.
destruct H1.
constructor; constructor.
apply Rlt_le_trans with (Rmin r1 r2); trivial.
apply Rmin_l.
apply Rlt_le_trans with (Rmin r1 r2); trivial.
apply Rmin_r.
intros.
destruct H.
constructor.
rewrite metric_zero; trivial.
intro.
exists (open_ball x 1).
constructor.
auto with *.
intros.
destruct H.
destruct H0.
exists (open_ball y (r - d x y)); split.
constructor.
apply Rgt_minus; trivial.
red; intros z ?.
destruct H1.
constructor.
apply Rle_lt_trans with (d x y + d y z).
apply triangle_inequality; trivial.
assert (d x y + d y z < d x y + (r - d x y)).
auto with *.
ring_simplify in H2.
assumption.
Defined.
End metric_topology.
Arguments metric_topology_neighborhood_basis {X}.
Arguments MetricTopology {X}.
Definition metrizes (X:TopologicalSpace)
(d:point_set X -> point_set X -> R) : Prop :=
forall x:point_set X, open_neighborhood_basis
(metric_topology_neighborhood_basis d x) x.
Inductive metrizable (X:TopologicalSpace) : Prop :=
| intro_metrizable: forall d:point_set X -> point_set X -> R,
metric d -> metrizes X d ->
metrizable X.

(* Specifications: *)
Lemma MetricTopology_metrizable: forall (X:Type) (d:X->X->R)
(d_metric: metric d),
metrizes (MetricTopology d d_metric) d.