(* This file was originally generated by why.
   It can be modified; only the generated parts will be overwritten. *)
Require Export jessie_why.
Require Export WhyFloatsStrictLegacy.

(*Why type*) Definition charP: Set.
Admitted.

(*Why type*) Definition int8: Set.
Admitted.

(*Why type*) Definition padding: Set.
Admitted.

(*Why type*) Definition uint8: Set.
Admitted.

(*Why type*) Definition unsigned_charP: Set.
Admitted.

(*Why type*) Definition voidP: Set.
Admitted.

(*Why logic*) Definition charP_tag : (tag_id charP).
Admitted.

(*Why axiom*) Lemma charP_int : (int_of_tag charP_tag) = 1.
Admitted.
Dp_hint charP_int.

(*Why logic*) Definition charP_of_pointer_address :
  (pointer unit) -> (pointer charP).
Admitted.

(*Why axiom*) Lemma charP_of_pointer_address_of_pointer_addr :
  (forall (p:(pointer charP)),
   p = (charP_of_pointer_address (pointer_address p))).
Admitted.
Dp_hint charP_of_pointer_address_of_pointer_addr.

(*Why axiom*) Lemma charP_parenttag_bottom :
  (parenttag charP_tag (@bottom_tag charP)).
Admitted.
Dp_hint charP_parenttag_bottom.

(*Why axiom*) Lemma charP_tags :
  (forall (x:(pointer charP)),
   (forall (charP_tag_table:(tag_table charP)),
    (instanceof charP_tag_table x charP_tag))).
Admitted.
Dp_hint charP_tags.

(*Why logic*) Definition integer_of_int8 : int8 -> Z.
Admitted.

(*Why predicate*) Definition eq_int8  (x:int8) (y:int8)
  := (integer_of_int8 x) = (integer_of_int8 y).

(*Why logic*) Definition integer_of_uint8 : uint8 -> Z.
Admitted.

(*Why predicate*) Definition eq_uint8  (x:uint8) (y:uint8)
  := (integer_of_uint8 x) = (integer_of_uint8 y).

(*Why logic*) Definition int8_of_integer : Z -> int8.
Admitted.

(*Why axiom*) Lemma int8_coerce :
  (forall (x:Z),
   ((-128) <= x /\ x <= 127 -> (integer_of_int8 (int8_of_integer x)) = x)).
Admitted.

(*Why axiom*) Lemma int8_extensionality :
  (forall (x:int8),
   (forall (y:int8), ((integer_of_int8 x) = (integer_of_int8 y) -> x = y))).
Admitted.
Dp_hint int8_extensionality.

(*Why axiom*) Lemma int8_range :
  (forall (x:int8), (-128) <= (integer_of_int8 x) /\ (integer_of_int8 x) <=
   127).
Admitted.



(*Why predicate*) Definition left_valid_struct_charP  (p:(pointer charP)) (a:Z) (charP_alloc_table:(alloc_table charP))
  := (offset_min charP_alloc_table p) <= a.

(*Why predicate*) Definition left_valid_struct_unsigned_charP  (p:(pointer unsigned_charP)) (a:Z) (unsigned_charP_alloc_table:(alloc_table unsigned_charP))
  := (offset_min unsigned_charP_alloc_table p) <= a.

(*Why predicate*) Definition left_valid_struct_voidP  (p:(pointer voidP)) (a:Z) (voidP_alloc_table:(alloc_table voidP))
  := (offset_min voidP_alloc_table p) <= a.

(*Why axiom*) Lemma pointer_addr_of_charP_of_pointer_address :
  (forall (p:(pointer unit)),
   p = (pointer_address (charP_of_pointer_address p))).
Admitted.
Dp_hint pointer_addr_of_charP_of_pointer_address.

(*Why logic*) Definition unsigned_charP_of_pointer_address :
  (pointer unit) -> (pointer unsigned_charP).
Admitted.

(*Why axiom*) Lemma pointer_addr_of_unsigned_charP_of_pointer_address :
  (forall (p:(pointer unit)),
   p = (pointer_address (unsigned_charP_of_pointer_address p))).
Admitted.
Dp_hint pointer_addr_of_unsigned_charP_of_pointer_address.

(*Why logic*) Definition voidP_of_pointer_address :
  (pointer unit) -> (pointer voidP).
Admitted.

(*Why axiom*) Lemma pointer_addr_of_voidP_of_pointer_address :
  (forall (p:(pointer unit)),
   p = (pointer_address (voidP_of_pointer_address p))).
Admitted.
Dp_hint pointer_addr_of_voidP_of_pointer_address.

(*Why predicate*) Definition right_valid_struct_charP  (p:(pointer charP)) (b:Z) (charP_alloc_table:(alloc_table charP))
  := (offset_max charP_alloc_table p) >= b.

(*Why predicate*) Definition right_valid_struct_unsigned_charP  (p:(pointer unsigned_charP)) (b:Z) (unsigned_charP_alloc_table:(alloc_table unsigned_charP))
  := (offset_max unsigned_charP_alloc_table p) >= b.

(*Why predicate*) Definition right_valid_struct_voidP  (p:(pointer voidP)) (b:Z) (voidP_alloc_table:(alloc_table voidP))
  := (offset_max voidP_alloc_table p) >= b.

(*Why predicate*) Definition strict_valid_root_charP  (p:(pointer charP)) (a:Z) (b:Z) (charP_alloc_table:(alloc_table charP))
  := (offset_min charP_alloc_table p) = a /\
     (offset_max charP_alloc_table p) = b.

(*Why predicate*) Definition strict_valid_root_unsigned_charP  (p:(pointer unsigned_charP)) (a:Z) (b:Z) (unsigned_charP_alloc_table:(alloc_table unsigned_charP))
  := (offset_min unsigned_charP_alloc_table p) = a /\
     (offset_max unsigned_charP_alloc_table p) = b.

(*Why predicate*) Definition strict_valid_root_voidP  (p:(pointer voidP)) (a:Z) (b:Z) (voidP_alloc_table:(alloc_table voidP))
  := (offset_min voidP_alloc_table p) = a /\
     (offset_max voidP_alloc_table p) = b.

(*Why predicate*) Definition strict_valid_struct_charP  (p:(pointer charP)) (a:Z) (b:Z) (charP_alloc_table:(alloc_table charP))
  := (offset_min charP_alloc_table p) = a /\
     (offset_max charP_alloc_table p) = b.

(*Why predicate*) Definition strict_valid_struct_unsigned_charP  (p:(pointer unsigned_charP)) (a:Z) (b:Z) (unsigned_charP_alloc_table:(alloc_table unsigned_charP))
  := (offset_min unsigned_charP_alloc_table p) = a /\
     (offset_max unsigned_charP_alloc_table p) = b.

(*Why predicate*) Definition strict_valid_struct_voidP  (p:(pointer voidP)) (a:Z) (b:Z) (voidP_alloc_table:(alloc_table voidP))
  := (offset_min voidP_alloc_table p) = a /\
     (offset_max voidP_alloc_table p) = b.

(*Why logic*) Definition uint8_of_integer : Z -> uint8.
Admitted.

(*Why axiom*) Lemma uint8_coerce :
  (forall (x:Z),
   (0 <= x /\ x <= 255 -> (integer_of_uint8 (uint8_of_integer x)) = x)).
Admitted.
Dp_hint uint8_coerce.

(*Why axiom*) Lemma uint8_extensionality :
  (forall (x:uint8),
   (forall (y:uint8), ((integer_of_uint8 x) = (integer_of_uint8 y) -> x = y))).
Admitted.
Dp_hint uint8_extensionality.

(*Why axiom*) Lemma uint8_range :
  (forall (x:uint8), 0 <= (integer_of_uint8 x) /\ (integer_of_uint8 x) <= 255).
Admitted.
Dp_hint uint8_range.

(*Why logic*) Definition unsigned_charP_tag : (tag_id unsigned_charP).
Admitted.

(*Why axiom*) Lemma unsigned_charP_int : (int_of_tag unsigned_charP_tag) = 1.
Admitted.
Dp_hint unsigned_charP_int.

(*Why axiom*) Lemma unsigned_charP_of_pointer_address_of_pointer_addr :
  (forall (p:(pointer unsigned_charP)),
   p = (unsigned_charP_of_pointer_address (pointer_address p))).
Admitted.
Dp_hint unsigned_charP_of_pointer_address_of_pointer_addr.

(*Why axiom*) Lemma unsigned_charP_parenttag_bottom :
  (parenttag unsigned_charP_tag (@bottom_tag unsigned_charP)).
Admitted.
Dp_hint unsigned_charP_parenttag_bottom.

(*Why axiom*) Lemma unsigned_charP_tags :
  (forall (x:(pointer unsigned_charP)),
   (forall (unsigned_charP_tag_table:(tag_table unsigned_charP)),
    (instanceof unsigned_charP_tag_table x unsigned_charP_tag))).
Admitted.
Dp_hint unsigned_charP_tags.

(*Why predicate*) Definition valid_root_charP  (p:(pointer charP)) (a:Z) (b:Z) (charP_alloc_table:(alloc_table charP))
  := (offset_min charP_alloc_table p) <= a /\
     (offset_max charP_alloc_table p) >= b.

(*Why predicate*) Definition valid_root_unsigned_charP  (p:(pointer unsigned_charP)) (a:Z) (b:Z) (unsigned_charP_alloc_table:(alloc_table unsigned_charP))
  := (offset_min unsigned_charP_alloc_table p) <= a /\
     (offset_max unsigned_charP_alloc_table p) >= b.

(*Why predicate*) Definition valid_root_voidP  (p:(pointer voidP)) (a:Z) (b:Z) (voidP_alloc_table:(alloc_table voidP))
  := (offset_min voidP_alloc_table p) <= a /\
     (offset_max voidP_alloc_table p) >= b.

(*Why predicate*) Definition valid_struct_charP  (p:(pointer charP)) (a:Z) (b:Z) (charP_alloc_table:(alloc_table charP))
  := (offset_min charP_alloc_table p) <= a /\
     (offset_max charP_alloc_table p) >= b.

(*Why predicate*) Definition valid_struct_unsigned_charP  (p:(pointer unsigned_charP)) (a:Z) (b:Z) (unsigned_charP_alloc_table:(alloc_table unsigned_charP))
  := (offset_min unsigned_charP_alloc_table p) <= a /\
     (offset_max unsigned_charP_alloc_table p) >= b.

(*Why predicate*) Definition valid_struct_voidP  (p:(pointer voidP)) (a:Z) (b:Z) (voidP_alloc_table:(alloc_table voidP))
  := (offset_min voidP_alloc_table p) <= a /\
     (offset_max voidP_alloc_table p) >= b.

(*Why logic*) Definition voidP_tag : (tag_id voidP).
Admitted.

(*Why axiom*) Lemma voidP_int : (int_of_tag voidP_tag) = 1.
Admitted.
Dp_hint voidP_int.

(*Why axiom*) Lemma voidP_of_pointer_address_of_pointer_addr :
  (forall (p:(pointer voidP)),
   p = (voidP_of_pointer_address (pointer_address p))).
Admitted.
Dp_hint voidP_of_pointer_address_of_pointer_addr.

(*Why axiom*) Lemma voidP_parenttag_bottom :
  (parenttag voidP_tag (@bottom_tag voidP)).
Admitted.
Dp_hint voidP_parenttag_bottom.

(*Why axiom*) Lemma voidP_tags :
  (forall (x:(pointer voidP)),
   (forall (voidP_tag_table:(tag_table voidP)),
    (instanceof voidP_tag_table x voidP_tag))).
Admitted.
Dp_hint voidP_tags.

(* Why obligation from file "Sterbenz.c", line 38, characters 13-21: *)
(*Why goal*) Lemma Sterbenz_ensures_default_po_1 : 
  forall (x_0: single),
  forall (y: single),
  forall (HW_1: (* JC_7 *)
                ((* JC_5 *)
                 (Rle (Rdiv (single_value y) (2)%R) (single_value x_0)) /\
                (* JC_6 *)
                (Rle (single_value x_0) (Rmult (2)%R (single_value y))))),
  (* JC_16 *) (Rle (0)%R (single_value y)).
Proof.
intros x y (h1,h2).
apply Rmult_le_reg_l with 3%R.
  apply Rlt_le_trans with 2%R; auto with real.
apply Rplus_le_reg_l with (single_value y).
apply Rmult_le_reg_l with (/2)%R; auto with real.
replace (/ 2 * (single_value y + 3 * 0))%R with (single_value y / 2)%R by (unfold Rdiv; ring).
apply Rle_trans with (single_value x); [apply h1|idtac].
apply Rle_trans with  (2 * single_value y)%R; [ apply h2 | right; field].
Qed.

(* Why obligation from file "Sterbenz.c", line 39, characters 13-21: *)
(*Why goal*) Lemma Sterbenz_ensures_default_po_2 : 
  forall (x_0: single),
  forall (y: single),
  forall (HW_1: (* JC_7 *)
                ((* JC_5 *)
                 (Rle (Rdiv (single_value y) (2)%R) (single_value x_0)) /\
                (* JC_6 *)
                (Rle (single_value x_0) (Rmult (2)%R (single_value y))))),
  forall (HW_4: (* JC_16 *) (Rle (0)%R (single_value y))),
  (* JC_17 *) (Rle (0)%R (single_value x_0)).
Proof.
intros x y (h1,h2) y_pos.
apply Rle_trans with (single_value y / 2)%R; [idtac|apply h1].
unfold Rdiv; apply Rmult_le_pos; auto with real.
Save.

(* Why obligation from file "Sterbenz.c", line 35, characters 12-28: *)
(*Why goal*) Lemma Sterbenz_ensures_default_po_3 : 
  forall (x_0: single),
  forall (y: single),
  forall (HW_1: (* JC_7 *)
                ((* JC_5 *)
                 (Rle (Rdiv (single_value y) (2)%R) (single_value x_0)) /\
                (* JC_6 *)
                (Rle (single_value x_0) (Rmult (2)%R (single_value y))))),
  forall (HW_4: (* JC_16 *) (Rle (0)%R (single_value y))),
  forall (HW_5: (* JC_17 *) (Rle (0)%R (single_value x_0))),
  forall (result: single),
  forall (HW_6: (sub_single_post nearest_even x_0 y result)),
  forall (__retres: single),
  forall (HW_7: __retres = result),
  forall (why__return: single),
  forall (HW_8: why__return = __retres),
  (* JC_9 *)
  (eq (single_value why__return) (Rminus (single_value x_0) (single_value y))).
Proof.
intros x y (H1,H2) _ _ r (H4,(H5a,H5b)) r' H6 r'' H7.
rewrite H7,H6,H4; unfold single_value in *.
unfold FtoRradix; rewrite <- Fminus_correct; auto with zarith.
elim (mode_single_RoundingMode nearest_even); intros P (H8,H9).
apply sym_eq; apply RoundedModeProjectorIdemEq with bsingle 24%nat P; try apply psGivesBound; auto with zarith.
apply Sterbenz; auto with zarith; try apply FcanonicBound with radix; try now destruct x; try now destruct y.
fold FtoRradix; apply Rle_trans with (2:=H1); unfold Rdiv; simpl; right; ring.
Save.

(* Why obligation from file "Sterbenz.c", line 40, characters 9-12: *)
(*Why goal*) Lemma Sterbenz_safety_po_1 : 
  forall (x_0: single),
  forall (y: single),
  forall (HW_1: (* JC_7 *)
                ((* JC_5 *)
                 (Rle (Rdiv (single_value y) (2)%R) (single_value x_0)) /\
                (* JC_6 *)
                (Rle (single_value x_0) (Rmult (2)%R (single_value y))))),
  forall (HW_4: (* JC_13 *) (Rle (0)%R (single_value y))),
  forall (HW_5: (* JC_14 *) (Rle (0)%R (single_value x_0))),
  (no_overflow_single
   nearest_even (Rminus (single_value x_0) (single_value y))).
Proof.
intros x y (h1,h2) y_pos x_pos.
apply bounded_real_no_overflow_single.
case (Rle_or_lt (single_value x) (single_value y)); intros.
rewrite Rabs_left1.
ring_simplify.
apply Rle_trans with (-0+single_value y)%R;auto with real.
ring_simplify; rewrite <- (Rabs_right (single_value y)).
apply single_le_strict.
auto with real.
apply Rplus_le_reg_l with (single_value y); now ring_simplify.
rewrite Rabs_right.
ring_simplify.
apply Rle_trans with (single_value x-0)%R.
apply Rplus_le_compat_l; auto with real.
ring_simplify; rewrite <- (Rabs_right (single_value x)).
apply single_le_strict.
auto with real.
apply Rle_ge; apply Rplus_le_reg_l with (single_value y); ring_simplify; auto with real.
Save.

