diff --git a/src/plugins/e-acsl/at_with_lscope.ml b/src/plugins/e-acsl/at_with_lscope.ml
index dbb8338c3907bd51be8159743fd4701cf0205250..af7ff2a1f0c51f5998ff0b9b00bf3d205e10a7d6 100644
--- a/src/plugins/e-acsl/at_with_lscope.ml
+++ b/src/plugins/e-acsl/at_with_lscope.ml
@@ -95,10 +95,7 @@ let rec sizes_and_shifts_from_quantifs ~loc kf lscope sizes_and_shifts =
       | _ ->
         Options.fatal "Unexpected comparison operator"
     in
-    let i =
-      try Interval.infer t_size
-      with Interval.Not_a_number | Interval.Is_a_real -> assert false
-    in
+    let iv = Interval.(extract_ival (infer t_size)) in
     (* The EXACT amount of memory that is needed can be known at runtime. This
       is because the tightest bounds for the variables can be known at runtime.
       Example: In the following predicate
@@ -116,7 +113,7 @@ let rec sizes_and_shifts_from_quantifs ~loc kf lscope sizes_and_shifts =
       beneficial. In particular, though we may allocate more memory than
       needed, the number of reads/writes into it is the same in both cases.
       Conclusion: over-approximate [t_size] *)
-    let t_size = match Ival.min_and_max i with
+    let t_size = match Ival.min_and_max iv with
       | _, Some max ->
         Logic_const.tint ~loc max
       | _, None ->
@@ -233,9 +230,9 @@ let to_exp ~loc kf env pot label =
     Cil.intType
   | Misc.PoT_term t ->
     begin match Typing.get_number_ty t with
-    | Typing.C_type _ | Typing.Nan ->
+    | Typing.(C_integer _ | C_float _ | Nan) ->
       Typing.get_typ t
-    | Typing.Real ->
+    | Typing.(Rational | Real) ->
       Error.not_yet "\\at on purely logic variables and over real type"
     | Typing.Gmpz ->
       Error.not_yet "\\at on purely logic variables and over gmp type"
@@ -259,20 +256,19 @@ let to_exp ~loc kf env pot label =
       in
       Typing.type_term ~use_gmp_opt:false t_size;
       let malloc_stmt = match Typing.get_number_ty t_size with
-      | Typing.C_type IInt ->
+      | Typing.C_integer IInt ->
         let e_size, _ = term_to_exp kf env t_size in
         let e_size = Cil.constFold false e_size in
         let malloc_stmt =
           Misc.mk_call ~loc ~result:(Cil.var vi) "malloc" [e_size]
         in
         malloc_stmt
-      | Typing.C_type _ | Typing.Gmpz ->
+      | Typing.(C_integer _ | C_float _ | Gmpz) ->
         Error.not_yet
           "\\at on purely logic variables that needs to allocate \
-            too much memory (bigger than int_max bytes)"
-      | Typing.Real | Typing.Nan ->
-        Options.fatal
-          "quantification over non-integer type is not part of E-ACSL"
+           too much memory (bigger than int_max bytes)"
+      | Typing.(Rational | Real | Nan) ->
+        Error.not_yet "quantification over non-integer type"
       in
       let free_stmt = Misc.mk_call ~loc "free" [e] in
       (* The list of stmts returned by the current closure are inserted
@@ -306,7 +302,7 @@ let to_exp ~loc kf env pot label =
       [ Cil.mkStmt ~valid_sid:true (Block block) ], env
     | Misc.PoT_term t ->
       begin match Typing.get_number_ty t with
-      | Typing.C_type _ | Typing.Nan ->
+      | Typing.(C_integer _ | C_float _ | Nan) ->
         let env = Env.push env in
         let lval, env = lval_at_index ~loc kf env (e_at, vi_at, t_index) in
         let e, env = term_to_exp kf env t in
@@ -320,7 +316,7 @@ let to_exp ~loc kf env pot label =
         (* We CANNOT return [block.bstmts] because it does NOT contain
           variable declarations. *)
         [ Cil.mkStmt ~valid_sid:true (Block block) ], env
-      | Typing.Real ->
+      | Typing.(Rational | Real) ->
         Error.not_yet "\\at on purely logic variables and over real type"
       | Typing.Gmpz ->
         Error.not_yet "\\at on purely logic variables and over gmp type"
diff --git a/src/plugins/e-acsl/interval.ml b/src/plugins/e-acsl/interval.ml
index e2e7dc95323b11f513de5d200d007cc98184497f..3aab01f01d3d31e387085dadc8538cde56f8e824 100644
--- a/src/plugins/e-acsl/interval.ml
+++ b/src/plugins/e-acsl/interval.ml
@@ -30,20 +30,151 @@ open Cil_types
 (* Basic datatypes and operations *)
 (* ********************************************************************* *)
 
-exception Is_a_real
-exception Not_a_number
+type ival =
+  | Ival of Ival.t
+  | Float of fkind * float option (* a float constant, if any *)
+  | Rational
+  | Real
+  | Nan
+
+module D =
+  Datatype.Make_with_collections
+    (struct
+      type t = ival
+      let name = "E_ACSL.Interval.t"
+      let reprs = [ Float (FFloat, Some 0.); Rational; Real; Nan ]
+      include Datatype.Undefined
+
+      let compare i1 i2 =
+        if i1 == i2 then 0
+        else
+          match i1, i2 with
+          | Ival i1, Ival i2 ->
+            Ival.compare i1 i2
+          | Float (k1, f1), Float (k2, f2) ->
+            (* faster to compare a kind than a float *)
+            let n = Stdlib.compare k1 k2 in
+            if n = 0 then Stdlib.compare f1 f2 else n
+          | Ival _, (Float _ | Rational | Real | Nan)
+          | Float _, (Rational | Real | Nan)
+          | Rational, (Real | Nan)
+          | Real, Nan ->
+            -1
+          | Nan, (Ival _ | Float _ | Rational | Real)
+          | Real, (Ival _ | Float _ | Rational)
+          | Rational, (Ival _ | Float _)
+          | Float _, Ival _ ->
+            1
+          | Rational, Rational | Real, Real | Nan, Nan ->
+            assert false
+
+      let equal = Datatype.from_compare
+
+      let hash = function
+        | Ival i -> 7 * Ival.hash i
+        | Float(k, f) -> 17 * Hashtbl.hash f + 97 * Hashtbl.hash k
+        | Rational -> 787
+        | Real -> 1011
+        | Nan -> 1277
+
+      let pretty fmt = function
+        | Ival i -> Ival.pretty fmt i
+        | Float(_, Some f) -> Format.pp_print_float fmt f
+        | Float(FFloat, None) -> Format.pp_print_string fmt "float"
+        | Float(FDouble, None) -> Format.pp_print_string fmt "double"
+        | Float(FLongDouble, None) -> Format.pp_print_string fmt "long double"
+        | Rational -> Format.pp_print_string fmt "Rational"
+        | Real -> Format.pp_print_string fmt "Real"
+        | Nan -> Format.pp_print_string fmt "NaN"
+
+    end)
+
+let is_included i1 i2 = match i1, i2 with
+  | Ival i1, Ival i2 -> Ival.is_included i1 i2
+  | Float(k1, f1), Float(k2, f2) ->
+    Stdlib.compare k1 k2 <= 0
+    && (match f1, f2 with
+        | None, None | Some _, None -> true
+        | None, Some _ -> false
+        | Some f1, Some f2 -> f1 = f2)
+  | (Ival _ | Float _ | Rational), (Rational | Real)
+  | Real, Real
+  | Nan, Nan ->
+    true
+  (* floats and integer are not comparable: *)
+  | Ival _, Float _ | Float _, Ival _
+  (* nan is comparable to noone, but itself: *)
+  | (Ival _ | Float _ | Rational | Real), Nan
+  | Nan, (Ival _ | Float _ | Rational | Real)
+  (* cases for reals and rationals: *)
+  | Real, (Ival _ | Float _ | Rational)
+  | Rational, (Ival _ | Float _) ->
+    false
+
+let lift_unop f = function
+  | Ival iv -> Ival (f iv)
+  | Float _ ->
+    (* any unary operator over a float generates a rational
+       TODO: actually, certainly possible to generate a float *)
+    Rational
+  | Rational | Real | Nan as i -> i
+
+let lift_binop ~safe_float f i1 i2 = match i1, i2 with
+  | Ival i1, Ival i2 ->
+    Ival (f i1 i2)
+  | Float(k1, _), Float(k2, _) when safe_float ->
+    let k = if Stdlib.compare k1 k2 >= 0 then k1 else k2 in
+    Float(k, None (* lost value, if any before *))
+  | (Ival _ | Float _ | Rational), (Float _ | Rational)
+  | (Float _ | Rational), Ival _ ->
+    (* any binary operator over a float or a rational generates a rational *)
+    Rational
+  | (Ival _ | Float _ | Rational | Real), Real
+  | Real, (Ival _ | Float _ | Rational) ->
+    Real
+  | (Ival _ | Float _ | Rational | Real | Nan), Nan
+  | Nan, (Ival _ | Float _ | Rational | Real) ->
+    Nan
+
+let join = lift_binop ~safe_float:true Ival.join
+
+(* TODO: soundness of any downcast is not checked *)
+let cast ~src ~dst = match src, dst with
+  | Ival i1, Ival i2 ->
+    Ival (Ival.meet i1 i2)
+  | _, Float(_, Some _) ->
+    assert false
+  | Rational, Real
+  | Float _, (Rational | Real) ->
+    src
+  | _, _ ->
+    (* No need to optimize the other cases: if someone writes a cast
+       (in particular, from integer to float/real or conversely), it is
+       certainly on purpose . *)
+    dst
 
-(* constructors *)
+(* ********************************************************************* *)
+(* constructors and destructors *)
+(* ********************************************************************* *)
 
-let singleton_of_int n = Ival.inject_singleton (Integer.of_int n)
+let extract_ival = function
+  | Ival iv -> iv
+  | Float _ | Rational | Real | Nan -> assert false
+
+let bottom = Ival Ival.bottom
+let top_ival = Ival (Ival.inject_range None None)
+let singleton n = Ival (Ival.inject_singleton n)
+let singleton_of_int n = singleton (Integer.of_int n)
+let ival min max = Ival (Ival.inject_range (Some min) (Some max))
 
 let interv_of_unknown_block =
   (* since we have no idea of the size of this block, we take the largest
      possible one which is unfortunately quite large *)
-  lazy
-    (Ival.inject_range
-       (Some Integer.zero)
-       (Some (Bit_utils.max_byte_address ())))
+  lazy (ival Integer.zero (Bit_utils.max_byte_address ()))
+
+(* ********************************************************************* *)
+(* main algorithm *)
+(* ********************************************************************* *)
 
 (* The boolean indicates whether we have real numbers *)
 let rec interv_of_typ ty = match Cil.unrollType ty with
@@ -53,29 +184,31 @@ let rec interv_of_typ ty = match Cil.unrollType ty with
       if Cil.isSigned k then Cil.min_signed_number n, Cil.max_signed_number n
       else Integer.zero, Cil.max_unsigned_number n
     in
-    Ival.inject_range (Some l) (Some u)
+    ival l u
   | TEnum(enuminfo, _) ->
-    interv_of_typ (TInt (enuminfo.ekind, []))
-  | TFloat _ ->
-    raise Is_a_real
+    interv_of_typ (TInt(enuminfo.ekind, []))
+  | _ when Gmp.Z.is_t ty ->
+    top_ival
+  | TFloat (k, _) ->
+    Float(k, None)
   | _ when Real.is_t ty ->
-    raise Is_a_real
+    Rational (* only rationals are implemented *)
   | TVoid _ | TPtr _ | TArray _ | TFun _ | TComp _ | TBuiltin_va_list _ ->
-    raise Not_a_number
+    Nan
   | TNamed _ ->
     assert false
 
 let interv_of_logic_typ = function
   | Ctype ty -> interv_of_typ ty
-  | Linteger -> Ival.inject_range None None
-  | Lreal -> raise Is_a_real
+  | Linteger -> top_ival
+  | Lreal -> Real
   | Ltype _ -> Error.not_yet "user-defined logic type"
   | Lvar _ -> Error.not_yet "type variable"
-  | Larrow _ -> Error.not_yet "functional type"
+  | Larrow _ -> Nan
 
-let ikind_of_interv i =
-  if Ival.is_bottom i then IInt
-  else match Ival.min_and_max i with
+let ikind_of_ival iv =
+  if Ival.is_bottom iv then IInt
+  else match Ival.min_and_max iv with
     | Some l, Some u ->
       let is_pos = Integer.ge l Integer.zero in
       let lkind = Cil.intKindForValue l is_pos in
@@ -85,31 +218,31 @@ let ikind_of_interv i =
       (* convert the kind to [IInt] whenever smaller. *)
       if Cil.intTypeIncluded kind IInt then IInt else kind
     | None, None -> raise Cil.Not_representable (* GMP *)
+    (* TODO: do not raise an exception, but returns a value instead *)
     | None, Some _ | Some _, None ->
-      Kernel.fatal ~current:true "unexpected ival: %a" Ival.pretty i
+      Kernel.fatal ~current:true "unexpected ival: %a" Ival.pretty iv
 
 (* function call profiles (intervals for their formal parameters) *)
 module Profile = struct
   include Datatype.List_with_collections
-      (Ival)
+      (D)
       (struct
         let module_name = "E_ACSL.Interval.Logic_function_env.Profile"
       end)
-  let is_included p1 p2 = List.for_all2 Ival.is_included p1 p2
-  let _join p1 p2 = List.map2 Ival.join p1 p2 (* TODO: to be removed *)
+  let is_included p1 p2 = List.for_all2 is_included p1 p2
 end
 
 (* Imperative environments *)
 module rec Env: sig
   val clear: unit -> unit
-  val add: Cil_types.logic_var -> Ival.t -> unit
-  val find: Cil_types.logic_var -> Ival.t
+  val add: Cil_types.logic_var -> ival -> unit
+  val find: Cil_types.logic_var -> ival
   val remove: Cil_types.logic_var -> unit
-  val replace: Cil_types.logic_var -> Ival.t -> unit
+  val replace: Cil_types.logic_var -> ival -> unit
 end = struct
 
   open Cil_datatype
-  let tbl: Ival.t Logic_var.Hashtbl.t = Logic_var.Hashtbl.create 7
+  let tbl: ival Logic_var.Hashtbl.t = Logic_var.Hashtbl.create 7
 
   (* TODO: when adding, also join with the old value (if any). Would certainly
      be the correct way to handle a \let in a recursive logic functions (if the
@@ -127,7 +260,7 @@ end
 
 (* Environment for handling logic functions *)
 and Logic_function_env: sig
-  val widen: infer:(term -> Ival.t) -> term -> Ival.t -> bool * Ival.t
+  val widen: infer:(term -> ival) -> term -> ival -> bool * ival
   val clear: unit -> unit
 end = struct
 
@@ -161,13 +294,15 @@ end = struct
     Terms.clear terms;
     LF.Hashtbl.clear named_profiles
 
-  let interv_of_typ_containing_interv i =
-    try
-      let kind = ikind_of_interv i in
-      interv_of_typ (TInt(kind, []))
-    with Cil.Not_representable ->
-      (* infinity *)
-      Ival.inject_range None None
+  let interv_of_typ_containing_interv = function
+    | Float _ | Rational | Real | Nan as x ->
+      x
+    | Ival i ->
+      try
+        let kind = ikind_of_ival i in
+        interv_of_typ (TInt(kind, []))
+      with Cil.Not_representable ->
+        top_ival
 
   let rec map3 f l1 l2 l3 = match l1, l2, l3 with
     | [], [], [] -> []
@@ -177,24 +312,20 @@ end = struct
   let extract_profile ~infer old_profile t = match t.term_node with
     | Tapp(li, _, args) ->
       let old_profile = match old_profile with
-        | None -> List.map (fun _ -> Ival.bottom) li.l_profile
+        | None -> List.map (fun _ -> bottom) li.l_profile
         | Some p -> p
       in
       li.l_var_info.lv_name,
       map3
         (fun param old_i arg ->
-           try
-             let i = infer arg in
-             (* over-approximation of the interval to reach the fixpoint
-                faster, and to generate fewer specialized functions *)
-             let larger_i = interv_of_typ_containing_interv i in
-             (* merge the old profile and the new one *)
-             let new_i = Ival.join larger_i old_i in
-             Env.add param new_i;
-             new_i
-           with Not_a_number ->
-             (* no need to add [param] to the environment *)
-             Ival.bottom)
+           let i = infer arg in
+           (* over-approximation of the interval to reach the fixpoint
+              faster, and to generate fewer specialized functions *)
+           let larger_i = interv_of_typ_containing_interv i in
+           (* merge the old profile and the new one *)
+           let new_i = join larger_i old_i in
+           Env.add param new_i;
+           new_i)
         li.l_profile
         old_profile
         args
@@ -205,9 +336,9 @@ end = struct
     let (_, p as named_p) = extract_profile ~infer old_profile t in
     try
       let old_i = LF.Hashtbl.find named_profiles named_p in
-      if Ival.is_included i old_i then true, p, old_i
+      if is_included i old_i then true, p, old_i
       else begin
-        let j = Ival.join i old_i in
+        let j = join i old_i in
         LF.Hashtbl.replace named_profiles named_p j;
         false, p, j
       end
@@ -244,17 +375,17 @@ let infer_alignof ty = singleton_of_int (Cil.bytesAlignOf ty)
 let rec infer t =
   let get_cty t = match t.term_type with Ctype ty -> ty | _ -> assert false in
   match t.term_node with
-  | TConst (Integer (n, _)) -> Ival.inject_singleton n
+  | TConst (Integer (n, _)) -> singleton n
   | TConst (LChr c) ->
     let n = Cil.charConstToInt c in
-    Ival.inject_singleton n
+    singleton n
   | TConst (LEnum enumitem) ->
     let rec find_idx n = function
       | [] -> assert false
       | ei :: l -> if ei == enumitem then n else find_idx (n + 1) l
     in
     let n = Integer.of_int (find_idx 0 enumitem.eihost.eitems) in
-    Ival.inject_singleton n
+    singleton n
   | TLval lv -> infer_term_lval lv
   | TSizeOf ty -> infer_sizeof ty
   | TSizeOfE t -> infer_sizeof (get_cty t)
@@ -264,66 +395,53 @@ let rec infer t =
 
   | TUnOp (Neg, t) ->
     let i = infer t in
-    Ival.neg_int i
+    lift_unop Ival.neg_int i
   | TUnOp (BNot, t) ->
     let i = infer t in
-    Ival.bitwise_signed_not i
+    lift_unop Ival.bitwise_signed_not i
   | TUnOp (LNot, _)
   | TBinOp ((Lt | Gt | Le | Ge | Eq | Ne | LAnd | LOr), _, _) ->
-    Ival.zero_or_one
+    Ival Ival.zero_or_one
 
   | TBinOp (PlusA, t1, t2) ->
     let i1 = infer t1 in
     let i2 = infer t2 in
-    Ival.add_int i1 i2
+    lift_binop ~safe_float:false Ival.add_int i1 i2
   | TBinOp (MinusA, t1, t2) ->
     let i1 = infer t1 in
     let i2 = infer t2 in
-    Ival.sub_int i1 i2
+    lift_binop ~safe_float:false Ival.sub_int i1 i2
   | TBinOp (Mult, t1, t2) ->
     let i1 = infer t1 in
     let i2 = infer t2 in
-    Ival.mul i1 i2
+    lift_binop ~safe_float:false Ival.mul i1 i2
   | TBinOp (Div, t1, t2) ->
     let i1 = infer t1 in
     let i2 = infer t2 in
-    Ival.div i1 i2
+    lift_binop ~safe_float:false Ival.div i1 i2
   | TBinOp (Mod, t1, t2) ->
     let i1 = infer t1 in
     let i2 = infer t2 in
-    Ival.c_rem i1 i2
+    lift_binop ~safe_float:false Ival.c_rem i1 i2
   | TBinOp (Shiftlt , _, _) -> Error.not_yet "right shift"
   | TBinOp (Shiftrt , _, _) -> Error.not_yet "left shift"
   | TBinOp (BAnd, _, _) -> Error.not_yet "bitwise and"
   | TBinOp (BXor, t1, t2) ->
     let i1 = infer t1 in
     let i2 = infer t2 in
-    Ival.bitwise_xor i1 i2
+    lift_binop ~safe_float:false Ival.bitwise_xor i1 i2
   | TBinOp (BOr, t1, t2) ->
     let i1 = infer t1 in
     let i2 = infer t2 in
-    Ival.bitwise_or i1 i2
+    lift_binop ~safe_float:false Ival.bitwise_or i1 i2
   | TCastE (ty, t) ->
-    (try
-       let it = infer t in
-       let ity = interv_of_typ ty in
-       Ival.meet it ity
-     with Not_a_number ->
-       if Cil.isIntegralType ty then begin
-         (* heterogeneous cast from a non-integral term to an integral type:
-            consider that one eventually gets an integral type even if it is
-            not sure. *)
-         Options.warning
-           ~once:true "possibly unsafe cast from term '%a' to type '%a'."
-           Printer.pp_term t
-           Printer.pp_typ ty;
-         interv_of_typ ty
-       end else
-         raise Not_a_number)
+    let src = infer t in
+    let dst = interv_of_typ ty in
+    cast ~src ~dst
   | Tif (_, t2, t3) ->
     let i2 = infer t2 in
     let i3 = infer t3 in
-    Ival.join i2 i3
+    join i2 i3
   | Tat (t, _) ->
     infer t
   | TBinOp (MinusPP, t, _) ->
@@ -332,10 +450,7 @@ let rec infer t =
        (* the second argument must be in the same block than [t]. Consequently
           the result of the difference belongs to [0; \block_length(t)] *)
        let nb_bytes = if n mod 8 = 0 then n / 8 else n / 8 + 1 in
-       let i =
-         Ival.inject_range (Some Integer.zero) (Some (Integer.of_int nb_bytes))
-       in
-       i
+       ival Integer.zero (Integer.of_int nb_bytes)
      | TArray _ | TPtr _ ->
        Lazy.force interv_of_unknown_block
      | _ -> assert false)
@@ -353,7 +468,7 @@ let rec infer t =
   | Tapp (li, _, _args) ->
     (match li.l_body with
      | LBpred _ ->
-       Ival.zero_or_one
+       Ival Ival.zero_or_one
      | LBterm t' ->
        let rec fixpoint i =
          let is_included, new_i =
@@ -367,11 +482,7 @@ let rec infer t =
            List.iter (fun lv -> Env.remove lv) li.l_profile;
            fixpoint i
        in
-       let i = fixpoint Ival.bottom in
-       (* call [interv_of_logic_typ] in order to raise Is_a_real or Not_a_number
-          when the function does not return an integer *)
-       Extlib.may (fun lty -> ignore (interv_of_logic_typ lty)) li.l_type;
-       i
+       fixpoint bottom
      | LBnone
      | LBreads _ ->
        (match li.l_type with
@@ -386,7 +497,7 @@ let rec infer t =
   | Trange(Some n1, Some n2) ->
     let i1 = infer n1 in
     let i2 = infer n2 in
-    Ival.join i1 i2
+    join i1 i2
   | Trange(None, _) | Trange(_, None) ->
     Options.abort "unbounded ranges are not part of E-ACSl"
 
@@ -398,8 +509,9 @@ let rec infer t =
     let i2 = infer t in
     Env.remove li_v;
     i2
-  | TConst (LReal _) ->
-    raise Is_a_real
+  | TConst (LReal lr) ->
+    if lr.r_lower = lr.r_upper then Float(FDouble, Some lr.r_nearest)
+    else Rational
   | TConst (LStr _ | LWStr _)
   | TBinOp (PlusPI,_,_)
   | TBinOp (IndexPI,_,_)
@@ -413,7 +525,7 @@ let rec infer t =
   | Ttypeof _
   | Ttype _
   | Tempty_set ->
-    raise Not_a_number
+    Nan
 
 and infer_term_lval (host, offset as tlv) =
   match offset with
@@ -425,11 +537,11 @@ and infer_term_lval (host, offset as tlv) =
 and infer_term_host thost =
   match thost with
   | TVar v ->
-    (try Env.find v
-     with Not_found ->
+    (try Env.find v with Not_found ->
      match v.lv_type with
-     | Linteger -> Ival.inject_range None None
-     | Ctype (TFloat _) | Lreal -> raise Is_a_real
+     | Linteger -> top_ival
+     | Ctype (TFloat(fk, _)) -> Float(fk, None)
+     | Lreal -> Real
      | Ctype _ -> interv_of_typ (Logic_utils.logicCType v.lv_type)
      | Ltype _ | Lvar _ | Larrow _ -> Options.fatal "unexpected logic type")
   | TResult ty ->
@@ -444,6 +556,8 @@ and infer_term_host thost =
         Printer.pp_typ ty
         Printer.pp_term t
 
+include D
+
 (*
 Local Variables:
 compile-command: "make"
diff --git a/src/plugins/e-acsl/interval.mli b/src/plugins/e-acsl/interval.mli
index 9d7b5d59a91b56ff6aca9b15cb76a923b6637c9d..4260d80f8a3f8114ed328d15d20f0d9b8a4aa76c 100644
--- a/src/plugins/e-acsl/interval.mli
+++ b/src/plugins/e-acsl/interval.mli
@@ -51,15 +51,30 @@
 (** {3 Useful operations on intervals} *)
 (* ************************************************************************** *)
 
-exception Is_a_real
-exception Not_a_number
+type ival =
+  | Ival of Ival.t
+  | Float of Cil_types.fkind * float option
+  | Rational
+  | Real
+  | Nan
 
-val ikind_of_interv: Ival.t -> Cil_types.ikind
+include Datatype.S_with_collections with type t = ival
+
+val is_included: t -> t -> bool
+val join: t -> t -> t
+
+val top_ival: t
+val ival: Integer.t -> Integer.t -> t
+
+(** assume [Ival _] as argument *)
+val extract_ival: t -> Ival.t
+
+val ikind_of_ival: Ival.t -> Cil_types.ikind
 (** @return the smallest ikind that contains the given interval.
     @raise Cil.Not_representable if the given interval does not fit into any C
     integral type. *)
 
-val interv_of_typ: Cil_types.typ -> Ival.t
+val interv_of_typ: Cil_types.typ -> t
 (** @return the smallest interval which contains the given C type.
     @raise Is_a_real if the given type is a float type.
     @raise Not_a_number if the given type does not represent any number. *)
@@ -72,16 +87,16 @@ val interv_of_typ: Cil_types.typ -> Ival.t
     be extended from outside. *)
 module Env: sig
   val clear: unit -> unit
-  val add: Cil_types.logic_var -> Ival.t -> unit
+  val add: Cil_types.logic_var -> t -> unit
   val remove: Cil_types.logic_var -> unit
-  val replace: Cil_types.logic_var -> Ival.t -> unit
+  val replace: Cil_types.logic_var -> t -> unit
 end
 
 (* ************************************************************************** *)
 (** {3 Inference system} *)
 (* ************************************************************************** *)
 
-val infer: Cil_types.term -> Ival.t
+val infer: Cil_types.term -> t
 (** [infer t] infers the smallest possible integer interval which the values
     of the term can fit in.
     @raise Is_a_real if the term is either a float or a real.
diff --git a/src/plugins/e-acsl/logic_functions.ml b/src/plugins/e-acsl/logic_functions.ml
index f688b954836842a39eca24a22da1be98733597ed..dfaec0c2b93c95c1c868027c8604917518b5894c 100644
--- a/src/plugins/e-acsl/logic_functions.ml
+++ b/src/plugins/e-acsl/logic_functions.ml
@@ -126,8 +126,11 @@ let generate_kf ~loc fname env ret_ty params_ty li =
             (* GMP's integer are arrays: consider them as pointers in function's
                parameters *)
             Gmp.Z.t_as_ptr ()
-          | Typing.C_type ik -> TInt(ik, [])
-          | Typing.Real -> assert false (* TODO RATIONAL: to be implemented *)
+          | Typing.C_integer ik -> TInt(ik, [])
+          | Typing.C_float ik -> TFloat(ik, [])
+          (* for the time being, no reals but rationals instead *)
+          | Typing.Rational -> Real.t ()
+          | Typing.Real -> Error.not_yet "real number"
           | Typing.Nan -> Typing.typ_of_lty lvi.lv_type
         in
         (* build the formals: cannot use [Cil.makeFormal] since the function
@@ -190,14 +193,7 @@ let generate_kf ~loc fname env ret_ty params_ty li =
        before generating the code (code generation invokes typing) *)
     let env =
       let add env lvi vi =
-        let i =
-          try
-            Interval.interv_of_typ vi.vtype
-          with
-          | Interval.Not_a_number
-          | Interval.Is_a_real ->
-            Ival.inject_range None None
-        in
+        let i = Interval.interv_of_typ vi.vtype in
         Interval.Env.add lvi i;
         Env.Logic_binding.add_binding env lvi vi
       in
diff --git a/src/plugins/e-acsl/loops.ml b/src/plugins/e-acsl/loops.ml
index a41da743536de9d61a684126e138fef6b9380331..7ed887499ba3ac1622f6727d2cff36319a5d56f6 100644
--- a/src/plugins/e-acsl/loops.ml
+++ b/src/plugins/e-acsl/loops.ml
@@ -117,51 +117,49 @@ let preserve_invariant prj env kf stmt = match stmt.skind with
     Return: R with a guard guaranteeing that [lv] does not overflow *)
 let bounds_for_small_type ~loc (t1, lv, t2) =
   match lv.lv_type with
+  | Ltype _ | Lvar _ | Lreal | Larrow _ ->
+    Options.abort "quantification over non-integer type is not part of E-ACSL"
+
   | Linteger ->
     t1, t2, None
+
   | Ctype ty ->
-    (try
-       let i1 = Interval.infer t1 in
-       let i2 = Interval.infer t2 in
-       let i =
-         (* Ival.join would NOT be correct here:
-            Eg: (Ival.join [-3..-3] [300..300]) gives {-3, 300}
-                but NOT [-3..300] *)
-         Ival.inject_range (Ival.min_int i1) (Ival.max_int i2)
-       in
-       let ity = Interval.interv_of_typ ty in
-       if Ival.is_included i ity then
-         (* case 1 *)
-         t1, t2, None
-       else if Ival.is_singleton_int i1 && Ival.is_singleton_int i2 then begin
-         (* case 2 *)
-         let i = Ival.meet i ity in
-         (* now we potentially have a better interval for [lv]
-            ==> update the binding *)
-         Interval.Env.replace lv i;
-         (* the smaller bounds *)
-         let min, max = Misc.finite_min_and_max i in
-         let t1 = Logic_const.tint ~loc min in
-         let t2 = Logic_const.tint ~loc max in
-         let ctx = Typing.number_ty_of_typ ty in
-         (* we are assured that we will not have a GMP,
-            once again because we intersected with [ity] *)
-         Typing.type_term ~use_gmp_opt:false ~ctx t1;
-         Typing.type_term ~use_gmp_opt:false ~ctx t2;
-         t1, t2, None
-       end else
-         (* case 3 *)
-         let min, max = Misc.finite_min_and_max ity in
-         let guard_lower = Logic_const.tint ~loc min in
-         let guard_upper = Logic_const.tint ~loc max in
-         let lv_term = Logic_const.tvar ~loc lv in
-         let guard_lower = Logic_const.prel ~loc (Rle, guard_lower, lv_term) in
-         let guard_upper = Logic_const.prel ~loc (Rle, lv_term, guard_upper) in
-         let guard = Logic_const.pand ~loc (guard_lower, guard_upper) in
-         t1, t2, Some guard
-     with Interval.Not_a_number | Interval.Is_a_real -> assert false)
-  | Ltype _ | Lvar _ | Lreal | Larrow _ ->
-    Options.abort "quantification over non-integer type is not part of E-ACSL"
+    let iv1 = Interval.(extract_ival (infer t1)) in
+    let iv2 = Interval.(extract_ival (infer t2)) in
+    (* Ival.join is NOT correct here:
+       Eg: (Ival.join [-3..-3] [300..300]) gives {-3, 300}
+       but NOT [-3..300] *)
+    let iv = Ival.inject_range (Ival.min_int iv1) (Ival.max_int iv2) in
+    let ity = Interval.extract_ival (Interval.interv_of_typ ty) in
+    if Ival.is_included iv ity then
+      (* case 1 *)
+      t1, t2, None
+    else if Ival.is_singleton_int iv1 && Ival.is_singleton_int iv2 then begin
+      (* case 2 *)
+      let i = Ival.meet iv ity in
+      (* now we potentially have a better interval for [lv]
+         ==> update the binding *)
+      Interval.Env.replace lv (Interval.Ival i);
+      (* the smaller bounds *)
+      let min, max = Misc.finite_min_and_max i in
+      let t1 = Logic_const.tint ~loc min in
+      let t2 = Logic_const.tint ~loc max in
+      let ctx = Typing.number_ty_of_typ ty in
+      (* we are assured that we will not have a GMP,
+         once again because we intersected with [ity] *)
+      Typing.type_term ~use_gmp_opt:false ~ctx t1;
+      Typing.type_term ~use_gmp_opt:false ~ctx t2;
+      t1, t2, None
+    end else
+      (* case 3 *)
+      let min, max = Misc.finite_min_and_max ity in
+      let guard_lower = Logic_const.tint ~loc min in
+      let guard_upper = Logic_const.tint ~loc max in
+      let lv_term = Logic_const.tvar ~loc lv in
+      let guard_lower = Logic_const.prel ~loc (Rle, guard_lower, lv_term) in
+      let guard_upper = Logic_const.prel ~loc (Rle, lv_term, guard_upper) in
+      let guard = Logic_const.pand ~loc (guard_lower, guard_upper) in
+      t1, t2, Some guard
 
 let rec mk_nested_loops ~loc mk_innermost_block kf env lscope_vars =
   let term_to_exp = !term_to_exp_ref in
@@ -224,9 +222,9 @@ let rec mk_nested_loops ~loc mk_innermost_block kf env lscope_vars =
     let var_x, x, env = Env.Logic_binding.add ~ty env logic_x in
     let lv_x = var var_x in
     let env = match ctx_one with
-      | Typing.C_type _ -> env
+      | Typing.C_integer _ -> env
       | Typing.Gmpz -> Env.add_stmt env (Gmp.init ~loc x)
-      | Typing.Real | Typing.Nan -> assert false
+      | Typing.(C_float _ | Rational | Real | Nan) -> assert false
     in
     (* build the inner loops and loop body *)
     let body, env =
diff --git a/src/plugins/e-acsl/misc.ml b/src/plugins/e-acsl/misc.ml
index 0c62fb7c2c9706683c5511a27af9488411945abd..2f886c8ce5492a491518d8b1751a9bfdcd4a9144 100644
--- a/src/plugins/e-acsl/misc.ml
+++ b/src/plugins/e-acsl/misc.ml
@@ -246,6 +246,7 @@ let rec ptr_index ?(loc=Location.unknown) ?(index=(Cil.zero loc)) exp =
   | SizeOf _ | SizeOfE _ | SizeOfStr _ | AlignOf _ | AlignOfE _
     -> assert false
 
+(* TODO: should not be in this file *)
 let term_of_li li =  match li.l_body with
 | LBterm t -> t
 | LBnone | LBreads _ | LBpred _ | LBinductive _ ->
diff --git a/src/plugins/e-acsl/mmodel_translate.ml b/src/plugins/e-acsl/mmodel_translate.ml
index 7457de1d8cda7bc72736ca81a586c1795fb9a226..314f9c38c1797c55db1469ed39beafe5409ca0c4 100644
--- a/src/plugins/e-acsl/mmodel_translate.ml
+++ b/src/plugins/e-acsl/mmodel_translate.ml
@@ -211,10 +211,10 @@ let call_memory_block ~loc kf name ctx env ptr r p =
   let size, env = match Typing.get_number_ty size_term with
     | Typing.Gmpz ->
       gmp_to_sizet ~loc kf env size_term p
-    | Typing.C_type _ ->
+    | Typing.(C_integer _ | C_float _) ->
       let size, env = term_to_exp kf env size_term in
       Cil.constFold false size, env
-    | Typing.Real | Typing.Nan ->
+    | Typing.(Rational | Real | Nan) ->
       assert false
   in
   (* base and base_addr *)
diff --git a/src/plugins/e-acsl/quantif.ml b/src/plugins/e-acsl/quantif.ml
index a1ae19acb6cf7623ae26e635d9857f1daf17ec7b..58dad26a6507d6b4025b464c686275835153f8c3 100644
--- a/src/plugins/e-acsl/quantif.ml
+++ b/src/plugins/e-acsl/quantif.ml
@@ -113,25 +113,21 @@ let rec has_empty_quantif_with_false_negative = function
     (* case 2 *)
     false
   | (t1, rel1, _, rel2, t2) :: guards ->
-    try
-      let i1 = Interval.infer t1 in
-      let i2 = Interval.infer t2 in
-      let lower_bound, _ = Ival.min_and_max i1 in
-      let _, upper_bound = Ival.min_and_max i2 in
-      match lower_bound, upper_bound with
-      | Some lower_bound, Some upper_bound ->
-        let res = match rel1, rel2 with
-          | Rle, Rle -> lower_bound > upper_bound
-          | Rle, Rlt | Rlt, Rle -> lower_bound >= upper_bound
-          | Rlt, Rlt -> lower_bound >= Z.sub upper_bound Z.one
-          | _ -> assert false
-        in
-        res (* case 1 *) || has_empty_quantif_with_false_negative guards
-      | None, _ | _, None ->
-        has_empty_quantif_with_false_negative guards
-    with
-    | Interval.Not_a_number -> assert false
-    | Interval.Is_a_real -> Error.not_yet "quantification over real numbers"
+    let iv1 = Interval.(extract_ival (infer t1)) in
+    let iv2 = Interval.(extract_ival (infer t2)) in
+    let lower_bound, _ = Ival.min_and_max iv1 in
+    let _, upper_bound = Ival.min_and_max iv2 in
+    match lower_bound, upper_bound with
+    | Some lower_bound, Some upper_bound ->
+      let res = match rel1, rel2 with
+        | Rle, Rle -> lower_bound > upper_bound
+        | Rle, Rlt | Rlt, Rle -> lower_bound >= upper_bound
+        | Rlt, Rlt -> lower_bound >= Z.sub upper_bound Z.one
+        | _ -> assert false
+      in
+      res (* case 1 *) || has_empty_quantif_with_false_negative guards
+    | None, _ | _, None ->
+      has_empty_quantif_with_false_negative guards
 
 let () = Typing.compute_quantif_guards_ref := compute_quantif_guards
 
diff --git a/src/plugins/e-acsl/tests/bts/oracle/gen_bts1307.c b/src/plugins/e-acsl/tests/bts/oracle/gen_bts1307.c
index efbf831c0e626b5573f733d25e2ca2b6fa140bd0..c5ca246ce62c926a23616be2649c675d0a121fcf 100644
--- a/src/plugins/e-acsl/tests/bts/oracle/gen_bts1307.c
+++ b/src/plugins/e-acsl/tests/bts/oracle/gen_bts1307.c
@@ -126,79 +126,81 @@ void __gen_e_acsl_bar(float *Mtmin_in, float *Mwmin, float *Mtmin_out)
   }
   bar(Mtmin_in,Mwmin,Mtmin_out);
   {
-    __e_acsl_mpq_t __gen_e_acsl_;
-    __e_acsl_mpq_t __gen_e_acsl__2;
-    int __gen_e_acsl_eq;
+    int __gen_e_acsl_valid_read;
+    int __gen_e_acsl_valid_read_2;
     int __gen_e_acsl_and;
     int __gen_e_acsl_if;
-    __gmpq_init(__gen_e_acsl_);
-    __gmpq_set_d(__gen_e_acsl_,(double)*__gen_e_acsl_at);
-    __gmpq_init(__gen_e_acsl__2);
-    __gmpq_set_d(__gen_e_acsl__2,(double)*__gen_e_acsl_at_2);
-    __gen_e_acsl_eq = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl_),
-                                 (__e_acsl_mpq_struct const *)(__gen_e_acsl__2));
-    if (__gen_e_acsl_eq == 0) {
-      __e_acsl_mpq_t __gen_e_acsl__3;
-      __e_acsl_mpq_t __gen_e_acsl__4;
+    __gen_e_acsl_valid_read = __e_acsl_valid_read((void *)__gen_e_acsl_at_2,
+                                                  sizeof(float),
+                                                  (void *)__gen_e_acsl_at_2,
+                                                  (void *)(& __gen_e_acsl_at_2));
+    __e_acsl_assert(__gen_e_acsl_valid_read,(char *)"RTE",(char *)"bar",
+                    (char *)"mem_access: \\valid_read(__gen_e_acsl_at_2)",26);
+    __gen_e_acsl_valid_read_2 = __e_acsl_valid_read((void *)__gen_e_acsl_at,
+                                                    sizeof(float),
+                                                    (void *)__gen_e_acsl_at,
+                                                    (void *)(& __gen_e_acsl_at));
+    __e_acsl_assert(__gen_e_acsl_valid_read_2,(char *)"RTE",(char *)"bar",
+                    (char *)"mem_access: \\valid_read(__gen_e_acsl_at)",26);
+    if (*__gen_e_acsl_at == *__gen_e_acsl_at_2) {
+      __e_acsl_mpq_t __gen_e_acsl_;
+      __e_acsl_mpq_t __gen_e_acsl__2;
       __e_acsl_mpq_t __gen_e_acsl_mul;
-      __e_acsl_mpq_t __gen_e_acsl__5;
+      __e_acsl_mpq_t __gen_e_acsl__3;
       int __gen_e_acsl_lt;
-      __gmpq_init(__gen_e_acsl__3);
-      __gmpq_set_str(__gen_e_acsl__3,"085/100",10);
-      __gmpq_init(__gen_e_acsl__4);
-      __gmpq_set_d(__gen_e_acsl__4,(double)*__gen_e_acsl_at_4);
+      __gmpq_init(__gen_e_acsl_);
+      __gmpq_set_str(__gen_e_acsl_,"085/100",10);
+      __gmpq_init(__gen_e_acsl__2);
+      __gmpq_set_d(__gen_e_acsl__2,(double)*__gen_e_acsl_at_4);
       __gmpq_init(__gen_e_acsl_mul);
       __gmpq_mul(__gen_e_acsl_mul,
-                 (__e_acsl_mpq_struct const *)(__gen_e_acsl__3),
-                 (__e_acsl_mpq_struct const *)(__gen_e_acsl__4));
-      __gmpq_init(__gen_e_acsl__5);
-      __gmpq_set_d(__gen_e_acsl__5,(double)*__gen_e_acsl_at_3);
-      __gen_e_acsl_lt = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl__5),
+                 (__e_acsl_mpq_struct const *)(__gen_e_acsl_),
+                 (__e_acsl_mpq_struct const *)(__gen_e_acsl__2));
+      __gmpq_init(__gen_e_acsl__3);
+      __gmpq_set_d(__gen_e_acsl__3,(double)*__gen_e_acsl_at_3);
+      __gen_e_acsl_lt = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl__3),
                                    (__e_acsl_mpq_struct const *)(__gen_e_acsl_mul));
       __gen_e_acsl_and = __gen_e_acsl_lt < 0;
-      __gmpq_clear(__gen_e_acsl__3);
-      __gmpq_clear(__gen_e_acsl__4);
+      __gmpq_clear(__gen_e_acsl_);
+      __gmpq_clear(__gen_e_acsl__2);
       __gmpq_clear(__gen_e_acsl_mul);
-      __gmpq_clear(__gen_e_acsl__5);
+      __gmpq_clear(__gen_e_acsl__3);
     }
     else __gen_e_acsl_and = 0;
     if (__gen_e_acsl_and) {
-      __e_acsl_mpq_t __gen_e_acsl__6;
-      __e_acsl_mpq_t __gen_e_acsl__7;
-      int __gen_e_acsl_ne;
-      __gmpq_init(__gen_e_acsl__6);
-      __gmpq_set_str(__gen_e_acsl__6,"0/1",10);
-      __gmpq_init(__gen_e_acsl__7);
-      __gmpq_set_d(__gen_e_acsl__7,(double)*__gen_e_acsl_at_5);
-      __gen_e_acsl_ne = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl__7),
-                                   (__e_acsl_mpq_struct const *)(__gen_e_acsl__6));
-      __gen_e_acsl_if = __gen_e_acsl_ne != 0;
-      __gmpq_clear(__gen_e_acsl__6);
-      __gmpq_clear(__gen_e_acsl__7);
+      int __gen_e_acsl_valid_read_3;
+      __gen_e_acsl_valid_read_3 = __e_acsl_valid_read((void *)__gen_e_acsl_at_5,
+                                                      sizeof(float),
+                                                      (void *)__gen_e_acsl_at_5,
+                                                      (void *)(& __gen_e_acsl_at_5));
+      __e_acsl_assert(__gen_e_acsl_valid_read_3,(char *)"RTE",(char *)"bar",
+                      (char *)"mem_access: \\valid_read(__gen_e_acsl_at_5)",
+                      26);
+      __gen_e_acsl_if = (double)*__gen_e_acsl_at_5 != 0.;
     }
     else {
-      __e_acsl_mpq_t __gen_e_acsl__8;
-      __e_acsl_mpq_t __gen_e_acsl__9;
+      __e_acsl_mpq_t __gen_e_acsl__4;
+      __e_acsl_mpq_t __gen_e_acsl__5;
       __e_acsl_mpq_t __gen_e_acsl_mul_2;
-      __e_acsl_mpq_t __gen_e_acsl__10;
-      int __gen_e_acsl_ne_2;
-      __gmpq_init(__gen_e_acsl__8);
-      __gmpq_set_str(__gen_e_acsl__8,"085/100",10);
-      __gmpq_init(__gen_e_acsl__9);
-      __gmpq_set_d(__gen_e_acsl__9,(double)*__gen_e_acsl_at_6);
+      __e_acsl_mpq_t __gen_e_acsl__6;
+      int __gen_e_acsl_ne;
+      __gmpq_init(__gen_e_acsl__4);
+      __gmpq_set_str(__gen_e_acsl__4,"085/100",10);
+      __gmpq_init(__gen_e_acsl__5);
+      __gmpq_set_d(__gen_e_acsl__5,(double)*__gen_e_acsl_at_6);
       __gmpq_init(__gen_e_acsl_mul_2);
       __gmpq_mul(__gen_e_acsl_mul_2,
-                 (__e_acsl_mpq_struct const *)(__gen_e_acsl__8),
-                 (__e_acsl_mpq_struct const *)(__gen_e_acsl__9));
-      __gmpq_init(__gen_e_acsl__10);
-      __gmpq_set_str(__gen_e_acsl__10,"0/1",10);
-      __gen_e_acsl_ne_2 = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl_mul_2),
-                                     (__e_acsl_mpq_struct const *)(__gen_e_acsl__10));
-      __gen_e_acsl_if = __gen_e_acsl_ne_2 != 0;
-      __gmpq_clear(__gen_e_acsl__8);
-      __gmpq_clear(__gen_e_acsl__9);
+                 (__e_acsl_mpq_struct const *)(__gen_e_acsl__4),
+                 (__e_acsl_mpq_struct const *)(__gen_e_acsl__5));
+      __gmpq_init(__gen_e_acsl__6);
+      __gmpq_set_d(__gen_e_acsl__6,0.);
+      __gen_e_acsl_ne = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl_mul_2),
+                                   (__e_acsl_mpq_struct const *)(__gen_e_acsl__6));
+      __gen_e_acsl_if = __gen_e_acsl_ne != 0;
+      __gmpq_clear(__gen_e_acsl__4);
+      __gmpq_clear(__gen_e_acsl__5);
       __gmpq_clear(__gen_e_acsl_mul_2);
-      __gmpq_clear(__gen_e_acsl__10);
+      __gmpq_clear(__gen_e_acsl__6);
     }
     __e_acsl_assert(__gen_e_acsl_if,(char *)"Postcondition",(char *)"bar",
                     (char *)"*\\old(Mtmin_out) == *\\old(Mtmin_in) < 0.85 * *\\old(Mwmin)?\n  *\\old(Mtmin_in) != 0.:\n  0.85 * *\\old(Mwmin) != 0.",
@@ -206,8 +208,6 @@ void __gen_e_acsl_bar(float *Mtmin_in, float *Mwmin, float *Mtmin_out)
     __e_acsl_delete_block((void *)(& Mtmin_out));
     __e_acsl_delete_block((void *)(& Mwmin));
     __e_acsl_delete_block((void *)(& Mtmin_in));
-    __gmpq_clear(__gen_e_acsl_);
-    __gmpq_clear(__gen_e_acsl__2);
     return;
   }
 }
diff --git a/src/plugins/e-acsl/tests/format/oracle/fprintf.res.oracle b/src/plugins/e-acsl/tests/format/oracle/fprintf.res.oracle
index 79a76e5072ff36d4a82c3117a1502245997c1ce1..603bb0736371a1433b57909d540fc680df08b111 100644
--- a/src/plugins/e-acsl/tests/format/oracle/fprintf.res.oracle
+++ b/src/plugins/e-acsl/tests/format/oracle/fprintf.res.oracle
@@ -28,7 +28,7 @@
   E-ACSL construct `assigns clause in behavior' is not yet supported.
   Ignoring annotation.
 [e-acsl] FRAMAC_SHARE/libc/stdio.h:82: Warning: 
-  E-ACSL construct `logic functions with no definition nor reads clause'
+  E-ACSL construct `predicate with no definition nor reads clause'
   is not yet supported.
   Ignoring annotation.
 [e-acsl] FRAMAC_SHARE/libc/stdio.h:82: Warning: 
diff --git a/src/plugins/e-acsl/tests/gmp/oracle/cast.1.res.oracle b/src/plugins/e-acsl/tests/gmp/oracle/cast.1.res.oracle
index 7ac62ea8423fbba17d74651d7e521c862099f2b8..33fc270fbf28281dcc2a2ae460b83b6a31648ae2 100644
--- a/src/plugins/e-acsl/tests/gmp/oracle/cast.1.res.oracle
+++ b/src/plugins/e-acsl/tests/gmp/oracle/cast.1.res.oracle
@@ -1,6 +1,7 @@
 [e-acsl] beginning translation.
 [e-acsl] tests/gmp/cast.i:23: Warning: 
-  E-ACSL construct `R to Int' is not yet supported. Ignoring annotation.
+  E-ACSL construct `reals: cast from R to Z' is not yet supported.
+  Ignoring annotation.
 [e-acsl] translation done in project "e-acsl".
 [eva] Analyzing a complete application starting at main
 [eva] Computing initial state
diff --git a/src/plugins/e-acsl/tests/gmp/oracle/gen_let.c b/src/plugins/e-acsl/tests/gmp/oracle/gen_let.c
index 09ec8b4b6a9d92bee0ab1394102ea70ad26b73e4..33945c99959a19ca4e19697417b5ab475b0bf7d6 100644
--- a/src/plugins/e-acsl/tests/gmp/oracle/gen_let.c
+++ b/src/plugins/e-acsl/tests/gmp/oracle/gen_let.c
@@ -92,19 +92,10 @@ int main(void)
   __e_acsl_full_init((void *)(& f));
   /*@ assert \let u = f; u ≡ f; */
   {
-    __e_acsl_mpq_t __gen_e_acsl_u_10;
-    __e_acsl_mpq_t __gen_e_acsl_;
-    int __gen_e_acsl_eq;
-    __gmpq_init(__gen_e_acsl_u_10);
-    __gmpq_set_d(__gen_e_acsl_u_10,(double)f);
-    __gmpq_init(__gen_e_acsl_);
-    __gmpq_set_d(__gen_e_acsl_,(double)f);
-    __gen_e_acsl_eq = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl_u_10),
-                                 (__e_acsl_mpq_struct const *)(__gen_e_acsl_));
-    __e_acsl_assert(__gen_e_acsl_eq == 0,(char *)"Assertion",(char *)"main",
-                    (char *)"\\let u = f; u == f",27);
-    __gmpq_clear(__gen_e_acsl_u_10);
-    __gmpq_clear(__gen_e_acsl_);
+    float __gen_e_acsl_u_10;
+    __gen_e_acsl_u_10 = f;
+    __e_acsl_assert(__gen_e_acsl_u_10 == f,(char *)"Assertion",
+                    (char *)"main",(char *)"\\let u = f; u == f",27);
   }
   int t[4] = {1, 2, 3, 4};
   /*@ assert \let u = &t[1]; 1 ≡ 1; */
diff --git a/src/plugins/e-acsl/tests/gmp/oracle/gen_let2.c b/src/plugins/e-acsl/tests/gmp/oracle/gen_let2.c
index d2eb693da9f9d5ebca059faf87aad3622b79fd6d..111063ef2ab67bf20e648ebee2ccb5dcfcac3202 100644
--- a/src/plugins/e-acsl/tests/gmp/oracle/gen_let2.c
+++ b/src/plugins/e-acsl/tests/gmp/oracle/gen_let2.c
@@ -206,40 +206,37 @@ int main(void)
   __e_acsl_full_init((void *)(& f));
   /*@ assert \let u = f; u ≡ f; */
   {
-    __e_acsl_mpq_t __gen_e_acsl_u_14;
-    __e_acsl_mpq_t __gen_e_acsl__10;
-    int __gen_e_acsl_eq_4;
-    __gmpq_init(__gen_e_acsl_u_14);
-    __gmpq_set_d(__gen_e_acsl_u_14,(double)f);
-    __gmpq_init(__gen_e_acsl__10);
-    __gmpq_set_d(__gen_e_acsl__10,(double)f);
-    __gen_e_acsl_eq_4 = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl_u_14),
-                                   (__e_acsl_mpq_struct const *)(__gen_e_acsl__10));
-    __e_acsl_assert(__gen_e_acsl_eq_4 == 0,(char *)"Assertion",
+    float __gen_e_acsl_u_14;
+    __gen_e_acsl_u_14 = f;
+    __e_acsl_assert(__gen_e_acsl_u_14 == f,(char *)"Assertion",
                     (char *)"main",(char *)"\\let u = f; u == f",27);
-    __gmpq_clear(__gen_e_acsl_u_14);
-    __gmpq_clear(__gen_e_acsl__10);
   }
   int t[4] = {1, 2, 3, 4};
   /*@ assert \let u = &t[1]; 1 ≡ 1; */
   {
     int * /*[4]*/ __gen_e_acsl_u_15;
-    __e_acsl_mpz_t __gen_e_acsl__11;
-    int __gen_e_acsl_eq_5;
+    __e_acsl_mpz_t __gen_e_acsl__10;
+    int __gen_e_acsl_eq_4;
     __gen_e_acsl_u_15 = & t[1];
-    __gmpz_init_set_si(__gen_e_acsl__11,1L);
-    __gen_e_acsl_eq_5 = __gmpz_cmp((__e_acsl_mpz_struct const *)(__gen_e_acsl__11),
-                                   (__e_acsl_mpz_struct const *)(__gen_e_acsl__11));
-    __e_acsl_assert(__gen_e_acsl_eq_5 == 0,(char *)"Assertion",
+    __gmpz_init_set_si(__gen_e_acsl__10,1L);
+    __gen_e_acsl_eq_4 = __gmpz_cmp((__e_acsl_mpz_struct const *)(__gen_e_acsl__10),
+                                   (__e_acsl_mpz_struct const *)(__gen_e_acsl__10));
+    __e_acsl_assert(__gen_e_acsl_eq_4 == 0,(char *)"Assertion",
                     (char *)"main",(char *)"\\let u = &t[1]; 1 == 1",30);
-    __gmpz_clear(__gen_e_acsl__11);
+    __gmpz_clear(__gen_e_acsl__10);
   }
   /*@ assert (\let u = &t[1]; 1) ≡ 1; */
   {
     int * /*[4]*/ __gen_e_acsl_u_16;
+    __e_acsl_mpz_t __gen_e_acsl__11;
+    int __gen_e_acsl_eq_5;
     __gen_e_acsl_u_16 = & t[1];
-    __e_acsl_assert(1,(char *)"Assertion",(char *)"main",
-                    (char *)"(\\let u = &t[1]; 1) == 1",32);
+    __gmpz_init_set_si(__gen_e_acsl__11,1L);
+    __gen_e_acsl_eq_5 = __gmpz_cmp((__e_acsl_mpz_struct const *)(__gen_e_acsl__11),
+                                   (__e_acsl_mpz_struct const *)(__gen_e_acsl__11));
+    __e_acsl_assert(__gen_e_acsl_eq_5 == 0,(char *)"Assertion",
+                    (char *)"main",(char *)"(\\let u = &t[1]; 1) == 1",32);
+    __gmpz_clear(__gen_e_acsl__11);
   }
   struct __anonstruct_r_1 r = {.x = 1, .y = 2};
   __e_acsl_store_block((void *)(& r),(size_t)8);
@@ -273,9 +270,18 @@ int main(void)
   /*@ assert (\let u = s; u.x) > 0; */
   {
     union __anonunion_s_2 __gen_e_acsl_u_18;
+    __e_acsl_mpz_t __gen_e_acsl__15;
+    __e_acsl_mpz_t __gen_e_acsl__16;
+    int __gen_e_acsl_gt_3;
     __gen_e_acsl_u_18 = s;
-    __e_acsl_assert(__gen_e_acsl_u_18.x > 0,(char *)"Assertion",
-                    (char *)"main",(char *)"(\\let u = s; u.x) > 0",39);
+    __gmpz_init_set_si(__gen_e_acsl__15,(long)__gen_e_acsl_u_18.x);
+    __gmpz_init_set_si(__gen_e_acsl__16,0L);
+    __gen_e_acsl_gt_3 = __gmpz_cmp((__e_acsl_mpz_struct const *)(__gen_e_acsl__15),
+                                   (__e_acsl_mpz_struct const *)(__gen_e_acsl__16));
+    __e_acsl_assert(__gen_e_acsl_gt_3 > 0,(char *)"Assertion",(char *)"main",
+                    (char *)"(\\let u = s; u.x) > 0",39);
+    __gmpz_clear(__gen_e_acsl__15);
+    __gmpz_clear(__gen_e_acsl__16);
   }
   __retres = 0;
   __e_acsl_delete_block((void *)(& r));
diff --git a/src/plugins/e-acsl/tests/gmp/oracle/gen_reals.c b/src/plugins/e-acsl/tests/gmp/oracle/gen_reals.c
index 7627bd75e465e994363437329d9248bf68129f77..3033a792d26c9d50af66c5fa15d517a101cb1fbe 100644
--- a/src/plugins/e-acsl/tests/gmp/oracle/gen_reals.c
+++ b/src/plugins/e-acsl/tests/gmp/oracle/gen_reals.c
@@ -28,7 +28,7 @@ int main(void)
     __gmpq_init(__gen_e_acsl_);
     __gmpq_set_str(__gen_e_acsl_,"3",10);
     __gmpq_init(__gen_e_acsl__2);
-    __gmpq_set_str(__gen_e_acsl__2,"15/10",10);
+    __gmpq_set_d(__gen_e_acsl__2,1.5);
     __gen_e_acsl_ne = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl_),
                                  (__e_acsl_mpq_struct const *)(__gen_e_acsl__2));
     __e_acsl_assert(__gen_e_acsl_ne != 0,(char *)"Assertion",(char *)"main",
@@ -40,151 +40,144 @@ int main(void)
   {
     __e_acsl_mpq_t __gen_e_acsl__3;
     __e_acsl_mpq_t __gen_e_acsl__4;
+    __e_acsl_mpq_t __gen_e_acsl__5;
     __e_acsl_mpq_t __gen_e_acsl_add;
     int __gen_e_acsl_eq;
     __gmpq_init(__gen_e_acsl__3);
     __gmpq_set_str(__gen_e_acsl__3,"3",10);
     __gmpq_init(__gen_e_acsl__4);
-    __gmpq_set_str(__gen_e_acsl__4,"15/10",10);
+    __gmpq_set_d(__gen_e_acsl__4,1.5);
+    __gmpq_init(__gen_e_acsl__5);
+    __gmpq_set_d(__gen_e_acsl__5,1.5);
     __gmpq_init(__gen_e_acsl_add);
     __gmpq_add(__gen_e_acsl_add,
                (__e_acsl_mpq_struct const *)(__gen_e_acsl__4),
-               (__e_acsl_mpq_struct const *)(__gen_e_acsl__4));
+               (__e_acsl_mpq_struct const *)(__gen_e_acsl__5));
     __gen_e_acsl_eq = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl__3),
                                  (__e_acsl_mpq_struct const *)(__gen_e_acsl_add));
     __e_acsl_assert(__gen_e_acsl_eq == 0,(char *)"Assertion",(char *)"main",
                     (char *)"3 == 1.5 + 1.5",15);
     __gmpq_clear(__gen_e_acsl__3);
     __gmpq_clear(__gen_e_acsl__4);
+    __gmpq_clear(__gen_e_acsl__5);
     __gmpq_clear(__gen_e_acsl_add);
   }
   /*@ assert 0.1 ≡ 0.1; */
   {
-    __e_acsl_mpq_t __gen_e_acsl__5;
+    __e_acsl_mpq_t __gen_e_acsl__6;
     int __gen_e_acsl_eq_2;
-    __gmpq_init(__gen_e_acsl__5);
-    __gmpq_set_str(__gen_e_acsl__5,"01/10",10);
-    __gen_e_acsl_eq_2 = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl__5),
-                                   (__e_acsl_mpq_struct const *)(__gen_e_acsl__5));
+    __gmpq_init(__gen_e_acsl__6);
+    __gmpq_set_str(__gen_e_acsl__6,"01/10",10);
+    __gen_e_acsl_eq_2 = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl__6),
+                                   (__e_acsl_mpq_struct const *)(__gen_e_acsl__6));
     __e_acsl_assert(__gen_e_acsl_eq_2 == 0,(char *)"Assertion",
                     (char *)"main",(char *)"0.1 == 0.1",16);
-    __gmpq_clear(__gen_e_acsl__5);
+    __gmpq_clear(__gen_e_acsl__6);
   }
   /*@ assert (double)0.1 ≢ 0.1; */
   {
-    __e_acsl_mpq_t __gen_e_acsl__6;
-    double __gen_e_acsl_cast;
     __e_acsl_mpq_t __gen_e_acsl__7;
+    double __gen_e_acsl__8;
+    __e_acsl_mpq_t __gen_e_acsl__9;
     int __gen_e_acsl_ne_2;
-    __gmpq_init(__gen_e_acsl__6);
-    __gmpq_set_str(__gen_e_acsl__6,"01/10",10);
-    __gen_e_acsl_cast = __gmpq_get_d((__e_acsl_mpq_struct const *)(__gen_e_acsl__6));
     __gmpq_init(__gen_e_acsl__7);
-    /*@ assert Eva: is_nan_or_infinite: \is_finite(__gen_e_acsl_cast); */
-    __gmpq_set_d(__gen_e_acsl__7,__gen_e_acsl_cast);
-    __gen_e_acsl_ne_2 = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl__7),
-                                   (__e_acsl_mpq_struct const *)(__gen_e_acsl__6));
+    __gmpq_set_str(__gen_e_acsl__7,"01/10",10);
+    __gen_e_acsl__8 = __gmpq_get_d((__e_acsl_mpq_struct const *)(__gen_e_acsl__7));
+    __gmpq_init(__gen_e_acsl__9);
+    /*@ assert Eva: is_nan_or_infinite: \is_finite(__gen_e_acsl__8); */
+    __gmpq_set_d(__gen_e_acsl__9,__gen_e_acsl__8);
+    __gen_e_acsl_ne_2 = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl__9),
+                                   (__e_acsl_mpq_struct const *)(__gen_e_acsl__7));
     __e_acsl_assert(__gen_e_acsl_ne_2 != 0,(char *)"Assertion",
                     (char *)"main",(char *)"(double)0.1 != 0.1",17);
-    __gmpq_clear(__gen_e_acsl__6);
     __gmpq_clear(__gen_e_acsl__7);
+    __gmpq_clear(__gen_e_acsl__9);
   }
   /*@ assert (float)0.1 ≢ (double)0.1; */
   {
-    __e_acsl_mpq_t __gen_e_acsl__8;
-    double __gen_e_acsl_cast_2;
-    double __gen_e_acsl_cast_3;
-    __e_acsl_mpq_t __gen_e_acsl__9;
     __e_acsl_mpq_t __gen_e_acsl__10;
-    int __gen_e_acsl_ne_3;
-    __gmpq_init(__gen_e_acsl__8);
-    __gmpq_set_str(__gen_e_acsl__8,"01/10",10);
-    __gen_e_acsl_cast_2 = __gmpq_get_d((__e_acsl_mpq_struct const *)(__gen_e_acsl__8));
-    __gen_e_acsl_cast_3 = __gmpq_get_d((__e_acsl_mpq_struct const *)(__gen_e_acsl__8));
-    __gmpq_init(__gen_e_acsl__9);
-    /*@ assert Eva: is_nan_or_infinite: \is_finite(__gen_e_acsl_cast_2); */
-    /*@ assert
-        Eva: is_nan_or_infinite: \is_finite((float)__gen_e_acsl_cast_2);
-    */
-    __gmpq_set_d(__gen_e_acsl__9,(double)((float)__gen_e_acsl_cast_2));
+    double __gen_e_acsl__11;
+    double __gen_e_acsl__12;
     __gmpq_init(__gen_e_acsl__10);
-    /*@ assert Eva: is_nan_or_infinite: \is_finite(__gen_e_acsl_cast_3); */
-    __gmpq_set_d(__gen_e_acsl__10,__gen_e_acsl_cast_3);
-    __gen_e_acsl_ne_3 = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl__9),
-                                   (__e_acsl_mpq_struct const *)(__gen_e_acsl__10));
-    __e_acsl_assert(__gen_e_acsl_ne_3 != 0,(char *)"Assertion",
-                    (char *)"main",(char *)"(float)0.1 != (double)0.1",18);
-    __gmpq_clear(__gen_e_acsl__8);
-    __gmpq_clear(__gen_e_acsl__9);
+    __gmpq_set_str(__gen_e_acsl__10,"01/10",10);
+    __gen_e_acsl__11 = __gmpq_get_d((__e_acsl_mpq_struct const *)(__gen_e_acsl__10));
+    __gen_e_acsl__12 = __gmpq_get_d((__e_acsl_mpq_struct const *)(__gen_e_acsl__10));
+    /*@ assert Eva: is_nan_or_infinite: \is_finite(__gen_e_acsl__11); */
+    /*@ assert Eva: is_nan_or_infinite: \is_finite(__gen_e_acsl__12); */
+    /*@ assert Eva: is_nan_or_infinite: \is_finite((float)__gen_e_acsl__11);
+    */
+    __e_acsl_assert((double)((float)__gen_e_acsl__11) != __gen_e_acsl__12,
+                    (char *)"Assertion",(char *)"main",
+                    (char *)"(float)0.1 != (double)0.1",18);
     __gmpq_clear(__gen_e_acsl__10);
   }
   /*@ assert (double)1.1 ≢ 1 + 0.1; */
   {
-    __e_acsl_mpq_t __gen_e_acsl__11;
-    double __gen_e_acsl_cast_4;
-    __e_acsl_mpq_t __gen_e_acsl__12;
     __e_acsl_mpq_t __gen_e_acsl__13;
+    double __gen_e_acsl__14;
+    __e_acsl_mpq_t __gen_e_acsl__15;
+    __e_acsl_mpq_t __gen_e_acsl__16;
     __e_acsl_mpq_t __gen_e_acsl_add_2;
-    __e_acsl_mpq_t __gen_e_acsl__14;
-    int __gen_e_acsl_ne_4;
-    __gmpq_init(__gen_e_acsl__11);
-    __gmpq_set_str(__gen_e_acsl__11,"11/10",10);
-    __gen_e_acsl_cast_4 = __gmpq_get_d((__e_acsl_mpq_struct const *)(__gen_e_acsl__11));
-    __gmpq_init(__gen_e_acsl__12);
-    __gmpq_set_str(__gen_e_acsl__12,"1",10);
+    __e_acsl_mpq_t __gen_e_acsl__17;
+    int __gen_e_acsl_ne_3;
     __gmpq_init(__gen_e_acsl__13);
-    __gmpq_set_str(__gen_e_acsl__13,"01/10",10);
+    __gmpq_set_str(__gen_e_acsl__13,"11/10",10);
+    __gen_e_acsl__14 = __gmpq_get_d((__e_acsl_mpq_struct const *)(__gen_e_acsl__13));
+    __gmpq_init(__gen_e_acsl__15);
+    __gmpq_set_str(__gen_e_acsl__15,"1",10);
+    __gmpq_init(__gen_e_acsl__16);
+    __gmpq_set_str(__gen_e_acsl__16,"01/10",10);
     __gmpq_init(__gen_e_acsl_add_2);
     __gmpq_add(__gen_e_acsl_add_2,
-               (__e_acsl_mpq_struct const *)(__gen_e_acsl__12),
-               (__e_acsl_mpq_struct const *)(__gen_e_acsl__13));
-    __gmpq_init(__gen_e_acsl__14);
-    /*@ assert Eva: is_nan_or_infinite: \is_finite(__gen_e_acsl_cast_4); */
-    __gmpq_set_d(__gen_e_acsl__14,__gen_e_acsl_cast_4);
-    __gen_e_acsl_ne_4 = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl__14),
+               (__e_acsl_mpq_struct const *)(__gen_e_acsl__15),
+               (__e_acsl_mpq_struct const *)(__gen_e_acsl__16));
+    __gmpq_init(__gen_e_acsl__17);
+    /*@ assert Eva: is_nan_or_infinite: \is_finite(__gen_e_acsl__14); */
+    __gmpq_set_d(__gen_e_acsl__17,__gen_e_acsl__14);
+    __gen_e_acsl_ne_3 = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl__17),
                                    (__e_acsl_mpq_struct const *)(__gen_e_acsl_add_2));
-    __e_acsl_assert(__gen_e_acsl_ne_4 != 0,(char *)"Assertion",
+    __e_acsl_assert(__gen_e_acsl_ne_3 != 0,(char *)"Assertion",
                     (char *)"main",(char *)"(double)1.1 != 1 + 0.1",19);
-    __gmpq_clear(__gen_e_acsl__11);
-    __gmpq_clear(__gen_e_acsl__12);
     __gmpq_clear(__gen_e_acsl__13);
+    __gmpq_clear(__gen_e_acsl__15);
+    __gmpq_clear(__gen_e_acsl__16);
     __gmpq_clear(__gen_e_acsl_add_2);
-    __gmpq_clear(__gen_e_acsl__14);
+    __gmpq_clear(__gen_e_acsl__17);
   }
   /*@ assert 1 + 0.1 ≡ 2 - 0.9; */
   {
-    __e_acsl_mpq_t __gen_e_acsl__15;
-    __e_acsl_mpq_t __gen_e_acsl__16;
-    __e_acsl_mpq_t __gen_e_acsl_add_3;
-    __e_acsl_mpq_t __gen_e_acsl__17;
     __e_acsl_mpq_t __gen_e_acsl__18;
+    __e_acsl_mpq_t __gen_e_acsl__19;
+    __e_acsl_mpq_t __gen_e_acsl_add_3;
+    __e_acsl_mpq_t __gen_e_acsl__20;
+    __e_acsl_mpq_t __gen_e_acsl__21;
     __e_acsl_mpq_t __gen_e_acsl_sub;
     int __gen_e_acsl_eq_3;
-    __gmpq_init(__gen_e_acsl__15);
-    __gmpq_set_str(__gen_e_acsl__15,"1",10);
-    __gmpq_init(__gen_e_acsl__16);
-    __gmpq_set_str(__gen_e_acsl__16,"01/10",10);
+    __gmpq_init(__gen_e_acsl__18);
+    __gmpq_set_str(__gen_e_acsl__18,"1",10);
+    __gmpq_init(__gen_e_acsl__19);
+    __gmpq_set_str(__gen_e_acsl__19,"01/10",10);
     __gmpq_init(__gen_e_acsl_add_3);
     __gmpq_add(__gen_e_acsl_add_3,
-               (__e_acsl_mpq_struct const *)(__gen_e_acsl__15),
-               (__e_acsl_mpq_struct const *)(__gen_e_acsl__16));
-    __gmpq_init(__gen_e_acsl__17);
-    __gmpq_set_str(__gen_e_acsl__17,"2",10);
-    __gmpq_init(__gen_e_acsl__18);
-    __gmpq_set_str(__gen_e_acsl__18,"09/10",10);
+               (__e_acsl_mpq_struct const *)(__gen_e_acsl__18),
+               (__e_acsl_mpq_struct const *)(__gen_e_acsl__19));
+    __gmpq_init(__gen_e_acsl__20);
+    __gmpq_set_str(__gen_e_acsl__20,"2",10);
+    __gmpq_init(__gen_e_acsl__21);
+    __gmpq_set_str(__gen_e_acsl__21,"09/10",10);
     __gmpq_init(__gen_e_acsl_sub);
     __gmpq_sub(__gen_e_acsl_sub,
-               (__e_acsl_mpq_struct const *)(__gen_e_acsl__17),
-               (__e_acsl_mpq_struct const *)(__gen_e_acsl__18));
+               (__e_acsl_mpq_struct const *)(__gen_e_acsl__20),
+               (__e_acsl_mpq_struct const *)(__gen_e_acsl__21));
     __gen_e_acsl_eq_3 = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl_add_3),
                                    (__e_acsl_mpq_struct const *)(__gen_e_acsl_sub));
     __e_acsl_assert(__gen_e_acsl_eq_3 == 0,(char *)"Assertion",
                     (char *)"main",(char *)"1 + 0.1 == 2 - 0.9",20);
-    __gmpq_clear(__gen_e_acsl__15);
-    __gmpq_clear(__gen_e_acsl__16);
-    __gmpq_clear(__gen_e_acsl_add_3);
-    __gmpq_clear(__gen_e_acsl__17);
     __gmpq_clear(__gen_e_acsl__18);
+    __gmpq_clear(__gen_e_acsl__19);
+    __gmpq_clear(__gen_e_acsl_add_3);
+    __gmpq_clear(__gen_e_acsl__20);
+    __gmpq_clear(__gen_e_acsl__21);
     __gmpq_clear(__gen_e_acsl_sub);
   }
   float x = 0.2f;
@@ -193,84 +186,84 @@ int main(void)
   /*@ assert sum ≢ x * y; */
   {
     __e_acsl_mpq_t __gen_e_acsl_y;
-    __e_acsl_mpq_t __gen_e_acsl__19;
+    __e_acsl_mpq_t __gen_e_acsl__22;
     __e_acsl_mpq_t __gen_e_acsl_mul;
-    __e_acsl_mpq_t __gen_e_acsl__20;
-    int __gen_e_acsl_ne_5;
+    __e_acsl_mpq_t __gen_e_acsl__23;
+    int __gen_e_acsl_ne_4;
     __gmpq_init(__gen_e_acsl_y);
     __gmpq_set_d(__gen_e_acsl_y,(double)y);
-    __gmpq_init(__gen_e_acsl__19);
-    __gmpq_set_d(__gen_e_acsl__19,(double)x);
+    __gmpq_init(__gen_e_acsl__22);
+    __gmpq_set_d(__gen_e_acsl__22,(double)x);
     __gmpq_init(__gen_e_acsl_mul);
     __gmpq_mul(__gen_e_acsl_mul,
-               (__e_acsl_mpq_struct const *)(__gen_e_acsl__19),
+               (__e_acsl_mpq_struct const *)(__gen_e_acsl__22),
                (__e_acsl_mpq_struct const *)(__gen_e_acsl_y));
-    __gmpq_init(__gen_e_acsl__20);
-    __gmpq_set_d(__gen_e_acsl__20,(double)sum);
-    __gen_e_acsl_ne_5 = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl__20),
+    __gmpq_init(__gen_e_acsl__23);
+    __gmpq_set_d(__gen_e_acsl__23,(double)sum);
+    __gen_e_acsl_ne_4 = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl__23),
                                    (__e_acsl_mpq_struct const *)(__gen_e_acsl_mul));
-    __e_acsl_assert(__gen_e_acsl_ne_5 != 0,(char *)"Assertion",
+    __e_acsl_assert(__gen_e_acsl_ne_4 != 0,(char *)"Assertion",
                     (char *)"main",(char *)"sum != x * y",24);
     __gmpq_clear(__gen_e_acsl_y);
-    __gmpq_clear(__gen_e_acsl__19);
+    __gmpq_clear(__gen_e_acsl__22);
     __gmpq_clear(__gen_e_acsl_mul);
-    __gmpq_clear(__gen_e_acsl__20);
+    __gmpq_clear(__gen_e_acsl__23);
   }
   /*@ assert \let n = 1; 4 ≡ n + 3.0; */
   {
     int __gen_e_acsl_n;
-    __e_acsl_mpq_t __gen_e_acsl__21;
-    __e_acsl_mpq_t __gen_e_acsl__22;
-    __e_acsl_mpq_t __gen_e_acsl__23;
+    __e_acsl_mpq_t __gen_e_acsl__24;
+    __e_acsl_mpq_t __gen_e_acsl__25;
+    __e_acsl_mpq_t __gen_e_acsl__26;
     __e_acsl_mpq_t __gen_e_acsl_add_4;
     int __gen_e_acsl_eq_4;
     __gen_e_acsl_n = 1;
-    __gmpq_init(__gen_e_acsl__21);
-    __gmpq_set_str(__gen_e_acsl__21,"4",10);
-    __gmpq_init(__gen_e_acsl__22);
-    __gmpq_set_str(__gen_e_acsl__22,"30/10",10);
-    __gmpq_init(__gen_e_acsl__23);
-    __gmpq_set_si(__gen_e_acsl__23,(long)__gen_e_acsl_n);
+    __gmpq_init(__gen_e_acsl__24);
+    __gmpq_set_str(__gen_e_acsl__24,"4",10);
+    __gmpq_init(__gen_e_acsl__25);
+    __gmpq_set_d(__gen_e_acsl__25,3.);
+    __gmpq_init(__gen_e_acsl__26);
+    __gmpq_set_si(__gen_e_acsl__26,(long)__gen_e_acsl_n);
     __gmpq_init(__gen_e_acsl_add_4);
     __gmpq_add(__gen_e_acsl_add_4,
-               (__e_acsl_mpq_struct const *)(__gen_e_acsl__23),
-               (__e_acsl_mpq_struct const *)(__gen_e_acsl__22));
-    __gen_e_acsl_eq_4 = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl__21),
+               (__e_acsl_mpq_struct const *)(__gen_e_acsl__26),
+               (__e_acsl_mpq_struct const *)(__gen_e_acsl__25));
+    __gen_e_acsl_eq_4 = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl__24),
                                    (__e_acsl_mpq_struct const *)(__gen_e_acsl_add_4));
     __e_acsl_assert(__gen_e_acsl_eq_4 == 0,(char *)"Assertion",
                     (char *)"main",(char *)"\\let n = 1; 4 == n + 3.0",25);
-    __gmpq_clear(__gen_e_acsl__21);
-    __gmpq_clear(__gen_e_acsl__22);
-    __gmpq_clear(__gen_e_acsl__23);
+    __gmpq_clear(__gen_e_acsl__24);
+    __gmpq_clear(__gen_e_acsl__25);
+    __gmpq_clear(__gen_e_acsl__26);
     __gmpq_clear(__gen_e_acsl_add_4);
   }
   double d = 0.1;
   __gen_e_acsl_avg(4.3,11.7);
   /*@ assert 1.1d ≢ 1 + 0.1; */
   {
-    __e_acsl_mpq_t __gen_e_acsl__24;
-    __e_acsl_mpq_t __gen_e_acsl__25;
-    __e_acsl_mpq_t __gen_e_acsl__26;
+    __e_acsl_mpq_t __gen_e_acsl__27;
+    __e_acsl_mpq_t __gen_e_acsl__28;
     __e_acsl_mpq_t __gen_e_acsl_add_5;
-    int __gen_e_acsl_ne_6;
-    __gmpq_init(__gen_e_acsl__24);
-    __gmpq_set_str(__gen_e_acsl__24,"1.1d",10);
-    __gmpq_init(__gen_e_acsl__25);
-    __gmpq_set_str(__gen_e_acsl__25,"1",10);
-    __gmpq_init(__gen_e_acsl__26);
-    __gmpq_set_str(__gen_e_acsl__26,"01/10",10);
+    __e_acsl_mpq_t __gen_e_acsl__29;
+    int __gen_e_acsl_ne_5;
+    __gmpq_init(__gen_e_acsl__27);
+    __gmpq_set_str(__gen_e_acsl__27,"1",10);
+    __gmpq_init(__gen_e_acsl__28);
+    __gmpq_set_str(__gen_e_acsl__28,"01/10",10);
     __gmpq_init(__gen_e_acsl_add_5);
     __gmpq_add(__gen_e_acsl_add_5,
-               (__e_acsl_mpq_struct const *)(__gen_e_acsl__25),
-               (__e_acsl_mpq_struct const *)(__gen_e_acsl__26));
-    __gen_e_acsl_ne_6 = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl__24),
+               (__e_acsl_mpq_struct const *)(__gen_e_acsl__27),
+               (__e_acsl_mpq_struct const *)(__gen_e_acsl__28));
+    __gmpq_init(__gen_e_acsl__29);
+    __gmpq_set_d(__gen_e_acsl__29,1.1);
+    __gen_e_acsl_ne_5 = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl__29),
                                    (__e_acsl_mpq_struct const *)(__gen_e_acsl_add_5));
-    __e_acsl_assert(__gen_e_acsl_ne_6 != 0,(char *)"Assertion",
+    __e_acsl_assert(__gen_e_acsl_ne_5 != 0,(char *)"Assertion",
                     (char *)"main",(char *)"1.1d != 1 + 0.1",31);
-    __gmpq_clear(__gen_e_acsl__24);
-    __gmpq_clear(__gen_e_acsl__25);
-    __gmpq_clear(__gen_e_acsl__26);
+    __gmpq_clear(__gen_e_acsl__27);
+    __gmpq_clear(__gen_e_acsl__28);
     __gmpq_clear(__gen_e_acsl_add_5);
+    __gmpq_clear(__gen_e_acsl__29);
   }
   __retres = 0;
   return __retres;
diff --git a/src/plugins/e-acsl/tests/gmp/oracle/gen_reals2.c b/src/plugins/e-acsl/tests/gmp/oracle/gen_reals2.c
index 7627bd75e465e994363437329d9248bf68129f77..3033a792d26c9d50af66c5fa15d517a101cb1fbe 100644
--- a/src/plugins/e-acsl/tests/gmp/oracle/gen_reals2.c
+++ b/src/plugins/e-acsl/tests/gmp/oracle/gen_reals2.c
@@ -28,7 +28,7 @@ int main(void)
     __gmpq_init(__gen_e_acsl_);
     __gmpq_set_str(__gen_e_acsl_,"3",10);
     __gmpq_init(__gen_e_acsl__2);
-    __gmpq_set_str(__gen_e_acsl__2,"15/10",10);
+    __gmpq_set_d(__gen_e_acsl__2,1.5);
     __gen_e_acsl_ne = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl_),
                                  (__e_acsl_mpq_struct const *)(__gen_e_acsl__2));
     __e_acsl_assert(__gen_e_acsl_ne != 0,(char *)"Assertion",(char *)"main",
@@ -40,151 +40,144 @@ int main(void)
   {
     __e_acsl_mpq_t __gen_e_acsl__3;
     __e_acsl_mpq_t __gen_e_acsl__4;
+    __e_acsl_mpq_t __gen_e_acsl__5;
     __e_acsl_mpq_t __gen_e_acsl_add;
     int __gen_e_acsl_eq;
     __gmpq_init(__gen_e_acsl__3);
     __gmpq_set_str(__gen_e_acsl__3,"3",10);
     __gmpq_init(__gen_e_acsl__4);
-    __gmpq_set_str(__gen_e_acsl__4,"15/10",10);
+    __gmpq_set_d(__gen_e_acsl__4,1.5);
+    __gmpq_init(__gen_e_acsl__5);
+    __gmpq_set_d(__gen_e_acsl__5,1.5);
     __gmpq_init(__gen_e_acsl_add);
     __gmpq_add(__gen_e_acsl_add,
                (__e_acsl_mpq_struct const *)(__gen_e_acsl__4),
-               (__e_acsl_mpq_struct const *)(__gen_e_acsl__4));
+               (__e_acsl_mpq_struct const *)(__gen_e_acsl__5));
     __gen_e_acsl_eq = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl__3),
                                  (__e_acsl_mpq_struct const *)(__gen_e_acsl_add));
     __e_acsl_assert(__gen_e_acsl_eq == 0,(char *)"Assertion",(char *)"main",
                     (char *)"3 == 1.5 + 1.5",15);
     __gmpq_clear(__gen_e_acsl__3);
     __gmpq_clear(__gen_e_acsl__4);
+    __gmpq_clear(__gen_e_acsl__5);
     __gmpq_clear(__gen_e_acsl_add);
   }
   /*@ assert 0.1 ≡ 0.1; */
   {
-    __e_acsl_mpq_t __gen_e_acsl__5;
+    __e_acsl_mpq_t __gen_e_acsl__6;
     int __gen_e_acsl_eq_2;
-    __gmpq_init(__gen_e_acsl__5);
-    __gmpq_set_str(__gen_e_acsl__5,"01/10",10);
-    __gen_e_acsl_eq_2 = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl__5),
-                                   (__e_acsl_mpq_struct const *)(__gen_e_acsl__5));
+    __gmpq_init(__gen_e_acsl__6);
+    __gmpq_set_str(__gen_e_acsl__6,"01/10",10);
+    __gen_e_acsl_eq_2 = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl__6),
+                                   (__e_acsl_mpq_struct const *)(__gen_e_acsl__6));
     __e_acsl_assert(__gen_e_acsl_eq_2 == 0,(char *)"Assertion",
                     (char *)"main",(char *)"0.1 == 0.1",16);
-    __gmpq_clear(__gen_e_acsl__5);
+    __gmpq_clear(__gen_e_acsl__6);
   }
   /*@ assert (double)0.1 ≢ 0.1; */
   {
-    __e_acsl_mpq_t __gen_e_acsl__6;
-    double __gen_e_acsl_cast;
     __e_acsl_mpq_t __gen_e_acsl__7;
+    double __gen_e_acsl__8;
+    __e_acsl_mpq_t __gen_e_acsl__9;
     int __gen_e_acsl_ne_2;
-    __gmpq_init(__gen_e_acsl__6);
-    __gmpq_set_str(__gen_e_acsl__6,"01/10",10);
-    __gen_e_acsl_cast = __gmpq_get_d((__e_acsl_mpq_struct const *)(__gen_e_acsl__6));
     __gmpq_init(__gen_e_acsl__7);
-    /*@ assert Eva: is_nan_or_infinite: \is_finite(__gen_e_acsl_cast); */
-    __gmpq_set_d(__gen_e_acsl__7,__gen_e_acsl_cast);
-    __gen_e_acsl_ne_2 = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl__7),
-                                   (__e_acsl_mpq_struct const *)(__gen_e_acsl__6));
+    __gmpq_set_str(__gen_e_acsl__7,"01/10",10);
+    __gen_e_acsl__8 = __gmpq_get_d((__e_acsl_mpq_struct const *)(__gen_e_acsl__7));
+    __gmpq_init(__gen_e_acsl__9);
+    /*@ assert Eva: is_nan_or_infinite: \is_finite(__gen_e_acsl__8); */
+    __gmpq_set_d(__gen_e_acsl__9,__gen_e_acsl__8);
+    __gen_e_acsl_ne_2 = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl__9),
+                                   (__e_acsl_mpq_struct const *)(__gen_e_acsl__7));
     __e_acsl_assert(__gen_e_acsl_ne_2 != 0,(char *)"Assertion",
                     (char *)"main",(char *)"(double)0.1 != 0.1",17);
-    __gmpq_clear(__gen_e_acsl__6);
     __gmpq_clear(__gen_e_acsl__7);
+    __gmpq_clear(__gen_e_acsl__9);
   }
   /*@ assert (float)0.1 ≢ (double)0.1; */
   {
-    __e_acsl_mpq_t __gen_e_acsl__8;
-    double __gen_e_acsl_cast_2;
-    double __gen_e_acsl_cast_3;
-    __e_acsl_mpq_t __gen_e_acsl__9;
     __e_acsl_mpq_t __gen_e_acsl__10;
-    int __gen_e_acsl_ne_3;
-    __gmpq_init(__gen_e_acsl__8);
-    __gmpq_set_str(__gen_e_acsl__8,"01/10",10);
-    __gen_e_acsl_cast_2 = __gmpq_get_d((__e_acsl_mpq_struct const *)(__gen_e_acsl__8));
-    __gen_e_acsl_cast_3 = __gmpq_get_d((__e_acsl_mpq_struct const *)(__gen_e_acsl__8));
-    __gmpq_init(__gen_e_acsl__9);
-    /*@ assert Eva: is_nan_or_infinite: \is_finite(__gen_e_acsl_cast_2); */
-    /*@ assert
-        Eva: is_nan_or_infinite: \is_finite((float)__gen_e_acsl_cast_2);
-    */
-    __gmpq_set_d(__gen_e_acsl__9,(double)((float)__gen_e_acsl_cast_2));
+    double __gen_e_acsl__11;
+    double __gen_e_acsl__12;
     __gmpq_init(__gen_e_acsl__10);
-    /*@ assert Eva: is_nan_or_infinite: \is_finite(__gen_e_acsl_cast_3); */
-    __gmpq_set_d(__gen_e_acsl__10,__gen_e_acsl_cast_3);
-    __gen_e_acsl_ne_3 = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl__9),
-                                   (__e_acsl_mpq_struct const *)(__gen_e_acsl__10));
-    __e_acsl_assert(__gen_e_acsl_ne_3 != 0,(char *)"Assertion",
-                    (char *)"main",(char *)"(float)0.1 != (double)0.1",18);
-    __gmpq_clear(__gen_e_acsl__8);
-    __gmpq_clear(__gen_e_acsl__9);
+    __gmpq_set_str(__gen_e_acsl__10,"01/10",10);
+    __gen_e_acsl__11 = __gmpq_get_d((__e_acsl_mpq_struct const *)(__gen_e_acsl__10));
+    __gen_e_acsl__12 = __gmpq_get_d((__e_acsl_mpq_struct const *)(__gen_e_acsl__10));
+    /*@ assert Eva: is_nan_or_infinite: \is_finite(__gen_e_acsl__11); */
+    /*@ assert Eva: is_nan_or_infinite: \is_finite(__gen_e_acsl__12); */
+    /*@ assert Eva: is_nan_or_infinite: \is_finite((float)__gen_e_acsl__11);
+    */
+    __e_acsl_assert((double)((float)__gen_e_acsl__11) != __gen_e_acsl__12,
+                    (char *)"Assertion",(char *)"main",
+                    (char *)"(float)0.1 != (double)0.1",18);
     __gmpq_clear(__gen_e_acsl__10);
   }
   /*@ assert (double)1.1 ≢ 1 + 0.1; */
   {
-    __e_acsl_mpq_t __gen_e_acsl__11;
-    double __gen_e_acsl_cast_4;
-    __e_acsl_mpq_t __gen_e_acsl__12;
     __e_acsl_mpq_t __gen_e_acsl__13;
+    double __gen_e_acsl__14;
+    __e_acsl_mpq_t __gen_e_acsl__15;
+    __e_acsl_mpq_t __gen_e_acsl__16;
     __e_acsl_mpq_t __gen_e_acsl_add_2;
-    __e_acsl_mpq_t __gen_e_acsl__14;
-    int __gen_e_acsl_ne_4;
-    __gmpq_init(__gen_e_acsl__11);
-    __gmpq_set_str(__gen_e_acsl__11,"11/10",10);
-    __gen_e_acsl_cast_4 = __gmpq_get_d((__e_acsl_mpq_struct const *)(__gen_e_acsl__11));
-    __gmpq_init(__gen_e_acsl__12);
-    __gmpq_set_str(__gen_e_acsl__12,"1",10);
+    __e_acsl_mpq_t __gen_e_acsl__17;
+    int __gen_e_acsl_ne_3;
     __gmpq_init(__gen_e_acsl__13);
-    __gmpq_set_str(__gen_e_acsl__13,"01/10",10);
+    __gmpq_set_str(__gen_e_acsl__13,"11/10",10);
+    __gen_e_acsl__14 = __gmpq_get_d((__e_acsl_mpq_struct const *)(__gen_e_acsl__13));
+    __gmpq_init(__gen_e_acsl__15);
+    __gmpq_set_str(__gen_e_acsl__15,"1",10);
+    __gmpq_init(__gen_e_acsl__16);
+    __gmpq_set_str(__gen_e_acsl__16,"01/10",10);
     __gmpq_init(__gen_e_acsl_add_2);
     __gmpq_add(__gen_e_acsl_add_2,
-               (__e_acsl_mpq_struct const *)(__gen_e_acsl__12),
-               (__e_acsl_mpq_struct const *)(__gen_e_acsl__13));
-    __gmpq_init(__gen_e_acsl__14);
-    /*@ assert Eva: is_nan_or_infinite: \is_finite(__gen_e_acsl_cast_4); */
-    __gmpq_set_d(__gen_e_acsl__14,__gen_e_acsl_cast_4);
-    __gen_e_acsl_ne_4 = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl__14),
+               (__e_acsl_mpq_struct const *)(__gen_e_acsl__15),
+               (__e_acsl_mpq_struct const *)(__gen_e_acsl__16));
+    __gmpq_init(__gen_e_acsl__17);
+    /*@ assert Eva: is_nan_or_infinite: \is_finite(__gen_e_acsl__14); */
+    __gmpq_set_d(__gen_e_acsl__17,__gen_e_acsl__14);
+    __gen_e_acsl_ne_3 = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl__17),
                                    (__e_acsl_mpq_struct const *)(__gen_e_acsl_add_2));
-    __e_acsl_assert(__gen_e_acsl_ne_4 != 0,(char *)"Assertion",
+    __e_acsl_assert(__gen_e_acsl_ne_3 != 0,(char *)"Assertion",
                     (char *)"main",(char *)"(double)1.1 != 1 + 0.1",19);
-    __gmpq_clear(__gen_e_acsl__11);
-    __gmpq_clear(__gen_e_acsl__12);
     __gmpq_clear(__gen_e_acsl__13);
+    __gmpq_clear(__gen_e_acsl__15);
+    __gmpq_clear(__gen_e_acsl__16);
     __gmpq_clear(__gen_e_acsl_add_2);
-    __gmpq_clear(__gen_e_acsl__14);
+    __gmpq_clear(__gen_e_acsl__17);
   }
   /*@ assert 1 + 0.1 ≡ 2 - 0.9; */
   {
-    __e_acsl_mpq_t __gen_e_acsl__15;
-    __e_acsl_mpq_t __gen_e_acsl__16;
-    __e_acsl_mpq_t __gen_e_acsl_add_3;
-    __e_acsl_mpq_t __gen_e_acsl__17;
     __e_acsl_mpq_t __gen_e_acsl__18;
+    __e_acsl_mpq_t __gen_e_acsl__19;
+    __e_acsl_mpq_t __gen_e_acsl_add_3;
+    __e_acsl_mpq_t __gen_e_acsl__20;
+    __e_acsl_mpq_t __gen_e_acsl__21;
     __e_acsl_mpq_t __gen_e_acsl_sub;
     int __gen_e_acsl_eq_3;
-    __gmpq_init(__gen_e_acsl__15);
-    __gmpq_set_str(__gen_e_acsl__15,"1",10);
-    __gmpq_init(__gen_e_acsl__16);
-    __gmpq_set_str(__gen_e_acsl__16,"01/10",10);
+    __gmpq_init(__gen_e_acsl__18);
+    __gmpq_set_str(__gen_e_acsl__18,"1",10);
+    __gmpq_init(__gen_e_acsl__19);
+    __gmpq_set_str(__gen_e_acsl__19,"01/10",10);
     __gmpq_init(__gen_e_acsl_add_3);
     __gmpq_add(__gen_e_acsl_add_3,
-               (__e_acsl_mpq_struct const *)(__gen_e_acsl__15),
-               (__e_acsl_mpq_struct const *)(__gen_e_acsl__16));
-    __gmpq_init(__gen_e_acsl__17);
-    __gmpq_set_str(__gen_e_acsl__17,"2",10);
-    __gmpq_init(__gen_e_acsl__18);
-    __gmpq_set_str(__gen_e_acsl__18,"09/10",10);
+               (__e_acsl_mpq_struct const *)(__gen_e_acsl__18),
+               (__e_acsl_mpq_struct const *)(__gen_e_acsl__19));
+    __gmpq_init(__gen_e_acsl__20);
+    __gmpq_set_str(__gen_e_acsl__20,"2",10);
+    __gmpq_init(__gen_e_acsl__21);
+    __gmpq_set_str(__gen_e_acsl__21,"09/10",10);
     __gmpq_init(__gen_e_acsl_sub);
     __gmpq_sub(__gen_e_acsl_sub,
-               (__e_acsl_mpq_struct const *)(__gen_e_acsl__17),
-               (__e_acsl_mpq_struct const *)(__gen_e_acsl__18));
+               (__e_acsl_mpq_struct const *)(__gen_e_acsl__20),
+               (__e_acsl_mpq_struct const *)(__gen_e_acsl__21));
     __gen_e_acsl_eq_3 = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl_add_3),
                                    (__e_acsl_mpq_struct const *)(__gen_e_acsl_sub));
     __e_acsl_assert(__gen_e_acsl_eq_3 == 0,(char *)"Assertion",
                     (char *)"main",(char *)"1 + 0.1 == 2 - 0.9",20);
-    __gmpq_clear(__gen_e_acsl__15);
-    __gmpq_clear(__gen_e_acsl__16);
-    __gmpq_clear(__gen_e_acsl_add_3);
-    __gmpq_clear(__gen_e_acsl__17);
     __gmpq_clear(__gen_e_acsl__18);
+    __gmpq_clear(__gen_e_acsl__19);
+    __gmpq_clear(__gen_e_acsl_add_3);
+    __gmpq_clear(__gen_e_acsl__20);
+    __gmpq_clear(__gen_e_acsl__21);
     __gmpq_clear(__gen_e_acsl_sub);
   }
   float x = 0.2f;
@@ -193,84 +186,84 @@ int main(void)
   /*@ assert sum ≢ x * y; */
   {
     __e_acsl_mpq_t __gen_e_acsl_y;
-    __e_acsl_mpq_t __gen_e_acsl__19;
+    __e_acsl_mpq_t __gen_e_acsl__22;
     __e_acsl_mpq_t __gen_e_acsl_mul;
-    __e_acsl_mpq_t __gen_e_acsl__20;
-    int __gen_e_acsl_ne_5;
+    __e_acsl_mpq_t __gen_e_acsl__23;
+    int __gen_e_acsl_ne_4;
     __gmpq_init(__gen_e_acsl_y);
     __gmpq_set_d(__gen_e_acsl_y,(double)y);
-    __gmpq_init(__gen_e_acsl__19);
-    __gmpq_set_d(__gen_e_acsl__19,(double)x);
+    __gmpq_init(__gen_e_acsl__22);
+    __gmpq_set_d(__gen_e_acsl__22,(double)x);
     __gmpq_init(__gen_e_acsl_mul);
     __gmpq_mul(__gen_e_acsl_mul,
-               (__e_acsl_mpq_struct const *)(__gen_e_acsl__19),
+               (__e_acsl_mpq_struct const *)(__gen_e_acsl__22),
                (__e_acsl_mpq_struct const *)(__gen_e_acsl_y));
-    __gmpq_init(__gen_e_acsl__20);
-    __gmpq_set_d(__gen_e_acsl__20,(double)sum);
-    __gen_e_acsl_ne_5 = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl__20),
+    __gmpq_init(__gen_e_acsl__23);
+    __gmpq_set_d(__gen_e_acsl__23,(double)sum);
+    __gen_e_acsl_ne_4 = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl__23),
                                    (__e_acsl_mpq_struct const *)(__gen_e_acsl_mul));
-    __e_acsl_assert(__gen_e_acsl_ne_5 != 0,(char *)"Assertion",
+    __e_acsl_assert(__gen_e_acsl_ne_4 != 0,(char *)"Assertion",
                     (char *)"main",(char *)"sum != x * y",24);
     __gmpq_clear(__gen_e_acsl_y);
-    __gmpq_clear(__gen_e_acsl__19);
+    __gmpq_clear(__gen_e_acsl__22);
     __gmpq_clear(__gen_e_acsl_mul);
-    __gmpq_clear(__gen_e_acsl__20);
+    __gmpq_clear(__gen_e_acsl__23);
   }
   /*@ assert \let n = 1; 4 ≡ n + 3.0; */
   {
     int __gen_e_acsl_n;
-    __e_acsl_mpq_t __gen_e_acsl__21;
-    __e_acsl_mpq_t __gen_e_acsl__22;
-    __e_acsl_mpq_t __gen_e_acsl__23;
+    __e_acsl_mpq_t __gen_e_acsl__24;
+    __e_acsl_mpq_t __gen_e_acsl__25;
+    __e_acsl_mpq_t __gen_e_acsl__26;
     __e_acsl_mpq_t __gen_e_acsl_add_4;
     int __gen_e_acsl_eq_4;
     __gen_e_acsl_n = 1;
-    __gmpq_init(__gen_e_acsl__21);
-    __gmpq_set_str(__gen_e_acsl__21,"4",10);
-    __gmpq_init(__gen_e_acsl__22);
-    __gmpq_set_str(__gen_e_acsl__22,"30/10",10);
-    __gmpq_init(__gen_e_acsl__23);
-    __gmpq_set_si(__gen_e_acsl__23,(long)__gen_e_acsl_n);
+    __gmpq_init(__gen_e_acsl__24);
+    __gmpq_set_str(__gen_e_acsl__24,"4",10);
+    __gmpq_init(__gen_e_acsl__25);
+    __gmpq_set_d(__gen_e_acsl__25,3.);
+    __gmpq_init(__gen_e_acsl__26);
+    __gmpq_set_si(__gen_e_acsl__26,(long)__gen_e_acsl_n);
     __gmpq_init(__gen_e_acsl_add_4);
     __gmpq_add(__gen_e_acsl_add_4,
-               (__e_acsl_mpq_struct const *)(__gen_e_acsl__23),
-               (__e_acsl_mpq_struct const *)(__gen_e_acsl__22));
-    __gen_e_acsl_eq_4 = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl__21),
+               (__e_acsl_mpq_struct const *)(__gen_e_acsl__26),
+               (__e_acsl_mpq_struct const *)(__gen_e_acsl__25));
+    __gen_e_acsl_eq_4 = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl__24),
                                    (__e_acsl_mpq_struct const *)(__gen_e_acsl_add_4));
     __e_acsl_assert(__gen_e_acsl_eq_4 == 0,(char *)"Assertion",
                     (char *)"main",(char *)"\\let n = 1; 4 == n + 3.0",25);
-    __gmpq_clear(__gen_e_acsl__21);
-    __gmpq_clear(__gen_e_acsl__22);
-    __gmpq_clear(__gen_e_acsl__23);
+    __gmpq_clear(__gen_e_acsl__24);
+    __gmpq_clear(__gen_e_acsl__25);
+    __gmpq_clear(__gen_e_acsl__26);
     __gmpq_clear(__gen_e_acsl_add_4);
   }
   double d = 0.1;
   __gen_e_acsl_avg(4.3,11.7);
   /*@ assert 1.1d ≢ 1 + 0.1; */
   {
-    __e_acsl_mpq_t __gen_e_acsl__24;
-    __e_acsl_mpq_t __gen_e_acsl__25;
-    __e_acsl_mpq_t __gen_e_acsl__26;
+    __e_acsl_mpq_t __gen_e_acsl__27;
+    __e_acsl_mpq_t __gen_e_acsl__28;
     __e_acsl_mpq_t __gen_e_acsl_add_5;
-    int __gen_e_acsl_ne_6;
-    __gmpq_init(__gen_e_acsl__24);
-    __gmpq_set_str(__gen_e_acsl__24,"1.1d",10);
-    __gmpq_init(__gen_e_acsl__25);
-    __gmpq_set_str(__gen_e_acsl__25,"1",10);
-    __gmpq_init(__gen_e_acsl__26);
-    __gmpq_set_str(__gen_e_acsl__26,"01/10",10);
+    __e_acsl_mpq_t __gen_e_acsl__29;
+    int __gen_e_acsl_ne_5;
+    __gmpq_init(__gen_e_acsl__27);
+    __gmpq_set_str(__gen_e_acsl__27,"1",10);
+    __gmpq_init(__gen_e_acsl__28);
+    __gmpq_set_str(__gen_e_acsl__28,"01/10",10);
     __gmpq_init(__gen_e_acsl_add_5);
     __gmpq_add(__gen_e_acsl_add_5,
-               (__e_acsl_mpq_struct const *)(__gen_e_acsl__25),
-               (__e_acsl_mpq_struct const *)(__gen_e_acsl__26));
-    __gen_e_acsl_ne_6 = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl__24),
+               (__e_acsl_mpq_struct const *)(__gen_e_acsl__27),
+               (__e_acsl_mpq_struct const *)(__gen_e_acsl__28));
+    __gmpq_init(__gen_e_acsl__29);
+    __gmpq_set_d(__gen_e_acsl__29,1.1);
+    __gen_e_acsl_ne_5 = __gmpq_cmp((__e_acsl_mpq_struct const *)(__gen_e_acsl__29),
                                    (__e_acsl_mpq_struct const *)(__gen_e_acsl_add_5));
-    __e_acsl_assert(__gen_e_acsl_ne_6 != 0,(char *)"Assertion",
+    __e_acsl_assert(__gen_e_acsl_ne_5 != 0,(char *)"Assertion",
                     (char *)"main",(char *)"1.1d != 1 + 0.1",31);
-    __gmpq_clear(__gen_e_acsl__24);
-    __gmpq_clear(__gen_e_acsl__25);
-    __gmpq_clear(__gen_e_acsl__26);
+    __gmpq_clear(__gen_e_acsl__27);
+    __gmpq_clear(__gen_e_acsl__28);
     __gmpq_clear(__gen_e_acsl_add_5);
+    __gmpq_clear(__gen_e_acsl__29);
   }
   __retres = 0;
   return __retres;
diff --git a/src/plugins/e-acsl/tests/gmp/oracle/let.0.res.oracle b/src/plugins/e-acsl/tests/gmp/oracle/let.0.res.oracle
index 2d54fe6c596c255b651eaa4138f31aaf691f0b6d..eb489ce6c2576da5bebb4949ba0e066c54997a77 100644
--- a/src/plugins/e-acsl/tests/gmp/oracle/let.0.res.oracle
+++ b/src/plugins/e-acsl/tests/gmp/oracle/let.0.res.oracle
@@ -35,12 +35,6 @@
 [eva] using specification for function __e_acsl_store_block
 [eva] using specification for function __e_acsl_full_init
 [eva:alarm] tests/gmp/let.c:27: Warning: assertion got status unknown.
-[eva] using specification for function __gmpq_init
-[eva] using specification for function __gmpq_set_d
-[eva] using specification for function __gmpq_cmp
-[eva:alarm] tests/gmp/let.c:27: Warning: 
-  function __e_acsl_assert: precondition got status unknown.
-[eva] using specification for function __gmpq_clear
 [eva:alarm] tests/gmp/let.c:30: Warning: assertion got status unknown.
 [eva] tests/gmp/let.c:32: 
   cannot evaluate ACSL term, unsupported ACSL construct: \let bindings
diff --git a/src/plugins/e-acsl/tests/gmp/oracle/let.1.res.oracle b/src/plugins/e-acsl/tests/gmp/oracle/let.1.res.oracle
index bbae66240bf44940b5afced7bde61c5c56967fd0..4ef2a9f67a28af8af5599e60d8657f9d7bc338a3 100644
--- a/src/plugins/e-acsl/tests/gmp/oracle/let.1.res.oracle
+++ b/src/plugins/e-acsl/tests/gmp/oracle/let.1.res.oracle
@@ -49,24 +49,22 @@
 [eva] using specification for function __e_acsl_store_block
 [eva] using specification for function __e_acsl_full_init
 [eva:alarm] tests/gmp/let.c:27: Warning: assertion got status unknown.
-[eva] using specification for function __gmpq_init
-[eva] using specification for function __gmpq_set_d
-[eva] using specification for function __gmpq_cmp
-[eva:alarm] tests/gmp/let.c:27: Warning: 
-  function __e_acsl_assert: precondition got status unknown.
-[eva] using specification for function __gmpq_clear
 [eva:alarm] tests/gmp/let.c:30: Warning: assertion got status unknown.
 [eva:alarm] tests/gmp/let.c:30: Warning: 
   function __e_acsl_assert: precondition got status unknown.
 [eva] tests/gmp/let.c:32: 
   cannot evaluate ACSL term, unsupported ACSL construct: \let bindings
 [eva:alarm] tests/gmp/let.c:32: Warning: assertion got status unknown.
+[eva:alarm] tests/gmp/let.c:32: Warning: 
+  function __e_acsl_assert: precondition got status unknown.
 [eva:alarm] tests/gmp/let.c:35: Warning: assertion got status unknown.
 [eva:alarm] tests/gmp/let.c:35: Warning: 
   function __e_acsl_assert: precondition got status unknown.
 [eva] tests/gmp/let.c:39: 
   cannot evaluate ACSL term, unsupported ACSL construct: \let bindings
 [eva:alarm] tests/gmp/let.c:39: Warning: assertion got status unknown.
+[eva:alarm] tests/gmp/let.c:39: Warning: 
+  function __e_acsl_assert: precondition got status unknown.
 [eva] using specification for function __e_acsl_delete_block
 [eva] using specification for function __e_acsl_memory_clean
 [eva] done for function main
diff --git a/src/plugins/e-acsl/tests/gmp/oracle/reals.0.res.oracle b/src/plugins/e-acsl/tests/gmp/oracle/reals.0.res.oracle
index a1a5dd8416dc57984e6502155398de1c462b9a77..c17cb20a38b2b1165d3aab40dc144b871549f964 100644
--- a/src/plugins/e-acsl/tests/gmp/oracle/reals.0.res.oracle
+++ b/src/plugins/e-acsl/tests/gmp/oracle/reals.0.res.oracle
@@ -3,6 +3,10 @@
   (warn-once: no further messages from category 'parser:decimal-float' will be emitted)
 [e-acsl] beginning translation.
 [e-acsl] Warning: R to float: double rounding might cause unsoundness
+[e-acsl] tests/gmp/reals.c:18: Warning: 
+  E-ACSL construct `predicate with no definition nor reads clause'
+  is not yet supported.
+  Ignoring annotation.
 [e-acsl] translation done in project "e-acsl".
 [eva] Analyzing a complete application starting at main
 [eva] Computing initial state
@@ -17,6 +21,7 @@
 [eva] using specification for function __e_acsl_memory_init
 [eva] using specification for function __gmpq_init
 [eva] using specification for function __gmpq_set_str
+[eva] using specification for function __gmpq_set_d
 [eva] using specification for function __gmpq_cmp
 [eva] using specification for function __e_acsl_assert
 [eva:alarm] tests/gmp/reals.c:14: Warning: 
@@ -31,21 +36,20 @@
 [eva:alarm] tests/gmp/reals.c:17: Warning: assertion got status unknown.
 [eva] using specification for function __gmpq_get_d
 [eva:alarm] tests/gmp/reals.c:17: Warning: 
-  non-finite double value. assert \is_finite(__gen_e_acsl_cast);
-[eva] using specification for function __gmpq_set_d
+  non-finite double value. assert \is_finite(__gen_e_acsl__8);
 [eva:alarm] tests/gmp/reals.c:17: Warning: 
   function __e_acsl_assert: precondition got status unknown.
 [eva:alarm] tests/gmp/reals.c:18: Warning: 
-  non-finite double value. assert \is_finite(__gen_e_acsl_cast_2);
+  non-finite double value. assert \is_finite(__gen_e_acsl__11);
 [eva:alarm] tests/gmp/reals.c:18: Warning: 
-  non-finite float value. assert \is_finite((float)__gen_e_acsl_cast_2);
+  non-finite double value. assert \is_finite(__gen_e_acsl__12);
 [eva:alarm] tests/gmp/reals.c:18: Warning: 
-  non-finite double value. assert \is_finite(__gen_e_acsl_cast_3);
+  non-finite float value. assert \is_finite((float)__gen_e_acsl__11);
 [eva:alarm] tests/gmp/reals.c:18: Warning: 
   function __e_acsl_assert: precondition got status unknown.
 [eva:alarm] tests/gmp/reals.c:19: Warning: assertion got status unknown.
 [eva:alarm] tests/gmp/reals.c:19: Warning: 
-  non-finite double value. assert \is_finite(__gen_e_acsl_cast_4);
+  non-finite double value. assert \is_finite(__gen_e_acsl__14);
 [eva:alarm] tests/gmp/reals.c:19: Warning: 
   function __e_acsl_assert: precondition got status unknown.
 [eva:alarm] tests/gmp/reals.c:20: Warning: assertion got status unknown.
diff --git a/src/plugins/e-acsl/tests/gmp/oracle/reals.1.res.oracle b/src/plugins/e-acsl/tests/gmp/oracle/reals.1.res.oracle
index a1a5dd8416dc57984e6502155398de1c462b9a77..c17cb20a38b2b1165d3aab40dc144b871549f964 100644
--- a/src/plugins/e-acsl/tests/gmp/oracle/reals.1.res.oracle
+++ b/src/plugins/e-acsl/tests/gmp/oracle/reals.1.res.oracle
@@ -3,6 +3,10 @@
   (warn-once: no further messages from category 'parser:decimal-float' will be emitted)
 [e-acsl] beginning translation.
 [e-acsl] Warning: R to float: double rounding might cause unsoundness
+[e-acsl] tests/gmp/reals.c:18: Warning: 
+  E-ACSL construct `predicate with no definition nor reads clause'
+  is not yet supported.
+  Ignoring annotation.
 [e-acsl] translation done in project "e-acsl".
 [eva] Analyzing a complete application starting at main
 [eva] Computing initial state
@@ -17,6 +21,7 @@
 [eva] using specification for function __e_acsl_memory_init
 [eva] using specification for function __gmpq_init
 [eva] using specification for function __gmpq_set_str
+[eva] using specification for function __gmpq_set_d
 [eva] using specification for function __gmpq_cmp
 [eva] using specification for function __e_acsl_assert
 [eva:alarm] tests/gmp/reals.c:14: Warning: 
@@ -31,21 +36,20 @@
 [eva:alarm] tests/gmp/reals.c:17: Warning: assertion got status unknown.
 [eva] using specification for function __gmpq_get_d
 [eva:alarm] tests/gmp/reals.c:17: Warning: 
-  non-finite double value. assert \is_finite(__gen_e_acsl_cast);
-[eva] using specification for function __gmpq_set_d
+  non-finite double value. assert \is_finite(__gen_e_acsl__8);
 [eva:alarm] tests/gmp/reals.c:17: Warning: 
   function __e_acsl_assert: precondition got status unknown.
 [eva:alarm] tests/gmp/reals.c:18: Warning: 
-  non-finite double value. assert \is_finite(__gen_e_acsl_cast_2);
+  non-finite double value. assert \is_finite(__gen_e_acsl__11);
 [eva:alarm] tests/gmp/reals.c:18: Warning: 
-  non-finite float value. assert \is_finite((float)__gen_e_acsl_cast_2);
+  non-finite double value. assert \is_finite(__gen_e_acsl__12);
 [eva:alarm] tests/gmp/reals.c:18: Warning: 
-  non-finite double value. assert \is_finite(__gen_e_acsl_cast_3);
+  non-finite float value. assert \is_finite((float)__gen_e_acsl__11);
 [eva:alarm] tests/gmp/reals.c:18: Warning: 
   function __e_acsl_assert: precondition got status unknown.
 [eva:alarm] tests/gmp/reals.c:19: Warning: assertion got status unknown.
 [eva:alarm] tests/gmp/reals.c:19: Warning: 
-  non-finite double value. assert \is_finite(__gen_e_acsl_cast_4);
+  non-finite double value. assert \is_finite(__gen_e_acsl__14);
 [eva:alarm] tests/gmp/reals.c:19: Warning: 
   function __e_acsl_assert: precondition got status unknown.
 [eva:alarm] tests/gmp/reals.c:20: Warning: assertion got status unknown.
diff --git a/src/plugins/e-acsl/translate.ml b/src/plugins/e-acsl/translate.ml
index 1aaf8e0276f7d273c2a2696e2fa0a3e96668c5bd..82de0f17f9facdd1fe5605919343de6e351ddab6 100644
--- a/src/plugins/e-acsl/translate.ml
+++ b/src/plugins/e-acsl/translate.ml
@@ -83,7 +83,6 @@ let add_cast ~loc ?name env ctx strnum t_opt e =
     e, env
   in
   let e, env = match strnum with
-    (* TODO RATIONAL: make this matching consistent *)
     | Str_Z -> mk_mpz e
     | Str_R -> Real.mk_real ~loc ?name e env t_opt
     | C_number -> e, env
@@ -149,42 +148,38 @@ let constant_to_exp ~loc t c =
   in
   match c with
   | Integer(n, _repr) ->
-    (try
-       let ity = Typing.get_number_ty t in
-       match ity with
-       | Typing.Nan ->
-         assert false
-       | Typing.Real ->
-         (* TODO RATIONAL:
-            - is it possible?
-            - why converting the integer to a string? *)
+    let ity = Typing.get_number_ty t in
+    (match ity with
+     | Typing.Nan -> assert false
+     | Typing.Real -> Error.not_yet "real number constant"
+     | Typing.Rational -> mk_real (Integer.to_string n)
+     | Typing.Gmpz ->
+       (* too large integer *)
+       Cil.mkString ~loc (Integer.to_string n), Str_Z
+     | Typing.C_float _fkind -> assert false (* TODO RATIONAL *)
+     | Typing.C_integer kind ->
+       let cast = Typing.get_cast t in
+       match cast, kind with
+       | Some ty, (ILongLong | IULongLong) when Gmp.Z.is_t ty ->
+         (* too large integer *)
+         Cil.mkString ~loc (Integer.to_string n), Str_Z
+       | Some ty, _ when Real.is_t ty ->
          mk_real (Integer.to_string n)
-       | Typing.Gmpz ->
-         raise Cil.Not_representable
-       | Typing.C_type kind ->
-         let cast = Typing.get_cast t in
-         match cast, kind with
-         (* TODO RATIONAL: why are the two first cases not the same?
-            (exception vs builder) *)
-         | Some ty, (ILongLong | IULongLong) when Gmp.Z.is_t ty ->
-           raise Cil.Not_representable
-         | Some ty, (ILongLong | IULongLong) when Real.is_t ty ->
-           mk_real (Integer.to_string n)
-         | (None | Some _), _ ->
-           (* do not keep the initial string representation because the
-              generated constant must reflect its type computed by the type
-              system. For instance, when translating [INT_MAX+1], we must
-              generate a [long long] addition and so [1LL]. If we keep the
-              initial string representation, the kind would be ignored in the
-              generated code and so [1] would be generated. *)
-           Cil.kinteger64 ~loc ~kind n, C_number
-     with Cil.Not_representable ->
-       (* too big integer *)
-       Cil.mkString ~loc (Integer.to_string n), Str_Z)
+       | (None | Some _), _ ->
+         (* do not keep the initial string representation because the generated
+            constant must reflect its type computed by the type system. For
+            instance, when translating [INT_MAX+1], we must generate a [long
+            long] addition and so [1LL]. If we keep the initial string
+            representation, the kind would be ignored in the generated code and
+            so [1] would be generated. *)
+         Cil.kinteger64 ~loc ~kind n, C_number)
   | LStr s -> Cil.new_exp ~loc (Const (CStr s)), C_number
   | LWStr s -> Cil.new_exp ~loc (Const (CWStr s)), C_number
   | LChr c -> Cil.new_exp ~loc (Const (CChr c)), C_number
-  | LReal {r_literal=s; r_nearest=_; r_lower=_; r_upper=_} -> mk_real s
+  | LReal lr ->
+    if lr.r_lower = lr.r_upper
+    then Cil.kfloat ~loc FDouble lr.r_nearest, C_number
+    else mk_real lr.r_literal
   | LEnum e -> Cil.new_exp ~loc (Const (CEnum e)), C_number
 
 let conditional_to_exp ?(name="if") loc t_opt e1 (e2, env2) (e3, env3) =
@@ -436,14 +431,14 @@ and context_insensitive_term_to_exp kf env t =
     Cil.new_exp ~loc (BinOp(bop, e1, e2, ty)), env, C_number, ""
   | TBinOp(MinusPP, t1, t2) ->
     begin match Typing.get_number_ty t with
-      | Typing.C_type _ ->
+      | Typing.C_integer _ ->
         let e1, env = term_to_exp kf env t1 in
         let e2, env = term_to_exp kf env t2 in
         let ty = Typing.get_typ t in
         Cil.new_exp ~loc (BinOp(MinusPP, e1, e2, ty)), env, C_number, ""
       | Typing.Gmpz ->
         not_yet env "pointer subtraction resulting in gmp"
-      | Typing.Real | Typing.Nan ->
+      | Typing.(C_float _ | Rational | Real | Nan) ->
         assert false
     end
   | TCastE(ty, t') ->
@@ -497,7 +492,6 @@ and context_insensitive_term_to_exp kf env t =
                let e, env =
                  try
                    let ty = Typing.typ_of_number_ty param_ty in
-                   (* TODO RATIONAL: check [Not_a_strnum] *)
                    add_cast loc env (Some ty) C_number (Some targ) e
                  with Typing.Not_a_number ->
                    e, env
@@ -604,7 +598,7 @@ and comparison_to_exp
   in
   let e2, env = term_to_exp kf env t2 in
   match ity with
-  | Typing.C_type _ | Typing.Nan ->
+  | Typing.C_integer _ | Typing.C_float _ | Typing.Nan ->
     Cil.mkBinOp ~loc bop e1 e2, env
   | Typing.Gmpz ->
     let _, e, env = Env.new_var
@@ -617,8 +611,10 @@ and comparison_to_exp
            [ Misc.mk_call ~loc ~result:(Cil.var v) "__gmpz_cmp" [ e1; e2 ] ])
     in
     Cil.new_exp ~loc (BinOp(bop, e, Cil.zero ~loc, Cil.intType)), env
-  | Typing.Real ->
+  | Typing.Rational ->
     Real.cmp ~loc bop e1 e2 env t_opt
+  | Typing.Real ->
+    Error.not_yet "comparison involving real numbers"
 
 and at_to_exp_no_lscope env t_opt label e =
   let stmt = E_acsl_label.get_stmt (Env.get_visitor env) label in
@@ -672,12 +668,14 @@ and env_of_li li kf env loc =
   let vi, vi_e, env = Env.Logic_binding.add ~ty env li.l_var_info in
   let e, env = term_to_exp kf env t in
   let stmt = match Typing.get_number_ty t with
-    | Typing.C_type _ | Typing.Nan ->
+    | Typing.(C_integer _ | C_float _ | Nan) ->
       Cil.mkStmtOneInstr (Set (Cil.var vi, e, loc))
     | Typing.Gmpz ->
       Gmp.init_set ~loc (Cil.var vi) vi_e e
-    | Typing.Real ->
+    | Typing.Rational ->
       Real.init_set ~loc (Cil.var vi) vi_e e
+    | Typing.Real ->
+      Error.not_yet "real number"
   in
   Env.add_stmt env stmt
 
@@ -739,8 +737,8 @@ and named_predicate_content_to_exp ?name kf env p =
       kf
       env
       (Logic_const.pand ~loc
-	 (Logic_const.pimplies ~loc (p1, p2),
-	  Logic_const.pimplies ~loc (p2, p1)))
+         (Logic_const.pimplies ~loc (p1, p2),
+          Logic_const.pimplies ~loc (p2, p1)))
   | Pnot p ->
     let e, env = named_predicate_to_exp kf env p in
     Cil.new_exp ~loc (UnOp(LNot, e, Cil.intType)), env
@@ -919,11 +917,11 @@ let term_to_exp typ t =
   (* infer a context from the given [typ] whenever possible *)
   let ctx_of_typ ty =
     if Gmp.Z.is_t ty then Typing.gmpz
-    else if Real.is_t ty then Typing.real
+    else if Real.is_t ty then Typing.rational
     else
       match ty with
       | TInt(ik, _) -> Typing.ikind ik
-      | TFloat _ -> Typing.real
+      | TFloat(fk, _) -> Typing.fkind fk
       | _ -> Typing.nan
   in
   let ctx = Extlib.opt_map ctx_of_typ typ in
diff --git a/src/plugins/e-acsl/typing.ml b/src/plugins/e-acsl/typing.ml
index 31e9eb057f2c8dc55ddf1fff1bef64f4ce85fe74..774e0c22d3fe329912e6327df742b28cd3f09f5d 100644
--- a/src/plugins/e-acsl/typing.ml
+++ b/src/plugins/e-acsl/typing.ml
@@ -37,15 +37,18 @@ let compute_quantif_guards_ref
 (******************************************************************************)
 
 type number_ty =
-  | C_type of ikind
+  | C_integer of ikind
+  | C_float of fkind
   | Gmpz
+  | Rational
   | Real
   | Nan
 
-let c_int = C_type IInt
-let ikind ik = C_type ik
+let ikind ik = C_integer ik
+let c_int = ikind IInt
 let gmpz = Gmpz
-let real = Real
+let fkind fk = C_float fk
+let rational = Rational
 let nan = Nan
 
 module D =
@@ -60,30 +63,44 @@ module D =
         if ty1 == ty2 then 0
         else
           match ty1, ty2 with
-          | C_type i1, C_type i2 ->
+          | C_integer i1, C_integer i2 ->
             if i1 = i2 then 0
             else if Cil.intTypeIncluded i1 i2 then -1 else 1
-          | (C_type _ | Gmpz | Real), Nan
-          | (C_type _ | Gmpz), Real
-          | C_type _, Gmpz ->
+          | C_float f1, C_float f2 ->
+            Stdlib.compare f1 f2
+          | (C_integer _ | C_float _ | Gmpz | Rational | Real), Nan
+          | (C_integer _ | C_float _ | Gmpz | Rational ), Real
+          | (C_integer _ | C_float _ | Gmpz), Rational
+          | (C_integer _ | C_float _), Gmpz
+          | C_integer _, C_float _ ->
             -1
-          | (Gmpz | Real | Nan), C_type _
-          | (Real | Nan), Gmpz
+          | (C_float _ | Gmpz | Rational | Real | Nan), C_integer _
+          | (Gmpz | Rational | Real | Nan), C_float _
+          | (Rational | Real | Nan), Gmpz
+          | (Real | Nan), Rational
           | Nan, Real ->
             1
-          | Gmpz, Gmpz | Real, Real | Nan, Nan -> assert false
+          | Gmpz, Gmpz
+          | Rational, Rational
+          | Real, Real
+          | Nan, Nan ->
+            assert false
 
       let equal = Datatype.from_compare
 
       let hash = function
-        | C_type ik -> 7 * Hashtbl.hash ik
+        | C_integer ik -> 7 * Hashtbl.hash ik
+        | C_float fk -> 97 * Hashtbl.hash fk
         | Gmpz -> 787
+        | Rational -> 907
         | Real -> 1011
         | Nan -> 1277
 
       let pretty fmt = function
-        | C_type k -> Printer.pp_ikind fmt k
+        | C_integer k -> Printer.pp_ikind fmt k
+        | C_float k -> Printer.pp_fkind fmt k
         | Gmpz -> Format.pp_print_string fmt "Gmpz"
+        | Rational -> Format.pp_print_string fmt "Rational"
         | Real -> Format.pp_print_string fmt "Real"
         | Nan -> Format.pp_print_string fmt "Nan"
     end)
@@ -92,40 +109,58 @@ module D =
 (** Basic operations *)
 (******************************************************************************)
 
-let join ty1 ty2 = match ty1, ty2 with
-  | Nan, Nan ->
-    Nan
-  | Nan, Real | Real, Nan ->
-    Options.fatal "[typing] join failure: real and nan"
-  | Real, Real -> Real
-  | Real, (Gmpz | C_type _) | (Gmpz | C_type _), Real ->
-    Real
-  | Nan, (Gmpz | C_type _) | (Gmpz | C_type _), Nan ->
-    Options.fatal "[typing] join failure: integer and nan"
-  | Gmpz, _ | _, Gmpz -> Gmpz
-  | C_type i1, C_type i2 ->
-    if Options.Gmp_only.get () then Gmpz
-    else
-      let ty = Cil.arithmeticConversion (TInt(i1, [])) (TInt(i2, [])) in
-      match ty with
-      | TInt(i, _) -> C_type i
-      | _ ->
-        Options.fatal "[typing] join failure: unexpected result %a"
-          Printer.pp_typ ty
+let join_cty ty1 ty2 =
+  let ty = Cil.arithmeticConversion ty1 ty2 in
+  match ty with
+  | TInt(i, _) -> C_integer i
+  | TFloat(f, _) -> C_float f
+  | _ ->
+    Options.fatal "[typing] join failure: unexpected result %a"
+      Printer.pp_typ ty
+
+let join ty1 ty2 =
+  if ty1 == ty2 then ty1
+  else
+    match ty1, ty2 with
+    | Nan, Nan | Real, Real | Rational, Rational | Gmpz, Gmpz ->
+      assert false
+    | Nan, (C_integer _ | C_float _ | Gmpz | Rational | Real as ty)
+    | (C_integer _ | C_float _ | Gmpz | Rational | Real as ty), Nan ->
+      Options.fatal "[typing] join failure: number %a and nan" D.pretty ty
+    | Real, (C_integer _ | C_float _ | Gmpz | Rational)
+    | (C_integer _ | C_float _ | Rational | Gmpz), Real ->
+      Real
+    | Rational, (C_integer _ | C_float _ | Gmpz)
+    | (C_integer _ | C_float _ | Gmpz), Rational
+    | C_float _, Gmpz
+    | Gmpz, C_float _ ->
+      Rational
+    | Gmpz, C_integer _
+    | C_integer _, Gmpz ->
+      Gmpz
+    | C_float f1, C_float f2 ->
+      join_cty (TFloat(f1, [])) (TFloat(f2, []))
+    | C_float f, C_integer n
+    | C_integer n, C_float f ->
+      join_cty (TFloat(f, [])) (TInt(n, []))
+    | C_integer i1, C_integer i2 ->
+      if Options.Gmp_only.get () then Gmpz
+      else join_cty (TInt(i1, [])) (TInt(i2, []))
 
 exception Not_a_number
 let typ_of_number_ty = function
-  | C_type ik -> TInt(ik, [])
+  | C_integer ik -> TInt(ik, [])
+  | C_float fk -> TFloat(fk, [])
   | Gmpz -> Gmp.Z.t ()
-  | Real -> Real.t ()
+  (* for the time being, no reals but rationals instead *)
+  | Rational -> Real.t ()
+  | Real -> Error.not_yet "real number type"
   | Nan -> raise Not_a_number
 
 let typ_of_lty = function
   | Ctype cty -> cty
   | Linteger -> Gmp.Z.t ()
-  | Lreal ->
-    (* TODO RATIONAL: implement this case *)
-    assert false
+  | Lreal -> Error.not_yet "real type"
   | Ltype _ | Lvar _ | Larrow _ -> Options.fatal "unexpected logic type"
 
 (******************************************************************************)
@@ -192,20 +227,31 @@ end
 
 (* Compute the smallest type (bigger than [int]) which can contain the whole
    interval. It is the \theta operator of the JFLA's paper. *)
-let ty_of_interv ?ctx i =
-  try
-    let kind = Interval.ikind_of_interv i in
-    (match ctx with
-     | None | Some (Gmpz | Nan) -> C_type kind
-     | Some (C_type ik as ctx) ->
-       (* return [ctx] type for types smaller than int to prevent superfluous
-          casts in the generated code *)
-       if Cil.intTypeIncluded kind ik then ctx else C_type kind
-     | Some Real -> Real)
-  with Cil.Not_representable ->
-    match ctx with
-    | Some Real -> Real
-    | None | Some _ -> Gmpz
+let ty_of_interv ?ctx = function
+  | Interval.Float(fk, _) -> C_float fk
+  | Interval.Rational -> Rational
+  | Interval.Real -> Real
+  | Interval.Nan -> Nan
+  | Interval.Ival iv ->
+    try
+      let kind = Interval.ikind_of_ival iv in
+      (match ctx with
+       | None
+       | Some (Gmpz | Nan) ->
+         C_integer kind
+       | Some (C_integer ik as ctx) ->
+         (* return [ctx] type for types smaller than int to prevent superfluous
+            casts in the generated code *)
+         if Cil.intTypeIncluded kind ik then ctx else C_integer kind
+       | Some (C_float _ | Rational) ->
+         Rational
+       | Some Real ->
+         Real)
+    with Cil.Not_representable ->
+      match ctx with
+      | None | Some(C_integer _ | Gmpz | Nan) -> Gmpz
+      | Some (C_float _ | Rational) -> Rational
+      | Some Real -> Real
 
 (* compute a new {!computed_info} by coercing the given type [ty] to the given
    context [ctx]. [op] is the type for the operator. *)
@@ -224,8 +270,8 @@ let coerce ~arith_operand ~ctx ~op ty =
     else { ty; op; cast = None }
 
 let number_ty_of_typ ty = match Cil.unrollType ty with
-  | TInt(ik, _) | TEnum({ ekind = ik }, _) -> C_type ik
-  | TFloat _ -> Real
+  | TInt(ik, _) | TEnum({ ekind = ik }, _) -> C_integer ik
+  | TFloat(fk, _) -> C_float fk
   | TVoid _ | TPtr _ | TArray _ | TFun _ | TComp _ | TBuiltin_va_list _ -> Nan
   | TNamed _ -> assert false
 
@@ -243,12 +289,8 @@ let ty_of_logic_ty ?term lty =
   | Some t ->
     if Options.Gmp_only.get () && lty = Linteger then Gmpz
     else
-      try
-        let i = Interval.infer t in
-        ty_of_interv i
-      with
-      | Interval.Not_a_number -> nan
-      | Interval.Is_a_real -> real
+      let i = Interval.infer t in
+      ty_of_interv i
 
 (******************************************************************************)
 (** {2 Type system} *)
@@ -257,33 +299,23 @@ let ty_of_logic_ty ?term lty =
 (* generate a context [c]. Take --e-acsl-gmp-only into account iff [use_gmp_opt]
    is true. *)
 let mk_ctx ~use_gmp_opt = function
-  | C_type _ as c -> if use_gmp_opt && Options.Gmp_only.get () then Gmpz else c
-  | Gmpz | Real | Nan as c -> c
+  | C_integer _ as c ->
+    if use_gmp_opt && Options.Gmp_only.get () then Gmpz
+    else c
+  | C_float _ | Gmpz | Rational | Real | Nan as c -> c
 
 (* the number_ty corresponding to [t] whenever use as an offset.
    In that case, it cannot be a GMP, so it must be coerced to an integral type
    in that case *)
 let type_offset t =
-  try
-    let i = Interval.infer t in
-    match ty_of_interv i with
-    | Gmpz -> C_type ILongLong (* largest possible type *)
-    | ty -> ty
-  with
-  | Interval.Is_a_real ->
-    (* TODO RATIONAL: shouldn't it be 'assert false' because of typing? *)
-    C_type ILongLong
-  | Interval.Not_a_number ->
-    Options.fatal "expected an integral type for %a" Printer.pp_term t
-
-let type_letin li =
-  let li_t = Misc.term_of_li li in
-  match ty_of_logic_ty li_t.term_type with
-  | C_type _ | Gmpz ->
-    let i = Interval.infer li_t in
-    Interval.Env.add li.l_var_info i
-  | Real | Nan ->
-    ()
+  let i = Interval.infer t in
+  match ty_of_interv i with
+  | Gmpz -> C_integer ILongLong (* largest possible type *)
+  | ty -> ty
+
+let type_letin li li_t =
+  let i = Interval.infer li_t in
+  Interval.Env.add li.l_var_info i
 
 (* type the term [t] in a context [ctx] by taking --e-acsl-gmp-only into account
    iff [use_gmp_opt] is true. *)
@@ -308,31 +340,17 @@ let rec type_term ~use_gmp_opt ?(arith_operand=false) ?ctx t =
        (and of course also covers the missing cases). Also enforce the invariant
        that every subterm is typed, even if it is not an integer. *)
     match t.term_node with
-    | TConst (LReal _) ->
-      (* TODO RATIONAL: real: irrationals raise not_yet *)
-      dup real
-    | TConst (Integer _ | LChr _ | LEnum _)
+    | TConst (Integer _ | LChr _ | LEnum _ | LReal _)
     | TSizeOf _
     | TSizeOfStr _
     | TAlignOf _ ->
-      let ty =
-        try
-          let i = Interval.infer t in
-          ty_of_interv ?ctx i
-        with
-        | Interval.Not_a_number -> nan
-        | Interval.Is_a_real -> assert false
-      in
+      let i = Interval.infer t in
+      let ty = ty_of_interv ?ctx i in
       dup ty
+
     | TLval tlv ->
-      let ty =
-        try
-          let i = Interval.infer t in
-          ty_of_interv ?ctx i
-        with
-        | Interval.Not_a_number -> nan
-        | Interval.Is_a_real -> real
-      in
+      let i = Interval.infer t in
+      let ty = ty_of_interv ?ctx i in
       type_term_lval tlv;
       dup ty
 
@@ -340,42 +358,24 @@ let rec type_term ~use_gmp_opt ?(arith_operand=false) ?ctx t =
     | Tblock_length(_, t')
     | TSizeOfE t'
     | TAlignOfE t' ->
-      let ty =
-        try
-          let i = Interval.infer t in
-          (* [t'] must be typed, but it is a pointer *)
-          ignore (type_term ~use_gmp_opt:true ~ctx:nan t');
-          ty_of_interv ?ctx i
-        with (* this term is an integer *)
-        | Interval.Is_a_real
-        | Interval.Not_a_number -> assert false
-      in
+      let i = Interval.infer t in
+      (* [t'] must be typed, but it is a pointer *)
+      ignore (type_term ~use_gmp_opt:true ~ctx:Nan t');
+      let ty = ty_of_interv ?ctx i in
       dup ty
 
     | TBinOp (MinusPP, t1, t2) ->
-      let ty =
-        try
-          let i = Interval.infer t in
-          (* [t1] and [t2] must be typed, but they are pointers *)
-          ignore (type_term ~use_gmp_opt:true ~ctx:nan t1);
-          ignore (type_term ~use_gmp_opt:true ~ctx:nan t2);
-          ty_of_interv ?ctx i
-        with (* this term is an integer *)
-        | Interval.Is_a_real
-        | Interval.Not_a_number -> assert false
-      in
+      let i = Interval.infer t in
+      (* [t1] and [t2] must be typed, but they are pointers *)
+      ignore (type_term ~use_gmp_opt:true ~ctx:Nan t1);
+      ignore (type_term ~use_gmp_opt:true ~ctx:Nan t2);
+      let ty = ty_of_interv ?ctx i in
       dup ty
 
     | TUnOp (unop, t') ->
-      let ctx_res, ctx =
-        try
-          let i = Interval.infer t in
-          let i' = Interval.infer t' in
-          compute_ctx ?ctx (Ival.join i i')
-        with
-        | Interval.Is_a_real -> real, real
-        | Interval.Not_a_number -> assert false
-      in
+      let i = Interval.infer t in
+      let i' = Interval.infer t' in
+      let ctx_res, ctx = compute_ctx ?ctx (Interval.join i i') in
       ignore (type_term ~use_gmp_opt:true ~arith_operand:true ~ctx t');
       (match unop with
        | LNot -> c_int, ctx_res (* converted into [t == 0] in case of GMP *)
@@ -383,15 +383,11 @@ let rec type_term ~use_gmp_opt ?(arith_operand=false) ?ctx t =
 
     | TBinOp ((PlusA | MinusA | Mult | Div | Mod | Shiftlt | Shiftrt), t1, t2)
       ->
+      let i = Interval.infer t in
+      let i1 = Interval.infer t1 in
+      let i2 = Interval.infer t2 in
       let ctx_res, ctx =
-        try
-          let i = Interval.infer t in
-          let i1 = Interval.infer t1 in
-          let i2 = Interval.infer t2 in
-          compute_ctx ?ctx (Ival.join i (Ival.join i1 i2))
-        with
-        | Interval.Is_a_real -> dup real
-        | Interval.Not_a_number -> assert false
+        compute_ctx ?ctx (Interval.join i (Interval.join i1 i2))
       in
       (* it is enough to explicitly coerce when required one operand to [ctx]
          (through [arith_operand]) in order to force the type of the
@@ -410,33 +406,23 @@ let rec type_term ~use_gmp_opt ?(arith_operand=false) ?ctx t =
 
     | TBinOp ((Lt | Gt | Le | Ge | Eq | Ne), t1, t2) ->
       assert (match ctx with None -> true | Some c -> D.compare c c_int >= 0);
+      let i1 = Interval.infer t1 in
+      let i2 = Interval.infer t2 in
       let ctx =
-        try
-          let i1 = Interval.infer t1 in
-          let i2 = Interval.infer t2 in
-          mk_ctx ~use_gmp_opt:true (ty_of_interv ?ctx (Ival.join i1 i2))
-        with
-        | Interval.Is_a_real -> real
-        | Interval.Not_a_number -> nan
+        mk_ctx ~use_gmp_opt:true (ty_of_interv ?ctx (Interval.join i1 i2))
       in
       ignore (type_term ~use_gmp_opt:true ~ctx t1);
       ignore (type_term ~use_gmp_opt:true ~ctx t2);
       let ty = match ctx with
         | Nan -> c_int
-        | Real | Gmpz | C_type _ -> ctx
+        | Real | Rational | Gmpz | C_float _ | C_integer _ -> ctx
       in
       c_int, ty
 
     | TBinOp ((LAnd | LOr), t1, t2) ->
-      let ty =
-        try
-          let i1 = Interval.infer t1 in
-          let i2 = Interval.infer t2 in
-          ty_of_interv ?ctx (Ival.join i1 i2)
-        with (* this term is an integer *)
-        | Interval.Is_a_real
-        | Interval.Not_a_number -> assert false
-      in
+      let i1 = Interval.infer t1 in
+      let i2 = Interval.infer t2 in
+      let ty = ty_of_interv ?ctx (Interval.join i1 i2) in
       (* both operands fit in an int. *)
       ignore (type_term ~use_gmp_opt:true ~ctx:c_int t1);
       ignore (type_term ~use_gmp_opt:true ~ctx:c_int t2);
@@ -447,17 +433,11 @@ let rec type_term ~use_gmp_opt ?(arith_operand=false) ?ctx t =
     | TBinOp (BOr, _, _) -> Error.not_yet "bitwise or"
 
     | TCastE(_, t') ->
-      let ctx =
-        try
-          (* compute the smallest interval from the whole term [t] *)
-          let i = Interval.infer t in
-          (* nothing more to do: [i] is already more precise than what we
-             could infer from the arguments of the cast. *)
-          ty_of_interv ?ctx i
-        with
-        | Interval.Not_a_number -> nan
-        | Interval.Is_a_real -> real
-      in
+      (* compute the smallest interval from the whole term [t] *)
+      let i = Interval.infer t in
+      (* nothing more to do: [i] is already more precise than what we could
+         infer from the arguments of the cast. *)
+      let ctx = ty_of_interv ?ctx i in
       ignore (type_term ~use_gmp_opt:true ~ctx t');
       dup ctx
 
@@ -467,16 +447,10 @@ let rec type_term ~use_gmp_opt ?(arith_operand=false) ?ctx t =
       in
       ignore (type_term ~use_gmp_opt:false ~ctx:ctx1 t1);
       let i = Interval.infer t in
-      let ctx =
-        try
-          let i2 = Interval.infer t2 in
-          let i3 = Interval.infer t3 in
-          let ctx = ty_of_interv ?ctx (Ival.join i (Ival.join i2 i3)) in
-          mk_ctx ~use_gmp_opt:true ctx
-        with
-        | Interval.Is_a_real -> real
-        | Interval.Not_a_number -> nan
-      in
+      let i2 = Interval.infer t2 in
+      let i3 = Interval.infer t3 in
+      let ctx = ty_of_interv ?ctx (Interval.join i (Interval.join i2 i3)) in
+      let ctx = mk_ctx ~use_gmp_opt:true ctx in
       ignore (type_term ~use_gmp_opt:true ~ctx t2);
       ignore (type_term ~use_gmp_opt:true ~ctx t3);
       dup ctx
@@ -489,19 +463,19 @@ let rec type_term ~use_gmp_opt ?(arith_operand=false) ?ctx t =
     | TStartOf tlv ->
       (* it is a pointer, but subterms must be typed. *)
       type_term_lval tlv;
-      dup nan
+      dup Nan
 
     | Tbase_addr (_, t) ->
       (* it is a pointer, but subterms must be typed. *)
-      ignore (type_term ~use_gmp_opt:true ~ctx:nan t);
-      dup nan
+      ignore (type_term ~use_gmp_opt:true ~ctx:Nan t);
+      dup Nan
 
     | TBinOp ((PlusPI | IndexPI | MinusPI), t1, t2) ->
       (* both [t1] and [t2] must be typed. *)
-      ignore (type_term ~use_gmp_opt:true ~ctx:nan t1);
+      ignore (type_term ~use_gmp_opt:true ~ctx:Nan t1);
       let ctx = type_offset t2 in
       ignore (type_term ~use_gmp_opt:false ~ctx t2);
-      dup nan
+      dup Nan
 
     | Tapp(li, _, args) ->
       if Builtins.mem li.l_var_info.lv_name then
@@ -531,6 +505,7 @@ let rec type_term ~use_gmp_opt ?(arith_operand=false) ?ctx t =
             | None ->
               assert false
             | Some lty ->
+              (* TODO: what if the function returns a real? *)
               let ty = ty_of_logic_ty ~term:t lty in
               dup ty
           end
@@ -545,24 +520,22 @@ let rec type_term ~use_gmp_opt ?(arith_operand=false) ?ctx t =
     | Tunion _ -> Error.not_yet "tset union"
     | Tinter _ -> Error.not_yet "tset intersection"
     | Tcomprehension (_,_,_) -> Error.not_yet "tset comprehension"
+
+    | Trange(None, _) | Trange(_, None) ->
+      Options.abort "unbounded ranges are not part of E-ACSl"
     | Trange(Some n1, Some n2) ->
       ignore (type_term ~use_gmp_opt n1);
       ignore (type_term ~use_gmp_opt n2);
-      (try
-         let i = Interval.infer t in
-         let ty = ty_of_interv ?ctx i in
-         dup ty
-       with
-        | Interval.Is_a_real -> dup real
-        | Interval.Not_a_number -> dup nan)
+      let i = Interval.infer t in
+      let ty = ty_of_interv ?ctx i in
+      dup ty
 
-    | Trange(None, _) | Trange(_, None) ->
-      Options.abort "unbounded ranges are not part of E-ACSl"
     | Tlet(li, t) ->
-      type_letin li;
       let li_t = Misc.term_of_li li in
+      type_letin li li_t;
       ignore (type_term ~use_gmp_opt:true li_t);
       dup (type_term ~use_gmp_opt:true ?ctx t).ty
+
     | Tlambda (_,_) -> Error.not_yet "lambda"
     | TDataCons (_,_) -> Error.not_yet "datacons"
     | TUpdate (_,_,_) -> Error.not_yet "update"
@@ -571,7 +544,7 @@ let rec type_term ~use_gmp_opt ?(arith_operand=false) ?ctx t =
     | TConst (LStr _ | LWStr _)
     | Ttypeof _
     | Ttype _
-    | Tempty_set  -> dup nan
+    | Tempty_set  -> dup Nan
   in
   Memo.memo
     (fun t ->
@@ -588,7 +561,7 @@ and type_term_lval (host, offset) =
 and type_term_lhost = function
   | TVar _
   | TResult _ -> ()
-  | TMem t -> ignore (type_term ~use_gmp_opt:false ~ctx:nan t)
+  | TMem t -> ignore (type_term ~use_gmp_opt:false ~ctx:Nan t)
 
 and type_term_offset = function
   | TNoOffset -> ()
@@ -613,28 +586,22 @@ let rec type_predicate p =
              a retyping is done there *)
           c_int
         | LBnone -> (* Eg: \is_finite *)
-          Error.not_yet "logic functions with no definition nor reads clause"
+          Error.not_yet "predicate with no definition nor reads clause"
         | LBreads _ | LBterm _ | LBinductive _ ->
           Options.fatal "unexpected logic definition"
       end
     | Pseparated _ -> Error.not_yet "\\separated"
     | Pdangling _ -> Error.not_yet "\\dangling"
     | Prel(_, t1, t2) ->
-      let ctx =
-        try
-          let i1 = Interval.infer t1 in
-          let i2 = Interval.infer t2 in
-          let i = Ival.join i1 i2 in
-          mk_ctx ~use_gmp_opt:true (ty_of_interv ~ctx:c_int i)
-        with
-        | Interval.Not_a_number -> nan
-        | Interval.Is_a_real -> real
-      in
+      let i1 = Interval.infer t1 in
+      let i2 = Interval.infer t2 in
+      let i = Interval.join i1 i2 in
+      let ctx = mk_ctx ~use_gmp_opt:true (ty_of_interv ~ctx:c_int i) in
       ignore (type_term ~use_gmp_opt:true ~ctx t1);
       ignore (type_term ~use_gmp_opt:true ~ctx t2);
       (match ctx with
        | Nan -> c_int
-       | Real | Gmpz | C_type _ -> ctx)
+       | Real | Rational | Gmpz | C_float _ | C_integer _ -> ctx)
     | Pand(p1, p2)
     | Por(p1, p2)
     | Pxor(p1, p2)
@@ -653,64 +620,63 @@ let rec type_predicate p =
       ignore (type_predicate p2);
       c_int
     | Plet(li, p) ->
-      type_letin li;
       let li_t = Misc.term_of_li li in
+      type_letin li li_t;
       ignore (type_term ~use_gmp_opt:true li_t);
       (type_predicate p).ty
 
     | Pforall(bounded_vars, { pred_content = Pimplies(hyps, goal) })
     | Pexists(bounded_vars, { pred_content = Pand(hyps, goal) }) ->
       let guards = !compute_quantif_guards_ref p bounded_vars hyps in
-      (try
-         List.iter
-           (fun (t1, r1, x, r2, t2) ->
-              let i1 = Interval.infer t1 in
-              let i1 = match r1 with
-                | Rlt -> Ival.add_singleton_int Integer.one i1
-                | Rle -> i1
-                | _ -> assert false
-              in
-              let i2 = Interval.infer t2 in
-              (* add one to [i2], since we increment the loop counter one more
-                 time before going outside the loop. *)
-              let i2 = match r2 with
-                | Rlt -> i2
-                | Rle -> Ival.add_singleton_int Integer.one i2
-                | _ -> assert false
-              in
-              let i = Ival.join i1 i2 in
-              let ctx = match x.lv_type with
-                | Linteger -> mk_ctx ~use_gmp_opt:true (ty_of_interv ~ctx:Gmpz i)
-                | Ctype ty ->
-                  (match Cil.unrollType ty with
-                   | TInt(ik, _) -> mk_ctx ~use_gmp_opt:true (C_type ik)
-                   | ty ->
-                     Options.fatal "unexpected type %a for quantified variable %a"
-                       Printer.pp_typ ty
-                       Printer.pp_logic_var x)
-                | lty ->
+      let iv_plus_one iv =
+        Interval.Ival (Ival.add_singleton_int Integer.one iv)
+      in
+      List.iter
+        (fun (t1, r1, x, r2, t2) ->
+           let i1 = Interval.infer t1 in
+           let i1 = match r1, i1 with
+             | Rlt, Interval.Ival iv -> iv_plus_one iv
+             | Rle, _ -> i1
+             | _ -> assert false
+           in
+           let i2 = Interval.infer t2 in
+           (* add one to [i2], since we increment the loop counter one more
+              time before going outside the loop. *)
+           let i2 = match r2, i2 with
+             | Rlt, _ -> i2
+             | Rle, Interval.Ival iv -> iv_plus_one iv
+             | _ -> assert false
+           in
+           let i = Interval.join i1 i2 in
+           let ctx = match x.lv_type with
+             | Linteger -> mk_ctx ~use_gmp_opt:true (ty_of_interv ~ctx:Gmpz i)
+             | Ctype ty ->
+               (match Cil.unrollType ty with
+                | TInt(ik, _) -> mk_ctx ~use_gmp_opt:true (C_integer ik)
+                | ty ->
                   Options.fatal "unexpected type %a for quantified variable %a"
-                    Printer.pp_logic_type lty
-                    Printer.pp_logic_var x
-              in
-              (* forcing when typing bounds prevents to generate an extra useless
-                 GMP variable when --e-acsl-gmp-only *)
-              ignore (type_term ~use_gmp_opt:false ~ctx t1);
-              ignore (type_term ~use_gmp_opt:false ~ctx t2);
-              (* if we must generate GMP code, degrade the interval in order to
-                 guarantee that [x] will be a GMP when typing the goal *)
-              let i = match ctx with
-                | C_type _ -> i
-                | Gmpz -> Ival.inject_range None None (* [ -\infty; +\infty ] *)
-                | Nan -> assert false
-                | Real -> Error.not_yet "reals: quantification"
-              in
-              Interval.Env.add x i)
-           guards;
-         (type_predicate goal).ty
-       with
-       | Interval.Not_a_number -> assert false
-       | Interval.Is_a_real -> Error.not_yet "quantification over real numbers")
+                    Printer.pp_typ ty
+                    Printer.pp_logic_var x)
+             | lty ->
+               Options.fatal "unexpected type %a for quantified variable %a"
+                 Printer.pp_logic_type lty
+                 Printer.pp_logic_var x
+           in
+           (* forcing when typing bounds prevents to generate an extra useless
+              GMP variable when --e-acsl-gmp-only *)
+           ignore (type_term ~use_gmp_opt:false ~ctx t1);
+           ignore (type_term ~use_gmp_opt:false ~ctx t2);
+           (* if we must generate GMP code, degrade the interval in order to
+              guarantee that [x] will be a GMP when typing the goal *)
+           let i = match ctx with
+             | C_integer _ -> i
+             | Gmpz -> Interval.top_ival (* [ -\infty; +\infty ] *)
+             | C_float _ | Rational | Real | Nan ->
+               Options.fatal "unexpected quantification over %a" D.pretty ctx
+           in
+           Interval.Env.add x i)
+        guards;
+      (type_predicate goal).ty
 
     | Pinitialized(_, t)
     | Pfreeable(_, t)
@@ -718,7 +684,7 @@ let rec type_predicate p =
     | Pvalid(_, t)
     | Pvalid_read(_, t)
     | Pvalid_function t ->
-      ignore (type_term ~use_gmp_opt:false ~ctx:nan t);
+      ignore (type_term ~use_gmp_opt:false ~ctx:Nan t);
       c_int
 
     | Pforall _ -> Error.not_yet "unguarded \\forall quantification"
@@ -761,7 +727,8 @@ let extract_typ t ty =
   with Not_a_number ->
     match t.term_type with
     | Ctype _ as lty -> Logic_utils.logicCType lty
-    | Linteger | Lreal -> assert false
+    | Linteger | Lreal ->
+      Options.fatal "unexpected context NaN for term %a" Printer.pp_term t
     | Ltype _ -> Error.not_yet "unsupported logic type: user-defined type"
     | Lvar _ -> Error.not_yet "unsupported logic type: type variable"
     | Larrow _ -> Error.not_yet "unsupported logic type: type arrow"
diff --git a/src/plugins/e-acsl/typing.mli b/src/plugins/e-acsl/typing.mli
index 7674d4519ed19a145d9adb8eb6f0fe404a6cdd48..29be0fa5d4e072b353af0a821f314178166d5cd1 100644
--- a/src/plugins/e-acsl/typing.mli
+++ b/src/plugins/e-acsl/typing.mli
@@ -53,8 +53,10 @@ open Cil_types
 (** Possible types infered by the system. *)
 
 type number_ty = private
-  | C_type of ikind
+  | C_integer of ikind
+  | C_float of fkind
   | Gmpz
+  | Rational
   | Real
   | Nan
 
@@ -64,8 +66,9 @@ module Datatype: Datatype.S_with_collections with type t = number_ty
 
 val c_int: number_ty
 val ikind: ikind -> number_ty
+val fkind: fkind -> number_ty
 val gmpz: number_ty
-val real: number_ty
+val rational: number_ty
 val nan: number_ty
 
 (** {3 Useful operations over {!number_ty}} *)
@@ -139,7 +142,7 @@ val unsafe_set: term -> ?ctx:number_ty -> number_ty -> unit
 (** {2 Typing/types-related utils} *)
 (*****************************************************************************)
 
-val ty_of_interv: ?ctx:number_ty -> Ival.t -> number_ty
+val ty_of_interv: ?ctx:number_ty -> Interval.t -> number_ty
 (* Compute the smallest type (bigger than [int]) which can contain the whole
    interval. It is the \theta operator of the JFLA's paper. *)