(* The type diadic represents the set of numbers who can be written:  	*)
(* x = n*2^p with  n and p in Z. (diadic numbers)			*)
(* n = Dnum and p = Dexp 						*)
   
Record diadic : Set := Diadic {Dnum : Z; Dexp : Z}.(* The type diadic represents the set of numbers who can be written:  	*)
(* x = n*2^p with  n and p in Z. (diadic numbers)			*)
(* n = Dnum and p = Dexp 						*)
   
Record diadic : Set := Diadic {Dnum : Z; Dexp : Z}.(* The type diadic represents the set of numbers who can be written:  	*)
(* x = n*2^p with  n and p in Z. (diadic numbers)			*)
(* n = Dnum and p = Dexp 						*)
   
Record diadic : Set := Diadic {Dnum : Z; Dexp : Z}.(* The type diadic represents the set of numbers who can be written:  	*)
(* x = n*2^p with  n and p in Z. (diadic numbers)			*)
(* n = Dnum and p = Dexp 						*)
   
Record diadic : Set := Diadic {Dnum : Z; Dexp : Z}.Definition Dshift (n : Z) (x : diadic) := Diadic (Dnum x) (Dexp x + n).Definition Dzero (x : Z) := Diadic 0 x.Definition is_Dzero (x : diadic) := Dnum x = 0%Z.(**
Fixpoint Dnormalize[x:diadic] : diadic :=
  Cases (Dnum x) of
    (POS (xO y)) => (Dnormalize (Diadic (POS y) `(Dexp x)+1`))
  | (NEG (xO y)) => (Dnormalize (Diadic (NEG y) `(Dexp x)+1`))
  | _ => x
  end.
**)
Inductive rounding_mode : Set :=
  | Rounding_sup : rounding_mode
  | Rounding_inf : rounding_mode
  | Rounding_nearest : rounding_mode
  | Rounding_zero : rounding_mode.(**
Fixpoint Dnormalize[x:diadic] : diadic :=
  Cases (Dnum x) of
    (POS (xO y)) => (Dnormalize (Diadic (POS y) `(Dexp x)+1`))
  | (NEG (xO y)) => (Dnormalize (Diadic (NEG y) `(Dexp x)+1`))
  | _ => x
  end.
**)
Inductive rounding_mode : Set :=
  | Rounding_sup : rounding_mode
  | Rounding_inf : rounding_mode
  | Rounding_nearest : rounding_mode
  | Rounding_zero : rounding_mode.(**
Fixpoint Dnormalize[x:diadic] : diadic :=
  Cases (Dnum x) of
    (POS (xO y)) => (Dnormalize (Diadic (POS y) `(Dexp x)+1`))
  | (NEG (xO y)) => (Dnormalize (Diadic (NEG y) `(Dexp x)+1`))
  | _ => x
  end.
**)
Inductive rounding_mode : Set :=
  | Rounding_sup : rounding_mode
  | Rounding_inf : rounding_mode
  | Rounding_nearest : rounding_mode
  | Rounding_zero : rounding_mode.(**
Fixpoint Dnormalize[x:diadic] : diadic :=
  Cases (Dnum x) of
    (POS (xO y)) => (Dnormalize (Diadic (POS y) `(Dexp x)+1`))
  | (NEG (xO y)) => (Dnormalize (Diadic (NEG y) `(Dexp x)+1`))
  | _ => x
  end.
**)
Inductive rounding_mode : Set :=
  | Rounding_sup : rounding_mode
  | Rounding_inf : rounding_mode
  | Rounding_nearest : rounding_mode
  | Rounding_zero : rounding_mode.(**
Fixpoint Dnormalize[x:diadic] : diadic :=
  Cases (Dnum x) of
    (POS (xO y)) => (Dnormalize (Diadic (POS y) `(Dexp x)+1`))
  | (NEG (xO y)) => (Dnormalize (Diadic (NEG y) `(Dexp x)+1`))
  | _ => x
  end.
**)
Inductive rounding_mode : Set :=
  | Rounding_sup : rounding_mode
  | Rounding_inf : rounding_mode
  | Rounding_nearest : rounding_mode
  | Rounding_zero : rounding_mode.Definition Rounding_mode_opp (m : rounding_mode) :=
  match m with
  | Rounding_sup => Rounding_inf
  | Rounding_inf => Rounding_sup
  | Rounding_nearest => Rounding_nearest
  | Rounding_zero => Rounding_zero
  end.(* Inductive relation := EGAL | INFERIEUR | SUPERIEUR *) 
Definition Deq (x y : diadic) :=
  match Dcompare x y with
  | Datatypes.Eq => True
  | Datatypes.Lt => False
  | Datatypes.Gt => False
  end.Definition Dneq (x y : diadic) :=
  match Dcompare x y with
  | Datatypes.Eq => False
  | Datatypes.Lt => True
  | Datatypes.Gt => True
  end.Definition Dle (x y : diadic) :=
  match Dcompare x y with
  | Datatypes.Eq => True
  | Datatypes.Lt => True
  | Datatypes.Gt => False
  end.Definition Dlt (x y : diadic) :=
  match Dcompare x y with
  | Datatypes.Eq => False
  | Datatypes.Lt => True
  | Datatypes.Gt => False
  end.Definition Dge (x y : diadic) :=
  match Dcompare x y with
  | Datatypes.Eq => True
  | Datatypes.Lt => False
  | Datatypes.Gt => True
  end.Definition Dgt (x y : diadic) :=
  match Dcompare x y with
  | Datatypes.Eq => False
  | Datatypes.Lt => False
  | Datatypes.Gt => True
  end.Definition Deq_bool (x y : diadic) :=
  match Dcompare x y with
  | Datatypes.Eq => true
  | Datatypes.Lt => false
  | Datatypes.Gt => false
  end.Definition Dneq_bool (x y : diadic) :=
  match Dcompare x y with
  | Datatypes.Eq => false
  | Datatypes.Lt => true
  | Datatypes.Gt => true
  end.Definition Dle_bool (x y : diadic) :=
  match Dcompare x y with
  | Datatypes.Eq => true
  | Datatypes.Lt => true
  | Datatypes.Gt => false
  end.Definition Dlt_bool (x y : diadic) :=
  match Dcompare x y with
  | Datatypes.Eq => false
  | Datatypes.Lt => true
  | Datatypes.Gt => false
  end.Definition Dge_bool (x y : diadic) :=
  match Dcompare x y with
  | Datatypes.Eq => true
  | Datatypes.Lt => false
  | Datatypes.Gt => true
  end.Definition Dgt_bool (x y : diadic) :=
  match Dcompare x y with
  | Datatypes.Eq => false
  | Datatypes.Lt => false
  | Datatypes.Gt => true
  end.

(* Specifications: *)
Lemma Dcompare_shift : forall (x y : diadic) (n : Z), Dcompare (Dshift n x) (Dshift n y) = Dcompare x y.
Lemma eq_Deq : forall x y : diadic, x = y -> Deq x y.
Lemma Deq_shift : forall (x y : diadic) (n : Z), Deq x y -> Deq (Dshift n x) (Dshift n y).
Lemma Deq_x_shift_x : forall (x : diadic) (n : Z), (0 <= n)%Z -> Deq x (Diadic (Dnum x * two_p n) (Dexp x - n)).
Lemma Dle_Zle : forall n1 n2 d : Z, (n1 <= n2)%Z -> Dle (Diadic n1 d) (Diadic n2 d).
Lemma Dlt_Zlt : forall n1 n2 d : Z, (n1 < n2)%Z -> Dlt (Diadic n1 d) (Diadic n2 d).
Lemma Dge_Zge : forall n1 n2 d : Z, (n1 >= n2)%Z -> Dge (Diadic n1 d) (Diadic n2 d).
Lemma Dgt_Zgt : forall n1 n2 d : Z, (n1 > n2)%Z -> Dgt (Diadic n1 d) (Diadic n2 d).
Lemma Dle_refl : forall x y : diadic, Deq x y -> Dle x y.