(** Given a triple (mantissa, exponent, position), this function computes a triple with a canonic exponent, assuming the original triple had enough precision. *)
Definition truncate t :=
let '(m, e, l) := t in
let k := (fexp (Zdigits beta m + e) - e)%Z in
if Zlt_bool 0 k then truncate_aux t k
else t.

(* Specifications: *)
Theorem truncate_0 :
forall e l,
let '(m', e', l') := truncate (0, e, l)%Z in
m' = Z0.
Theorem generic_format_truncate :
forall m e l,
(0 <= m)%Z ->
let '(m', e', l') := truncate (m, e, l) in
format (F2R (Float beta m' e')).
Theorem truncate_correct_format :
forall m e,
m <> Z0 ->
let x := F2R (Float beta m e) in
generic_format beta fexp x ->
(e <= fexp (Zdigits beta m + e))%Z ->
let '(m', e', l') := truncate (m, e, loc_Exact) in
x = F2R (Float beta m' e') /\ e' = canonic_exp beta fexp x.
Theorem truncate_correct_partial :
forall x m e l,
(0 < x)%R ->
inbetween_float beta m e x l ->
(e <= fexp (Zdigits beta m + e))%Z ->
let '(m', e', l') := truncate (m, e, l) in
inbetween_float beta m' e' x l' /\ e' = canonic_exp beta fexp x.
Theorem truncate_correct :
forall x m e l,
(0 <= x)%R ->
inbetween_float beta m e x l ->
(e <= fexp (Zdigits beta m + e))%Z \/ l = loc_Exact ->
let '(m', e', l') := truncate (m, e, l) in
inbetween_float beta m' e' x l' /\
(e' = canonic_exp beta fexp x \/ (l' = loc_Exact /\ format x)).
Theorem truncate_0 :
forall e l,
let '(m', e', l') := truncate (0, e, l)%Z in
m' = Z0.
Theorem generic_format_truncate :
forall m e l,
(0 <= m)%Z ->
let '(m', e', l') := truncate (m, e, l) in
format (F2R (Float beta m' e')).
Theorem truncate_correct_format :
forall m e,
m <> Z0 ->
let x := F2R (Float beta m e) in
generic_format beta fexp x ->
(e <= fexp (Zdigits beta m + e))%Z ->
let '(m', e', l') := truncate (m, e, loc_Exact) in
x = F2R (Float beta m' e') /\ e' = canonic_exp beta fexp x.
Theorem truncate_correct_partial :
forall x m e l,
(0 < x)%R ->
inbetween_float beta m e x l ->
(e <= fexp (Zdigits beta m + e))%Z ->
let '(m', e', l') := truncate (m, e, l) in
inbetween_float beta m' e' x l' /\ e' = canonic_exp beta fexp x.
Theorem truncate_correct :
forall x m e l,
(0 <= x)%R ->
inbetween_float beta m e x l ->
(e <= fexp (Zdigits beta m + e))%Z \/ l = loc_Exact ->
let '(m', e', l') := truncate (m, e, l) in
inbetween_float beta m' e' x l' /\
(e' = canonic_exp beta fexp x \/ (l' = loc_Exact /\ format x)).