Revision 058022c3be6121e485ecf48e19424d1ed36dc535 authored by François Dupressoir on 19 January 2022, 19:29:05 UTC, committed by François Dupressoir on 19 January 2022, 19:29:05 UTC
1 parent 46ba308
Raw File
RealLub.ec
(* --------------------------------------------------------------------
 * Copyright (c) - 2012--2016 - IMDEA Software Institute
 * Copyright (c) - 2012--2021 - Inria
 * Copyright (c) - 2012--2021 - Ecole Polytechnique
 *
 * Distributed under the terms of the CeCILL-B-V1 license
 * -------------------------------------------------------------------- *)

(* -------------------------------------------------------------------- *)
require import AllCore Bool StdRing StdOrder.
(*---*) import RField RealOrder.

pragma +implicits.

(* -------------------------------------------------------------------- *)
op down (E : real -> bool) =
  fun x => exists y, E y /\ x <= y.

(* -------------------------------------------------------------------- *)
lemma downK E : down (down E) = down E.
proof.
apply/fun_ext=> x; apply/eq_iff; split; last first.
+ by move=> Ex; exists x; split.
case=> y [[z [Ez le_yz]] le_xy]; exists z.
by split => //; apply/(ler_trans y).
qed.

(* -------------------------------------------------------------------- *)
lemma le_down E : E <= down E.
proof. by move=> x Ex; exists x; split. qed.

(* -------------------------------------------------------------------- *)
lemma has_lub_down E : has_lub (down E) <=> has_lub E.
proof. split; case=> nz hub.
+ split; first by case: nz=> x [y [Ey _]]; exists y.
  by case: hub=> x hub; exists x => y /le_down /hub.
+ split; first by case: nz => x /le_down ?; exists x.
  case: hub => x hub; exists x => y [z [Ez le_zy]].
  by apply/(ler_trans _ le_zy)/hub.
qed.

(* -------------------------------------------------------------------- *)
lemma nosmt ler_lub_down (E1 E2 : real -> bool) :
  (E1 <= down E2) => has_lub E2 => nonempty E1 => lub E1 <= lub E2.
proof.
move=> le lub2 [x E1x]; have {x E1x} lub1: has_lub E1.
  split; [exists x | exists (lub E2)]; move=> // y.
  by move/le=> [z] [E2z /ler_trans]; apply; apply/lub_upper_bound.
rewrite lerNgt -subr_gt0; apply/negP => lt_sup.
case: (lub_adherent _ lub1 _ lt_sup)=> x [/le [z [E2z le_xz]]].
rewrite opprD !addrA subrr add0r opprK => lt_S2x.
have := ltr_le_trans _ _ _ lt_S2x le_xz; rewrite ltrNge /=.
by apply/lub_upper_bound.
qed.

(* -------------------------------------------------------------------- *)
lemma nosmt ler_lub (E1 E2 : real -> bool) :
     (forall x, E1 x => exists y, E2 y /\ x <= y)
  => has_lub E2 => nonempty E1 => lub E1 <= lub E2.
proof. by move=> le12 lub2 nz1; apply: ler_lub_down. qed.

(* -------------------------------------------------------------------- *)
lemma lub_down E : has_lub E => lub (down E) = lub E.
proof.
move=> lubE; rewrite eqr_le !ler_lub_down //.
+ by move: lubE; rewrite -has_lub_down; case.
+ by rewrite downK le_down.
+ by rewrite has_lub_down.
+ by case: lubE.
qed.

(* -------------------------------------------------------------------- *)
lemma eq_lub (E1 E2 : real -> bool) :
  (forall x, E1 x <=> E2 x) => lub E1 = lub E2.
proof.
move=> eqE; have /fun_ext ->//: forall x, E1 x = E2 x.
by move=> x; apply/eq_iff/eqE.
qed.

(* -------------------------------------------------------------------- *)
lemma nosmt lub_le_ub E z : has_lub E => ub E z => lub E <= z.
proof.
move=> hlE ub_Ez; rewrite lerNgt &(negP) => lt_zlE.
case: (lub_adherent _ hlE (lub E - z) _); 1: by rewrite subr_gt0.
move=> e [eE]; rewrite opprB addrCA subrr addr0.
by rewrite ltrNge /=; apply: ub_Ez.
qed.
back to top