@@ -6,79 +6,72 @@ From mathcomp Require Import filter reals normedtype convex.
66Import numFieldNormedType.Exports.
77Local Open Scope classical_set_scope.
88
9-
10-
11-
129(**md************************************************************************* *)
10+ (* # The Hahn-Banach theorem *)
1311(* *)
14- (* *)
15- (* This files proves the Hahn-Banach theorem thanks to Zorn's lemma. Theorem *)
16- (* `Hahnbanach` states that, considering `V` a Lmodtype on a realtype, a *)
17- (* linear function on a subLmotdype of V, that is bounded by a convex *)
12+ (* This files proves the Hahn-Banach theorem thanks to Zorn's lemma. Theorem *)
13+ (* `Hahnbanach` states that, considering `V` an lmodtype on a realtype, a *)
14+ (* linear function on a subLmodype of V, that is bounded by a convex *)
1815(* function, can be extended to a linear map on V boundeby the same convex *)
19- (* function. Theorem `HBgeom ` specifies this to the extention of a linear *)
20- (* continuous function on a subspace to the whole NormedModule. *)
16+ (* function. Theorem `HB_geom_normed ` specifies this to the extention of a *)
17+ (* linear continuous function on a subspace to the whole NormedModule. *)
2118(* *)
19+ (* ``` *)
2220(* Module Lingraph == definitions on linear relations, thought of as *)
2321(* graph of functions *)
2422(* Module HBPreparation == defintion of the type Zorntype of linear *)
2523(* functional graphs, bounded by a convex function *)
2624(* and extending to the whole space a given linear *)
2725(* graph. *)
26+ (* ``` *)
27+ (* *)
2828(***************************************************************************** *)
2929
30-
31-
32-
3330Set Implicit Arguments .
3431Unset Strict Implicit .
3532Unset Printing Implicit Defensive.
3633Import Order.TTheory GRing.Theory Num.Def Num.Theory.
3734
38-
3935Local Open Scope ring_scope.
4036Local Open Scope convex_scope.
4137Local Open Scope real_scope.
4238Import GRing.Theory.
4339Import Num.Theory.
4440
45-
4641Section pos_quotient.
4742
4843(* auxiliary lemmas that could be moved elsewhere *)
49- (* TBD once merged in mathcomp *)
5044
45+ (* NB: to appear in MathComp 2.6.0 *)
5146Lemma divDl_ge0 (R: numDomainType) (s t : R) (s0 : 0 <= s) (t0 : 0 <= t) : 0 <= s / (s + t).
5247Proof .
5348by apply: divr_ge0 => //; apply: addr_ge0.
5449Qed .
5550
51+ (* NB: to appear in MathComp 2.6.0 *)
5652Lemma divDl_le1 (R: numFieldType) (s t : R) (s0 : 0 <= s) (t0 : 0 <= t) : s / (s + t) <= 1.
5753Proof .
5854move: s0; rewrite le0r => /predU1P [->|s0]; first by rewrite mul0r.
5955by rewrite ler_pdivrMr ?mul1r ?lerDl // ltr_wpDr.
6056Qed .
6157
62- Lemma divD_onem (R: realType) (s t : R) (s0 : 0 < s) (t0 : 0 < t): (s / (s + t)).~ = t / (s + t).
58+ Lemma divD_onem (R: realType) (s t : R) (s0 : 0 < s) (t0 : 0 < t) :
59+ (s / (s + t)).~ = t / (s + t).
6360Proof .
64- rewrite /(_).~.
65- suff -> : 1 = (s + t)/(s + t) by rewrite -mulrBl -addrAC subrr add0r.
66- rewrite divff // /eqP addr_eq0; apply/negbT/eqP => H.
67- by move: s0; rewrite H oppr_gt0 ltNge; move/negP; apply; rewrite ltW.
61+ rewrite /onem.
62+ by rewrite -(@divff _ (s + t)) ?gt_eqF ?addr_gt0// -mulrBl (addrC s) addrK.
6863Qed .
6964
7065End pos_quotient.
7166
72-
7367Module Lingraph.
7468Section Lingraphsec.
75-
7669Variables (R : numDomainType) (V : lmodType R).
7770
7871Definition graph := V -> R -> Prop.
7972
8073Definition linear_graph (f : graph) :=
81- forall v1 v2 l r1 r2, f v1 r1 -> f v2 r2 -> f (v1 + l *: v2) (r1 + l * r2).
74+ forall v1 v2 l r1 r2, f v1 r1 -> f v2 r2 -> f (v1 + l *: v2) (r1 + l * r2).
8275
8376Variable f : graph.
8477Hypothesis lrf : linear_graph f.
@@ -96,21 +89,19 @@ have -> : f (l *: x) (l * r) = f (0 + l *: x) (0 + l * r) by rewrite !add0r.
9689by apply: lrf=> //; exact: lingraph_00 fxr.
9790Qed .
9891
99- Lemma lingraph_add x1 x2 r1 r2 : f x1 r1 -> f x2 r2 -> f (x1 - x2)(r1 - r2).
92+ Lemma lingraph_add x1 x2 r1 r2 : f x1 r1 -> f x2 r2 -> f (x1 - x2) (r1 - r2).
10093Proof .
10194have -> : x1 - x2 = x1 + (-1) *: x2 by rewrite scaleNr scale1r.
10295have -> : r1 - r2 = r1 + (-1) * r2 by rewrite mulNr mul1r.
103- by exact: lrf.
96+ exact: lrf.
10497Qed .
10598
106-
107- Definition add_line f w a := fun v r => exists v' : V, exists r' : R, exists lambda : R,
108- [/\ f v' r', v = v' + lambda *: w & r = r' + lambda * a].
99+ Definition add_line f w a := fun v r => exists (v' : V) (r' : R) (lambda : R),
100+ [/\ f v' r', v = v' + lambda *: w & r = r' + lambda * a].
109101
110102End Lingraphsec.
111103End Lingraph.
112104
113-
114105Module HBPreparation.
115106Section HBPreparation.
116107Import Lingraph.
@@ -133,66 +124,69 @@ Definition linear_graph f :=
133124 forall v1 v2 l r1 r2, f v1 r1 -> f v2 r2 -> f (v1 + l *: v2) (r1 + l * r2).
134125
135126Definition le_extend_graph f :=
136- [/\ functional_graph f, linear_graph f, le_graph p f & extend_graph f].
127+ [/\ functional_graph f, linear_graph f, le_graph p f & extend_graph f].
137128
138129Record zorn_type : Type := ZornType
139- {carrier : graph V; specP : le_extend_graph carrier}.
130+ {carrier : graph V; specP : le_extend_graph carrier}.
140131
141- Let spec_phi : le_extend_graph (fun v r => exists2 y : F', v = val y & r = phi y).
132+ Let spec_phi : le_extend_graph (fun v r => exists2 y : F', v = val y & r = phi y).
142133Proof .
143134split.
144135- by move=> v r1 r2 [y1 -> ->] [y2 + ->] => /val_inj ->.
145136- move => v1 v2 l r1 r2 [y1 -> ->] [y2 -> ->].
146- by exists (y1 + l *: y2); rewrite !linearD !linearZ // .
147- - by move => r v [y -> ->].
148- - by move => v; exists v.
137+ by exists (y1 + l *: y2); rewrite !linearD !linearZ.
138+ - by move=> r v [y -> ->].
139+ - by move=> v; exists v.
149140Qed .
150141
151142Definition zphi := ZornType spec_phi.
152143
153144Lemma zorn_type_eq z1 z2 : carrier z1 = carrier z2 -> z1 = z2.
154145Proof .
155- case: z1 => m1 pm1; case: z2 => m2 pm2 /= e; move: pm1 pm2; rewrite e => pm1 pm2.
156- by congr ZornType; apply : Prop_irrelevance.
146+ case: z1 => m1 pm1; case: z2 => m2 pm2 /= e; rewrite e in pm1 pm2 * .
147+ by congr ZornType; exact : Prop_irrelevance.
157148Qed .
158149
159150Definition zornS (z1 z2 : zorn_type):=
160- forall x y, (carrier z1 x y) -> (carrier z2 x y ).
151+ forall x y, (carrier z1 x y) -> (carrier z2 x y ).
161152
162- (* Zorn applied to the relation of extending the graph of the first function *)
153+ (* Zorn applied to the relation of extending the graph of the first function: *)
163154Lemma zornS_ex : exists g : zorn_type, forall z, zornS g z -> z = g.
164155Proof .
165- pose Rbool := (fun x y => `[< zornS x y >]) .
166- have RboolP : forall z t, Rbool z t <-> zornS z t by split; move => /asboolP //= .
167- suff [t st]: exists t : zorn_type, forall s : zorn_type, Rbool t s -> s = t.
168- by exists t; move => z /RboolP tz; apply : st.
169- apply: (@Zorn zorn_type Rbool); first by move => t; apply /RboolP.
170- - by move => r s t /RboolP a /RboolP b; apply/RboolP => x y /a /b.
171- - move => r s /RboolP a /RboolP b; apply: zorn_type_eq.
172- by apply: funext => z; apply: funext => h;apply: propext; split => [/a | /b].
156+ pose Rbool x y := `[< zornS x y >].
157+ have RboolP z t : Rbool z t <-> zornS z t by split => /asboolP.
158+ suff [t st] : exists t : zorn_type, forall s : zorn_type, Rbool t s -> s = t.
159+ by exists t; move => z /RboolP tz; exact : st.
160+ apply: (@Zorn zorn_type Rbool); first by move=> t; exact /RboolP.
161+ - by move=> r s t /RboolP a /RboolP b; apply/RboolP => x y /a /b.
162+ - move=> r s /RboolP a /RboolP b; apply: zorn_type_eq.
163+ by apply: funext => z; apply: funext => h; apply: propext; split => [/a | /b].
173164- move => A Amax.
174- case: (lem (exists a, A a)) => [[w Aw] | eA]; last by exists zphi => a Aa; elim: eA; exists a.
175- (* g is the union of the graphs indexed by elements in a *)
176- pose g v r := exists a, A a /\ (carrier a v r).
165+ have [[w Aw] | eA] := lem (exists a, A a); last first.
166+ by exists zphi => a Aa; elim: eA; exists a.
167+ (* g is the union of the graphs indexed by elements in a *)
168+ pose g v r := exists2 a, A a & (carrier a v r).
177169 have g_fun : functional_graph g.
178- move=> v r1 r2 [a [ Aa avr1]] [b [ Ab bvr2] ].
170+ move=> v r1 r2 [a Aa avr1] [b Ab bvr2].
179171 have [] : Rbool a b \/ Rbool b a by exact: Amax.
180172 rewrite /Rbool /RboolP /zornS; case: b Ab bvr2 {Aa}.
181173 move => s2 [fs2 _ _ _] /= _ s2vr2 /asboolP ecas2.
182- by move/ecas2: avr1 => /fs2 /(_ s2vr2).
183- rewrite /Rbool /RboolP /zornS; case: a Aa avr1 {Ab} => s1 [fs1 _ _ _] /= _ s1vr1 /asboolP ecbs1.
184- by move/ecbs1: bvr2; apply: fs1.
174+ by move/ecas2: avr1 => /fs2 /(_ s2vr2).
175+ rewrite /Rbool /RboolP /zornS.
176+ case: a Aa avr1 {Ab} => s1 [fs1 _ _ _] /= _ s1vr1 /asboolP ecbs1.
177+ by move/ecbs1: bvr2; apply: fs1.
185178have g_lin : linear_graph g.
186- move=> v1 v2 l r1 r2 [a1 [Aa1 c1]] [a2 [Aa2 c2]].
187- have [/RboolP sc12 | /RboolP sc21] := Amax _ _ Aa1 Aa2.
188- - have {c1 sc12 Aa1 a1} c1 : carrier a2 v1 r1 by apply: sc12.
189- exists a2; split=> //; case: a2 {Aa2} c2 c1 => c /= [_ hl _ _] *; exact: hl.
190- - have {c2 sc21 Aa2 a2} c2 : carrier a1 v2 r2 by apply: sc21.
191- exists a1; split=> //; case: a1 {Aa1} c2 c1 => c /= [_ hl _ _] *; exact: hl.
192- have g_majp : le_graph p g by move=> v r [[c [fs1 ls1 ms1 ps1]]] /= [_ /ms1].
179+ move=> v1 v2 l r1 r2 [a1 Aa1 c1] [a2 Aa2 c2].
180+ have [/RboolP sc12 | /RboolP sc21] := Amax _ _ Aa1 Aa2.
181+ - have {c1 sc12 Aa1 a1} c1 : carrier a2 v1 r1 by apply: sc12.
182+ by exists a2 => //; case: a2 {Aa2} c2 c1 => c /= [_ hl _ _] *; exact: hl.
183+ - have {c2 sc21 Aa2 a2} c2 : carrier a1 v2 r2 by apply: sc21.
184+ by exists a1 => //; case: a1 {Aa1} c2 c1 => c /= [_ hl _ _] *; exact: hl.
185+ have g_majp : le_graph p g.
186+ by move=> v r [[c/= [fs1 ls1 ms1 ps1]]]/= _ => /ms1.
193187have g_prol : extend_graph g.
194- move=> *; exists w; split => //; case: w Aw => [c [_ _ _ hp]] _ //=; exact: hp.
195- have spec_g : le_extend_graph g by split.
188+ by move=> *; exists w=> //; case: w Aw => [c [_ _ _ hp]] _ //=; exact: hp.
189+ have spec_g : le_extend_graph g by split.
196190pose zg := ZornType spec_g.
197191by exists zg => [a Aa]; apply/RboolP; rewrite /zornS => v r cvr; exists a.
198192Qed .
@@ -205,16 +199,17 @@ Hypothesis gP : forall z, zornS g z -> z = g.
205199real line directed by an arbitrary vector v *)
206200
207201Lemma domain_extend (z : zorn_type) v :
208- exists2 ze : zorn_type, ( zornS z ze) & ( exists r, (carrier ze) v r) .
202+ exists2 ze : zorn_type, zornS z ze & exists r, (carrier ze) v r.
209203Proof .
210204case: (lem (exists r, (carrier z v r))).
211205 by case=> r rP; exists z => //; exists r.
212206case: z => [c [fs1 ls1 ms1 ps1]] /= nzv.
213207have c00 : c 0 0.
214208 have <- : phi 0 = 0 by rewrite linear0.
215209 by move: ps1; rewrite /extend_graph /= => /(_ 0) /=; rewrite GRing.val0; apply.
216- have [a aP] : exists a, forall (x : V) (r lambda : R), c x r -> r + lambda * a <= p (x + lambda *: v).
217- suff [a aP] : exists a, forall (x : V) (r lambda : R), c x r -> 0 < lambda ->
210+ have [a aP] : exists a, forall (x : V) (r lambda : R), c x r ->
211+ r + lambda * a <= p (x + lambda *: v).
212+ suff [a aP] : exists a, forall (x : V) (r lambda : R), c x r -> 0 < lambda ->
218213 r + lambda * a <= p (x + lambda *: v) /\ r - lambda * a <= p (x - lambda *: v).
219214 exists a=> x r lambda cxr.
220215 have {aP} aP := aP _ _ _ cxr.
@@ -321,21 +316,19 @@ have [z /gP sgz [r zr]]:= domain_extend g v.
321316by exists r; rewrite -sgz.
322317Qed .
323318
324-
325319Lemma hb_witness : exists h : V -> R, forall v r, carrier g v r <-> (h v = r).
326320Proof .
327321move: (choice tot_g) => [h hP]; exists h => v r; split; last by move<-.
328322case: g gP tot_g hP => c /= [fg lg mg pg] => gP' tot_g' hP cvr.
329323by have -> // := fg v r (h v).
330324Qed .
331325
332-
333326End HBPreparation.
334327End HBPreparation.
335328
336329Section HahnBanach.
337330Import Lingraph.
338- Import HBPreparation.
331+ Import HBPreparation.
339332(* Now we prove HahnBanach on functions *)
340333(* We consider R a real (=ordered) field with supremum, and V a (left) module
341334 on R. We do not make use of the 'vector' interface as the latter enforces
@@ -350,7 +343,7 @@ Hypothesis p_cvx : (@convex_function R V [set: V] p).
350343Hypothesis f_bounded_by_p : forall (z : F'), (f z <= p (\val z)).
351344
352345Theorem HahnBanach : exists g : {scalar V},
353- (forall x, g x <= p x) /\ (forall (z : F'), g (\val z) = f z).
346+ (forall x, g x <= p x) /\ (forall (z : F'), g (\val z) = f z).
354347Proof .
355348pose graphF (v : V) r := exists2 z : F', v = \val z & r = f z.
356349have [z zmax]:= zornS_ex f_bounded_by_p.
@@ -397,7 +390,7 @@ Proof.
397390 rewrite /convex_function /conv => l v1 v2 _ _ /=.
398391 rewrite [X in (_ <= X)]/conv /= /p.
399392 apply: le_trans.
400- have H : `|l%:num *: v1 + (l%:num).~ *: v2| <= `|l%:num *: v1| + `|(l%:num).~ *: v2|.
393+ have H : `|l%:num *: v1 + (l%:num).~ *: v2| <= `|l%:num *: v1| + `|(l%:num).~ *: v2|.
401394 by apply: ler_normD.
402395 by apply: (@ler_pM _ _ _ r r _ _ H) => //; apply: ltW.
403396 rewrite mulrDl !normrZ -![_ *: _]/(_ * _).
@@ -407,19 +400,19 @@ Proof.
407400 have majfp : forall z : F', f z <= p (\val z).
408401 move => z; rewrite /(p _) ; apply : le_trans; last by [].
409402 by apply : ler_norm.
410- move: (HahnBanach convp majfp) => [g] [majgp F_eqgf] {majfp}.
411- have ling :( linear (g : V -> R)) by exact:linearP.
412- have contg: (continuous (g : V -> R)).
413- move=> x; rewrite /cvgP; apply: ( continuousfor0_continuous) .
403+ move: (HahnBanach convp majfp) => [g] [majgp F_eqgf] {majfp}.
404+ have ling : linear (g : V -> R) by exact: linearP.
405+ have contg : (continuous (g : V -> R)).
406+ move=> x; rewrite /cvgP; apply: continuousfor0_continuous.
414407 apply: bounded_linear_continuous.
415- exists r; split; first by exact: gtr0_real.
408+ exists r; split; first exact: gtr0_real.
416409 move => M m1; rewrite nbhs_ballP; exists 1 => /=; first by [].
417410 move => y; rewrite -ball_normE //= sub0r => y1.
418- rewrite ler_norml; apply/andP. split.
419- - rewrite lerNl -linearN; apply: (le_trans (majgp (-y))).
420- by rewrite /p -[X in _ <= X]mul1r; apply: ler_pM; rewrite ?normr_ge0 ?ltW //= .
411+ rewrite ler_norml; apply/andP; split.
412+ - rewrite lerNl -linearN; apply: (le_trans (majgp (- y))).
413+ by rewrite /p -[X in _ <= X]mul1r; apply: ler_pM; rewrite ?normr_ge0 ?ltW.
421414 - apply: (le_trans (majgp (y))); rewrite /p -[X in _ <= X]mul1r -normrN.
422- apply: ler_pM; rewrite ?normr_ge0 ?ltW //= .
415+ by apply: ler_pM; rewrite ?normr_ge0 ?ltW.
423416pose Hg := isLinearContinuous.Build _ _ _ _ g ling contg.
424417pose g': {linear_continuous V -> R | *%R} := HB.pack (g : V -> R) Hg.
425418by exists g'.
0 commit comments