Theory Float_Topology
section ‹Topology for Floating Point Numbers›
theory Float_Topology
imports
"HOL-Analysis.Multivariate_Analysis"
"HOL-Library.Float"
begin
text ‹
This topology is totally disconnected and not complete, in which sense is it useful?
Perhaps for convergence of intervals?›
unbundle float.lifting
instantiation float :: dist
begin
lift_definition dist_float :: "float ⇒ float ⇒ real" is dist .
lemma dist_float_eq_0_iff: "(dist x y = 0) = (x = y)" for x y::float
by transfer simp
lemma dist_float_triangle2: "dist x y ≤ dist x z + dist y z" for x y z::float
by transfer (rule dist_triangle2)
instance ..
end
instantiation float :: uniformity
begin
definition uniformity_float :: "(float × float) filter"
where "uniformity_float = (INF e∈{0<..}. principal {(x, y). dist x y < e})"
instance ..
end
lemma float_dense_in_real:
fixes x :: real
assumes "x < y"
shows "∃r∈float. x < r ∧ r < y"
proof -
from ‹x < y› have "0 < y - x" by simp
with reals_Archimedean obtain q' :: nat where q': "inverse (real q') < y - x" and "0 < q'"
by blast
define q::nat where "q ≡ 2 ^ nat ¦bitlen q'¦"
from bitlen_bounds[of q'] ‹0 < q'› have "q' < q"
by (auto simp: q_def)
then have "inverse q < inverse q'"
using ‹0 < q'›
by (auto simp: divide_simps)
with ‹q' < q› q' have q: "inverse (real q) < y - x" and "0 < q"
by (auto simp: split: if_splits)
define p where "p = ⌈y * real q⌉ - 1"
define r where "r = of_int p / real q"
from q have "x < y - inverse (real q)"
by simp
also from ‹0 < q› have "y - inverse (real q) ≤ r"
by (simp add: r_def p_def le_divide_eq left_diff_distrib)
finally have "x < r" .
moreover from ‹0 < q› have "r < y"
by (simp add: r_def p_def divide_less_eq diff_less_eq less_ceiling_iff [symmetric])
moreover have "r ∈ float"
by (simp add: r_def q_def)
ultimately show ?thesis by blast
qed
lemma real_of_float_dense:
fixes x y :: real
assumes "x < y"
shows "∃q :: float. x < real_of_float q ∧ real_of_float q < y"
using float_dense_in_real [OF ‹x < y›]
by (auto elim: real_of_float_cases)
instantiation float :: linorder_topology
begin
definition open_float::"float set ⇒ bool" where
"open_float S = (∀x∈S. ∃e>0. ∀y. dist y x < e ⟶ y ∈ S)"
instance
proof (standard, intro ext iffI)
fix U::"float set"
assume "generate_topology (range lessThan ∪ range greaterThan) U"
then show "open U"
unfolding open_float_def uniformity_float_def
proof (induction U)
case UNIV
then show ?case by (auto intro!: zero_less_one)
next
case (Int a b)
show ?case
proof safe
fix x assume "x ∈ a" "x ∈ b"
with Int(3,4) obtain e1 e2
where "dist (y) (x) < e1 ⟹ y ∈ a"
and "dist (y) (x) < e2 ⟹ y ∈ b"
and "0 < e1" "0 < e2"
for y
by (auto dest!: bspec)
then show "∃e>0. ∀y. dist y x < e ⟶ y ∈ a ∩ b"
by (auto intro!: exI[where x="min e1 e2"])
qed
next
case (UN K)
show ?case
proof safe
fix x X assume x: "x ∈ X" and X: "X ∈ K"
from UN[OF X] x obtain e where
"dist (y) (x) < e ⟹ y ∈ X" "e > 0" for y
by auto
then show "∃e>0. ∀y. dist (real_of_float y) (real_of_float x) < e ⟶ y ∈ ⋃K"
using x X
by (auto intro!: exI[where x=e])
qed
next
case (Basis s)
then show ?case
proof safe
fix x u::float
assume "x < u"
then show "∃e>0. ∀y. dist (real_of_float y) (real_of_float x) < e ⟶ y ∈ {..<u}"
by (force simp add: eventually_principal dist_float_def
dist_real_def abs_real_def
intro!: exI[where x="(u - x)/2"])
next
fix x l::float
assume "l < x"
then show "∃e>0. ∀y. dist (real_of_float y) (real_of_float x) < e ⟶ y ∈ {l<..}"
by (force simp add: eventually_principal dist_float_def
dist_real_def abs_real_def
intro!: exI[where x="(x - l)/2"])
qed
qed
next
fix U::"float set"
assume "open U"
then obtain e where e:
"x ∈ U ⟹ e x > 0"
"x ∈ U ⟹ dist ( y) ( x) < e x ⟹ y ∈ U" for x y
unfolding open_float_def uniformity_float_def
by metis
{
fix x
assume x: "x ∈ U"
obtain e' where e': "e' > 0" "real_of_float e' < e x"
using real_of_float_dense[of 0 "e x"]
using e(1)[OF x]
by auto
then have "dist (y) ( x) < e' ⟹ y ∈ U" for y
by (intro e[OF x]) auto
then have "∃e'>0. ∀y. dist (y) ( x) < real_of_float e' ⟶ y ∈ U"
using e'
by auto
} then
obtain e' where e':
"x ∈ U ⟹ 0 < e' x"
"x ∈ U ⟹ dist y x < real_of_float (e' x) ⟹ y ∈ U" for x y
by metis
then have "U = (⋃x∈U. greaterThan (x - e' x) ∩ lessThan (x + e' x))"
by (auto simp: dist_float_def dist_commute dist_real_def)
also have "generate_topology (range lessThan ∪ range greaterThan) …"
by (intro generate_topology_Union generate_topology.Int generate_topology.Basis) auto
finally show "generate_topology (range lessThan ∪ range greaterThan) U" .
qed
end
instance float :: metric_space
proof standard
fix U::"float set"
show "open U = (∀x∈U. ∀⇩F (x', y) in uniformity. x' = x ⟶ y ∈ U)"
unfolding open_float_def open_dist uniformity_float_def uniformity_real_def
proof safe
fix x
assume "∀x∈U. ∃e>0. ∀y. dist (real_of_float y) (real_of_float x) < e ⟶ y ∈ U" "x ∈ U"
then obtain e where "e > 0" "dist (y) (x) < e ⟹ y ∈ U" for y
by auto
then show "∀⇩F (x', y) in INF e∈{0<..}. principal {(x, y). dist x y < e}. x' = x ⟶ y ∈ U"
by (intro eventually_INF1[where i=e])
(auto simp: eventually_principal dist_commute dist_float_def)
next
fix u
assume "∀x∈U. ∀⇩F (x', y) in INF e∈{0<..}. principal {(x, y). dist x y < e}. x' = x ⟶ y ∈ U"
"u ∈ U"
from this obtain E where E: "E ⊆ {0<..}" "finite E"
"∀(x', y)∈⋂x∈E. {(y', y). dist y' y < x}. x' = u ⟶ y ∈ U"
by (subst (asm) eventually_INF) (auto simp: INF_principal_finite eventually_principal)
then show "∃e>0. ∀y. dist (real_of_float y) (real_of_float u) < e ⟶ y ∈ U"
by (intro exI[where x="if E = {} then 1 else Min E"])
(auto simp: dist_commute dist_float_def)
qed
qed (use dist_float_eq_0_iff dist_float_triangle2 in
‹auto simp add: uniformity_float_def dist_float_def›)
instance float::topological_ab_group_add
proof
fix a b::float
show "((λx. fst x + snd x) ⤏ a + b) (nhds a ×⇩F nhds b)"
proof (rule tendstoI)
fix e::real
assume "e > 0"
have 1: "(fst ⤏ a) (nhds a ×⇩F nhds b)"
and 2: "(snd ⤏ b) (nhds a ×⇩F nhds b)"
by (auto intro!: tendsto_eq_intros filterlim_ident simp: nhds_prod[symmetric])
have "∀⇩F x in nhds a ×⇩F nhds b. dist (fst x) (a) < e/2"
by (rule tendstoD[OF 1]) (use ‹e > 0› in auto)
moreover have "∀⇩F x in nhds a ×⇩F nhds b. dist (snd x) (b) < e/2"
by (rule tendstoD[OF 2]) (use ‹e > 0› in auto)
ultimately show "∀⇩F x in nhds a ×⇩F nhds b. dist (fst x + snd x) (a + b) < e"
proof eventually_elim
case (elim x)
then show ?case
by (auto simp: dist_float_def) norm
qed
qed
show "(uminus ⤏ - a) (nhds a)"
using filterlim_ident[of "nhds a"]
by (auto intro!: tendstoI dest!: tendstoD simp: dist_float_def dist_minus)
qed
lifting_update float.lifting
lifting_forget float.lifting
end