diff --git a/libpoly/dune b/libpoly/dune
index 924c95c2c886f2ac00ac9efc289a81178c50876b..ff84f0ec1dd6d8abaf2953947e863797a72ba088 100644
--- a/libpoly/dune
+++ b/libpoly/dune
@@ -15,7 +15,7 @@
   (progn
     (chdir libpoly/build
      (progn
-      (run cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=install)
+      (run cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=install)
       (run make static_pic_poly poly)))
     (copy libpoly/build/src/libpicpoly.a libpoly.a)
     (copy libpoly/build/src/libpoly.so dllpoly.so)
diff --git a/libpoly/libpoly b/libpoly/libpoly
index 27094db6e7a34958a9762e4ff1803f0d25590a27..0e852f489a7148213e0a813417a96882062bceaa 160000
--- a/libpoly/libpoly
+++ b/libpoly/libpoly
@@ -1 +1 @@
-Subproject commit 27094db6e7a34958a9762e4ff1803f0d25590a27
+Subproject commit 0e852f489a7148213e0a813417a96882062bceaa
diff --git a/libpoly/ocaml_poly.ml b/libpoly/ocaml_poly.ml
index 53f46f5f1caca02b309fb32b913a1ef2334f90f4..5539f21f05536260426a9d2b13769266111a95c0 100644
--- a/libpoly/ocaml_poly.ml
+++ b/libpoly/ocaml_poly.ml
@@ -52,6 +52,8 @@ module A = struct
     C.Function.mpz_clear mpz;
     a
 
+  let of_int i = of_z (Z.of_int i)
+
   let mpq_of_q (q : Q.t) =
     let mpq = Ctypes.allocate_n C.Type.MPQ._struct 1 in
     C.Function.ml_z_mpz_init_set_z (mpq |-> C.Type.MPQ.mp_num) q.num;
@@ -101,6 +103,7 @@ module A = struct
 
   let neg = unop C.Function.lp_algebraic_number_neg
   let inv = unop C.Function.lp_algebraic_number_inv
+  let abs a = if sign a < 0 then neg a else a
   let add = binop C.Function.lp_algebraic_number_add
   let sub = binop C.Function.lp_algebraic_number_sub
   let mul = binop C.Function.lp_algebraic_number_mul
diff --git a/libpoly/ocaml_poly.mli b/libpoly/ocaml_poly.mli
index 6e4e4d5baae3f70130c6c8104645d8998d7a9328..afe21a80f1b287b100cdeeaed8eef62968c80518 100644
--- a/libpoly/ocaml_poly.mli
+++ b/libpoly/ocaml_poly.mli
@@ -28,12 +28,15 @@ module A : sig
   val to_rational_approx : t -> Q.t
   val to_string : t -> string
   val to_double : t -> float
+  val of_int : int -> t
   val of_z : Z.t -> t
   val of_q : Q.t -> t
   val add : t -> t -> t
   val sub : t -> t -> t
+  val mul : t -> t -> t
   val neg : t -> t
   val inv : t -> t
+  val abs : t -> t
   val div : t -> t -> t
   val div_t : t -> t -> Z.t
   val div_e : t -> t -> Z.t
diff --git a/src_colibri2/stdlib/std.ml b/src_colibri2/stdlib/std.ml
index b5996e1a892c84ab53a61f937117125e5999d63a..c666f604005085ca4485229c16a69abb79517766 100644
--- a/src_colibri2/stdlib/std.ml
+++ b/src_colibri2/stdlib/std.ml
@@ -185,10 +185,20 @@ module A = struct
   let gt a b = compare a b > 0
   let le a b = compare a b <= 0
   let lt a b = compare a b < 0
+  let min a b = if lt a b then a else b
+  let max a b = if gt a b then a else b
   let of_string_decimal s = Q (Q.of_string_decimal s)
+  let of_string s = Q (Q.of_string s)
+  let to_string = function Q q -> Q.to_string q | A a -> A.to_string a
   let is_integer = function Q q -> Q.is_integer q | A _ -> false
   (* by normalization *)
 
+  let is_real = function Q q -> Q.is_real q | A _ -> true
+  let to_z = function Q q -> q.Q.num | A _ -> assert false
+  let to_int = function Q q -> Q.to_int q | A _ -> assert false
+  let inf = Q Q.inf
+  let minus_inf = Q Q.minus_inf
+
   let normalize (a : A.t) =
     if A.is_rational a then Q (A.to_rational_approx a) else A a
 
@@ -198,12 +208,16 @@ module A = struct
     | Q q -> Q.is_unsigned_integer size q
     | A _ -> false
 
+  let of_q q = Q q
   let of_z z = Q (Q.of_bigint z)
+  let of_int z = Q (Q.of_int z)
+  let of_bigint = of_z
   let floor = function Q q -> Q (Q.floor q) | A a -> of_z (A.floor a)
   let ceil = function Q q -> Q (Q.ceil q) | A a -> of_z (A.ceil a)
   let truncate = function Q q -> Q (Q.truncate q) | A a -> of_z (A.truncate a)
   let neg = function Q q -> Q (Q.neg q) | A a -> normalize (A.neg a)
   let inv = function Q q -> Q (Q.inv q) | A a -> normalize (A.inv a)
+  let abs = function Q q -> Q (Q.abs q) | A a -> normalize (A.abs a)
 
   let combine2 fq fa cv a b =
     match (a, b) with Q a, Q b -> Q (fq a b) | _ -> cv (fa (to_a a) (to_a b))
@@ -212,6 +226,12 @@ module A = struct
   let add = combine2 Q.add A.add normalize
   let sub = combine2 Q.sub A.sub normalize
   let mul = combine2 Q.mul A.add normalize
+  let ( + ) = add
+  let ( - ) = sub
+  let ( ~- ) = neg
+  let ( ~+ ) x = x
+  let ( * ) = mul
+  let ( / ) = div
   let div_e = combine2 Q.div_e A.div_e of_z
   let div_t = combine2 Q.div_t A.div_t of_z
   let div_f = combine2 Q.div_f A.div_f of_z
@@ -226,20 +246,35 @@ module A = struct
 
   let a_gen : A.t QCheck.Gen.t =
     let open QCheck.Gen in
-    let* coefs = list small_signed_int in
-    let u = Ocaml_poly.UPolynomial.construct (List.map Z.of_int coefs) in
-    let roots = Ocaml_poly.UPolynomial.roots_isolate u in
-    oneofl roots
+    if false then
+      let rec aux s =
+        let coefs = small_list small_signed_int s in
+        let u = Ocaml_poly.UPolynomial.construct (List.map Z.of_int coefs) in
+        let roots = Ocaml_poly.UPolynomial.roots_isolate u in
+        match roots with [] -> aux s | _ -> oneofl roots s
+      in
+      aux
+    else fun s ->
+      let a = (triple small_signed_int small_nat small_nat) s in
+      let b = (triple small_signed_int small_nat small_nat) s in
+      let coefs = [ a; b ] in
+      List.fold_left
+        (fun acc (p, c, r) ->
+          A.add acc
+            (A.mul (A.of_int p) (A.positive_root (A.of_int c) Int.(r + 1))))
+        (A.zero ()) coefs
 
   let gen =
     let open QCheck.Gen in
-    oneof [ map (fun q -> Q q) Q.gen; map (fun a -> !!a) a_gen ]
+    frequency [ (999, map (fun q -> Q q) Q.gen); (1, map (fun a -> !!a) a_gen) ]
 
   let shrink q =
     let open QCheck.Iter in
     match q with
     | Q q -> map (fun q -> Q q) (Q.shrink q)
-    | A a -> if A.is_integer a then empty else return (of_z (A.truncate a))
+    | A _ ->
+        (* if A.is_integer a then empty else return (of_z (A.truncate a)) *)
+        empty
 
   let pow q n = match q with Q q -> Q (Q.pow q n) | A a -> !!(A.pow a n)
 end
diff --git a/src_colibri2/stdlib/std.mli b/src_colibri2/stdlib/std.mli
index c05caeebdea30ea223ffe501bdab61cee992863e..0a461204a0c75779b24988bbdc2cdd4dc80145ae 100644
--- a/src_colibri2/stdlib/std.mli
+++ b/src_colibri2/stdlib/std.mli
@@ -81,7 +81,7 @@ module Q : sig
 end
 
 module A : sig
-  type t
+  type t = Q of Q.t | A of Ocaml_poly.A.t
 
   val zero : t
   val one : t
@@ -89,15 +89,29 @@ module A : sig
   val minus_one : t
   (** 0, 1, -1. *)
 
+  val of_bigint : Z.t -> t
+  val of_z : Z.t -> t
+  val of_int : int -> t
+  val to_z : t -> Z.t
+
+  val to_int : t -> int
+  (** suppose that it is an integer *)
+
+  val of_q : Q.t -> t
   val sign : t -> int
 
   include Colibri2_popop_lib.Popop_stdlib.Datatype with type t := t
 
+  val to_string : t -> string
   val two : t
   val ge : t -> t -> bool
   val le : t -> t -> bool
   val gt : t -> t -> bool
   val lt : t -> t -> bool
+
+  val of_string : string -> t
+  (** integer *)
+
   val of_string_decimal : string -> t
   val floor : t -> t
   val ceil : t -> t
@@ -106,6 +120,7 @@ module A : sig
   val sub : t -> t -> t
   val neg : t -> t
   val inv : t -> t
+  val abs : t -> t
   val mul : t -> t -> t
   val div : t -> t -> t
   val div_t : t -> t -> t
@@ -116,6 +131,9 @@ module A : sig
   val mod_f : t -> t -> t
   val pow : t -> int -> t
   val is_integer : t -> bool
+  val is_real : t -> bool
+  val inf : t
+  val minus_inf : t
 
   val is_unsigned_integer : int -> t -> bool
   (** [is_unsigned_integer size q] checks that [q] is an integer that fits in
@@ -128,4 +146,12 @@ module A : sig
   val is_not_zero : t -> bool
   val gen : t QCheck.Gen.t
   val shrink : t QCheck.Shrink.t
+  val ( ~- ) : t -> t
+  val ( ~+ ) : t -> t
+  val ( + ) : t -> t -> t
+  val ( - ) : t -> t -> t
+  val ( * ) : t -> t -> t
+  val ( / ) : t -> t -> t
+  val min : t -> t -> t
+  val max : t -> t -> t
 end
diff --git a/src_colibri2/tests/tests_LRA.ml b/src_colibri2/tests/tests_LRA.ml
index d26a54428c5ca5079e83be14a3655bb371ace95d..4fc5a88e15ba232c6fc18e04b573c926cadff42b 100644
--- a/src_colibri2/tests/tests_LRA.ml
+++ b/src_colibri2/tests/tests_LRA.ml
@@ -36,9 +36,7 @@ let theories =
   ]
 
 let run f = Scheduler.run_exn ~step_limit:3000 ~nodec:() ~theories f
-
 let run_dec f = Scheduler.run_exn ~step_limit:3000 ?nodec:None ~theories f
-
 let ( $$ ) f x = f x
 
 (* The tests with rundec check only the result on a model satisfying
@@ -49,7 +47,7 @@ open Expr
 let solve0a _ =
   run @@ fun env ->
   let a = fresh env Ty.real "ar" in
-  let _1 = LRA.RealValue.cst Q.one in
+  let _1 = LRA.RealValue.cst A.one in
   let a1 = LRA.add env a _1 in
   register env a1;
   register env _1;
@@ -59,11 +57,11 @@ let solve0a _ =
 let solve0b _ =
   run @@ fun env ->
   let a = fresh env Ty.real "ar" in
-  let _1 = LRA.RealValue.cst Q.one in
-  let _2 = LRA.RealValue.cst Q.two in
-  let _4 = LRA.RealValue.cst (Q.of_int 4) in
+  let _1 = LRA.RealValue.cst A.one in
+  let _2 = LRA.RealValue.cst A.two in
+  let _4 = LRA.RealValue.cst (A.of_int 4) in
   let a1 = LRA.add env a _1 in
-  let _2a2 = LRA.add' env Q.two a Q.one _2 in
+  let _2a2 = LRA.add' env A.two a A.one _2 in
   List.iter (register env) [ a1; _1; _2; _4; _2a2 ];
   merge env a1 _2;
   fun env -> assert_bool "a+1 = 2 => 2*a+2 = 4" (is_equal env _2a2 _4)
@@ -72,7 +70,7 @@ let solve0c _ =
   run @@ fun env ->
   let a = fresh env Ty.real "ar" in
   let b = fresh env Ty.real "br" in
-  let _1 = LRA.RealValue.cst Q.one in
+  let _1 = LRA.RealValue.cst A.one in
   let a1 = LRA.add env a _1 in
   let b1 = LRA.add env b _1 in
   register env a1;
@@ -83,10 +81,10 @@ let solve0c _ =
 let solve1 _ =
   run @@ fun env ->
   let a, b = Shuffle.seq2 (fresh env Ty.real) ("ar", "br") in
-  let _1 = LRA.RealValue.cst Q.one in
+  let _1 = LRA.RealValue.cst A.one in
   let a1 = LRA.add env a _1 in
   let b1 = LRA.add env b _1 in
-  let _2 = LRA.RealValue.cst (Q.of_int 2) in
+  let _2 = LRA.RealValue.cst (A.of_int 2) in
   let a2 = LRA.add env a _2 in
   let b2 = LRA.add env b _2 in
   Shuffle.seql' (register env) [ a1; b1; a2; b2 ];
@@ -96,10 +94,10 @@ let solve1 _ =
 let solve2 _ =
   run @@ fun env ->
   let a, b = Shuffle.seq2 (fresh env Ty.real) ("ar", "br") in
-  let _1 = LRA.RealValue.cst Q.one in
+  let _1 = LRA.RealValue.cst A.one in
   let a1 = LRA.add env a _1 in
   let b1 = LRA.add env b _1 in
-  let _2 = LRA.RealValue.cst (Q.of_int 2) in
+  let _2 = LRA.RealValue.cst (A.of_int 2) in
   let a2 = LRA.add env a _2 in
   let b2 = LRA.add env b _2 in
   Shuffle.seql' (register env) [ a1; b1; a2; b2 ];
@@ -109,11 +107,11 @@ let solve2 _ =
 let solve3 _ =
   run @@ fun env ->
   let a, b = Shuffle.seq2 (fresh env Ty.real) ("ar", "br") in
-  let _1 = LRA.RealValue.cst Q.one in
+  let _1 = LRA.RealValue.cst A.one in
   let b1 = LRA.add env b _1 in
-  let _2 = LRA.RealValue.cst (Q.of_int 2) in
+  let _2 = LRA.RealValue.cst (A.of_int 2) in
   let a2 = LRA.add env a _2 in
-  let _3 = LRA.RealValue.cst (Q.of_int 3) in
+  let _3 = LRA.RealValue.cst (A.of_int 3) in
   Shuffle.seql
     [
       (fun () ->
@@ -131,15 +129,15 @@ let solve3 _ =
 let solve4 _ =
   run @@ fun env ->
   let a, b, c = Shuffle.seq3 (fresh env Ty.real) ("ar", "br", "cr") in
-  let t1 = LRA.RealValue.cst (Q.of_int 2) in
+  let t1 = LRA.RealValue.cst (A.of_int 2) in
   let t1 = LRA.add env t1 c in
   let t1 = LRA.add env a t1 in
-  let t1' = LRA.RealValue.cst (Q.of_int 1) in
+  let t1' = LRA.RealValue.cst (A.of_int 1) in
   let t1' = LRA.add env b t1' in
   let t2 = a in
-  let t2' = LRA.RealValue.cst (Q.of_int 2) in
+  let t2' = LRA.RealValue.cst (A.of_int 2) in
   let t2' = LRA.add env t2' b in
-  let t3' = LRA.RealValue.cst (Q.of_int (-3)) in
+  let t3' = LRA.RealValue.cst (A.of_int (-3)) in
   Shuffle.seql
     [
       (fun () ->
@@ -160,9 +158,9 @@ let solve5 _ =
   let c = fresh env Ty.real "cr" in
   let t1 = LRA.sub env b c in
   let t1 = LRA.add env a t1 in
-  let t1' = LRA.RealValue.cst (Q.of_int 2) in
+  let t1' = LRA.RealValue.cst (A.of_int 2) in
   let t2 = a in
-  let t2' = LRA.RealValue.cst (Q.of_int 2) in
+  let t2' = LRA.RealValue.cst (A.of_int 2) in
   let t3 = LRA.add env b c in
   let t3' = LRA.add env b b in
   Shuffle.seql
@@ -189,9 +187,9 @@ let mult0 _ =
   let t1 = LRA.sub env a b in
   let t1' = LRA.mult env a b in
   let t2 = a in
-  let t2' = LRA.RealValue.cst (Q.of_int 1) in
-  let t3 = LRA.mult_cst env (Q.of_int 2) b in
-  let t3' = LRA.RealValue.cst (Q.of_int 1) in
+  let t2' = LRA.RealValue.cst (A.of_int 1) in
+  let t3 = LRA.mult_cst env (A.of_int 2) b in
+  let t3' = LRA.RealValue.cst (A.of_int 1) in
   Shuffle.seql
     [
       (fun () ->
@@ -216,9 +214,9 @@ let mult1 _ =
   let t1' = LRA.add env b c in
   let t1' = LRA.mult env t1' a in
   let t2 = a in
-  let t2' = LRA.RealValue.cst (Q.of_int 2) in
+  let t2' = LRA.RealValue.cst (A.of_int 2) in
   let t3 = c in
-  let t3' = LRA.RealValue.cst (Q.of_int 1) in
+  let t3' = LRA.RealValue.cst (A.of_int 1) in
   Shuffle.seql
     [
       (fun () ->
diff --git a/src_colibri2/theories/FP/fp_value.ml b/src_colibri2/theories/FP/fp_value.ml
index b0d616b7db9c4ce84b4b97c9b18ce2c1439b4e01..85f19507a2204d601e65b7096b993981d3b8715a 100644
--- a/src_colibri2/theories/FP/fp_value.ml
+++ b/src_colibri2/theories/FP/fp_value.ml
@@ -36,7 +36,6 @@ module Float = Value.Register (F)
 include Float
 
 let cst' c = index c
-
 let cst c = node (cst' c)
 
 let debug =
@@ -93,7 +92,8 @@ let compute_ground d t =
   match Ground.sem t with
   | { app = { builtin = Expr.Real_to_fp (ew, prec); _ }; args; _ } ->
       let m, r = IArray.extract2_exn args in
-      !<(F.of_q ~ew ~mw:(prec - 1) ~mode:!>>m !>>>r)
+      let r = match !>>>r with Q q -> q | A _ -> assert false (* TODO *) in
+      !<(F.of_q ~ew ~mw:(prec - 1) ~mode:!>>m r)
   | { app = { builtin = Expr.Fp_to_fp (_ew1, _prec1, ew2, prec2); _ }; args; _ }
     ->
       let m, f1 = IArray.extract2_exn args in
@@ -125,7 +125,7 @@ let compute_ground d t =
            (Colibri2_theories_LRA.RealValue.unsigned_bitv (ew + prec) !>>>bv))
   | { app = { builtin = Expr.To_real (_ew, _prec); _ }; args; _ } ->
       let r = IArray.extract1_exn args in
-      !<<<(F.to_q !>r)
+      !<<<(A.of_q (F.to_q !>r))
   | { app = { builtin = Expr.Plus_infinity (ew, prec); _ }; args; _ } ->
       assert (IArray.is_empty args);
       !<(F.inf ~ew ~mw:(prec - 1) false)
@@ -254,8 +254,11 @@ let converter d (f : Ground.t) =
       Debug.dprintf2 debug "[FP] assign a value to %a" Node.pp a;
       attach d
         (set r
-           (let+ va = getq a in
-            F.of_q ~ew ~mw:(prec - 1) ~mode:!>>m va))
+           (let* va = getq a in
+            match va with
+            | Q va -> Some (F.of_q ~ew ~mw:(prec - 1) ~mode:!>>m va)
+            | A _ -> None
+            (* TODO *)))
   | { app = { builtin = Expr.NaN (ew, prec); _ }; args; _ } ->
       assert (IArray.is_empty args);
       merge (cst (F.nan ~ew ~mw:(prec - 1)))
diff --git a/src_colibri2/theories/LRA/LRA.mli b/src_colibri2/theories/LRA/LRA.mli
index 5c4bcd55d4a7bc319fb1d2b25c54ccf4a4547e7d..f408dfea11252abea55132f01df1a4b0d5630ab6 100644
--- a/src_colibri2/theories/LRA/LRA.mli
+++ b/src_colibri2/theories/LRA/LRA.mli
@@ -19,12 +19,10 @@
 (*************************************************************************)
 
 module RealValue : sig
-  include Value.S with type s = Q.t
-
-  val cst' : Q.t -> t
-
-  val cst : Q.t -> Node.t
+  include Value.S with type s = A.t
 
+  val cst' : A.t -> t
+  val cst : A.t -> Node.t
   val zero : Node.t
 end
 
@@ -32,24 +30,14 @@ val th_register : Egraph.wt -> unit
 
 (** helpers to remove *)
 
-val add' : _ Egraph.t -> Q.t -> Node.t -> Q.t -> Node.t -> Node.t
-
+val add' : _ Egraph.t -> A.t -> Node.t -> A.t -> Node.t -> Node.t
 val add : _ Egraph.t -> Node.t -> Node.t -> Node.t
-
 val sub : _ Egraph.t -> Node.t -> Node.t -> Node.t
-
-val mult_cst : _ Egraph.t -> Q.t -> Node.t -> Node.t
-
+val mult_cst : _ Egraph.t -> A.t -> Node.t -> Node.t
 val mult : _ Egraph.t -> Node.t -> Node.t -> Node.t
-
 val gt_zero : _ Egraph.t -> Node.t -> Node.t
-
 val ge_zero : _ Egraph.t -> Node.t -> Node.t
-
 val lt : _ Egraph.t -> Node.t -> Node.t -> Node.t
-
 val le : _ Egraph.t -> Node.t -> Node.t -> Node.t
-
 val gt : _ Egraph.t -> Node.t -> Node.t -> Node.t
-
 val ge : _ Egraph.t -> Node.t -> Node.t -> Node.t
diff --git a/src_colibri2/theories/LRA/delta.ml b/src_colibri2/theories/LRA/delta.ml
index b508b5a5b01a482c7c27cfbabbb1604262be844d..130c89299f8f0432bdaeb09c1e2e58f0e61b0c61 100644
--- a/src_colibri2/theories/LRA/delta.ml
+++ b/src_colibri2/theories/LRA/delta.ml
@@ -22,62 +22,50 @@
    doesn't compute distances *)
 
 module Edge = struct
-
   module T = struct
-    type t = {
-      src: Node.t;
-      dst: Node.t;
-    }
-    [@@deriving ord, eq, hash]
-
-
-    let pp fmt t =
-      Fmt.pf fmt "%a -> %a" Node.pp t.src Node.pp t.dst
+    type t = { src : Node.t; dst : Node.t } [@@deriving ord, eq, hash]
 
+    let pp fmt t = Fmt.pf fmt "%a -> %a" Node.pp t.src Node.pp t.dst
   end
 
   include T
-  include Colibri2_popop_lib.Popop_stdlib.MkDatatype(T)
-
+  include Colibri2_popop_lib.Popop_stdlib.MkDatatype (T)
 end
 
 module Dist = struct
-  type t = { q: Q.t; bound: Bound.t }
-  [@@deriving show]
+  type t = { q : A.t; bound : Bound.t } [@@deriving show]
 
   let min d1 d2 =
-    let c = Q.compare d1.q d2.q in
+    let c = A.compare d1.q d2.q in
     if c = 0 then
-      let bound = match d1.bound, d2.bound with
-      | Large, Large -> Bound.Large
-      | _ -> Strict
+      let bound =
+        match (d1.bound, d2.bound) with
+        | Large, Large -> Bound.Large
+        | _ -> Strict
       in
       { q = d1.q; bound }
-    else if c < 0 then d1 else d2
+    else if c < 0 then d1
+    else d2
 
   let included d1 d2 =
-    let c = Q.compare d1.q d2.q in
+    let c = A.compare d1.q d2.q in
     if c = 0 then
-      match d1.bound, d2.bound with
-        | Large, Strict -> false
-        | _ -> true
+      match (d1.bound, d2.bound) with Large, Strict -> false | _ -> true
     else c < 0
-
 end
 
-module HEdge = Datastructure.Hashtbl(Edge)
+module HEdge = Datastructure.Hashtbl (Edge)
 
 let edges = HEdge.create Dist.pp "Delta.edges"
 (* src - dst <= q *)
 
 let ty_real = Ground.Ty.convert Expr.Ty.Var.M.empty Expr.Ty.real
-
 let a = Expr.Term.Var.mk "a" Expr.Ty.real
 let ta = Expr.Term.of_var a
 
-let floor_pattern = (* Other floor functions? *)
-  Colibri2_theories_quantifiers.Pattern.of_term
-    ~subst:Ground.Subst.empty
+let floor_pattern =
+  (* Other floor functions? *)
+  Colibri2_theories_quantifiers.Pattern.of_term ~subst:Ground.Subst.empty
     (Expr.Term.Real.floor_to_int ta)
 
 (* let ceiling_patterns =
@@ -85,52 +73,57 @@ let floor_pattern = (* Other floor functions? *)
  *     (Expr.Term.Real.ceiling ta) *)
 
 let ceiling_pattern =
-  Colibri2_theories_quantifiers.Pattern.of_term
-    ~subst:Ground.Subst.empty
-    (Expr.Term.Int.minus (Expr.Term.Real.floor_to_int (Expr.Term.Real.minus ta)))
-
+  Colibri2_theories_quantifiers.Pattern.of_term ~subst:Ground.Subst.empty
+    (Expr.Term.Int.minus
+       (Expr.Term.Real.floor_to_int (Expr.Term.Real.minus ta)))
 
 let event d src dst =
-    match HEdge.find_opt edges d { src; dst },
-          HEdge.find_opt edges d { dst; src } with
-    | Some d1, Some d2 ->
+  match
+    (HEdge.find_opt edges d { src; dst }, HEdge.find_opt edges d { dst; src })
+  with
+  | Some d1, Some d2 ->
       let aux src dst d1 d2 =
-        if Dist.included d1 { q = Q.one; bound = Strict } &&
-           Dist.included d2 { q = Q.zero; bound = Large } then
+        if
+          Dist.included d1 { q = A.one; bound = Strict }
+          && Dist.included d2 { q = A.zero; bound = Large }
+        then
           if Dom_interval.is_integer d src then
             (* 0 <= src - dst < 1 => src:Int => src = ceil(dst) *)
             let s =
               Colibri2_theories_quantifiers.Pattern.check_term_exists d
-                { Ground.Subst.empty with term = Expr.Term.Var.M.singleton a dst }
-                ceiling_pattern in
+                {
+                  Ground.Subst.empty with
+                  term = Expr.Term.Var.M.singleton a dst;
+                }
+                ceiling_pattern
+            in
             Node.S.iter (Egraph.merge d src) s
           else if Dom_interval.is_integer d dst then
             (* 0 <= src - dst < 1 => dst:Int => dst = floor(src) *)
             let s =
               Colibri2_theories_quantifiers.Pattern.check_term_exists d
-                { Ground.Subst.empty with term = Expr.Term.Var.M.singleton a src }
-                floor_pattern in
+                {
+                  Ground.Subst.empty with
+                  term = Expr.Term.Var.M.singleton a src;
+                }
+                floor_pattern
+            in
             Node.S.iter (Egraph.merge d dst) s
       in
       aux src dst d1 d2;
       aux dst src d2 d1
-    | _ -> ()
+  | _ -> ()
 
 let add d src q bound dst =
   let d' = { Dist.q; bound } in
   HEdge.change
-    (function
-      | Some d ->
-        Some (Dist.min d d')
-      | None -> Some d')
-    edges d {src;dst};
+    (function Some d -> Some (Dist.min d d') | None -> Some d')
+    edges d { src; dst };
   (* Could be only when a change append *)
   event d src dst
 
-
 let add_le d src q dst = add d src q Large dst
 let add_lt d src q dst = add d src q Strict dst
 let add_ge d src q dst = add d dst q Large src
 let add_gt d src q dst = add d dst q Strict src
-
 let th_register _ = ()
diff --git a/src_colibri2/theories/LRA/delta.mli b/src_colibri2/theories/LRA/delta.mli
index b54fef6b21f8b05b415ad95ed21d4314b748cac5..6e0459004f67360c485d3146e3c3c3adb046ad74 100644
--- a/src_colibri2/theories/LRA/delta.mli
+++ b/src_colibri2/theories/LRA/delta.mli
@@ -20,21 +20,25 @@
 
 (** Distance Graph *)
 
-
-val add_le: Egraph.wt -> Node.t -> Q.t -> Node.t -> unit
+val add_le : Egraph.wt -> Node.t -> A.t -> Node.t -> unit
 (* [add_le d n1 q n2] n1 - n2 <= q *)
 
-val add_lt: Egraph.wt -> Node.t -> Q.t -> Node.t -> unit
+val add_lt : Egraph.wt -> Node.t -> A.t -> Node.t -> unit
 (* [add_lt d n1 q n2] n1 - n2 < q *)
 
-val add_ge: Egraph.wt -> Node.t -> Q.t -> Node.t -> unit
+val add_ge : Egraph.wt -> Node.t -> A.t -> Node.t -> unit
 (* [add_ge d n1 q n2] n1 - n2 >= q *)
 
-val add_gt: Egraph.wt -> Node.t -> Q.t -> Node.t -> unit
+val add_gt : Egraph.wt -> Node.t -> A.t -> Node.t -> unit
 (* [add_gt d n1 q n2] n1 - n2 > q *)
 
-val add: Egraph.wt -> Node.t -> Q.t -> Colibri2_theories_LRA_stages_def.Bound.t -> Node.t -> unit
+val add :
+  Egraph.wt ->
+  Node.t ->
+  A.t ->
+  Colibri2_theories_LRA_stages_def.Bound.t ->
+  Node.t ->
+  unit
 (* [add d n1 q bound n2] n1 - n2 <= q or < q *)
 
-val th_register: Egraph.wt -> unit
-
+val th_register : Egraph.wt -> unit
diff --git a/src_colibri2/theories/LRA/dom_interval.ml b/src_colibri2/theories/LRA/dom_interval.ml
index 4cd18bef6ab46015d381ca27447c7432e6d14d7d..84cc524771ad33ad890da9f18dd2a8abe969aab3 100644
--- a/src_colibri2/theories/LRA/dom_interval.ml
+++ b/src_colibri2/theories/LRA/dom_interval.ml
@@ -40,7 +40,6 @@ include Dom.Lattice (struct
   include D
 
   let key = dom
-
   let inter _ d1 d2 = inter d1 d2
 
   let is_singleton _ d =
@@ -62,7 +61,7 @@ let is_zero_or_positive d n =
 let is_not_zero d n =
   match Egraph.get_dom d dom n with
   | None -> false
-  | Some p -> D.absent Q.zero p
+  | Some p -> D.absent A.zero p
 
 let is_strictly_positive d n =
   match Egraph.get_dom d dom n with
@@ -80,9 +79,8 @@ let is_strictly_negative d n =
       | D.Gt -> true
       | D.Eq | D.Le | D.Ge | D.Lt | D.Uncomparable -> false)
 
-let assume_negative d n = upd_dom d n (D.lt Q.zero)
-
-let assume_positive d n = upd_dom d n (D.gt Q.zero)
+let assume_negative d n = upd_dom d n (D.lt A.zero)
+let assume_positive d n = upd_dom d n (D.gt A.zero)
 
 let zero_is d n =
   let r =
@@ -125,9 +123,7 @@ module ChoLRA = struct
 end
 
 let choice = ChoLRA.choice
-
 let neg_cmp = function `Lt -> `Ge | `Le -> `Gt | `Ge -> `Lt | `Gt -> `Le
-
 let com_cmp = function `Lt -> `Gt | `Le -> `Ge | `Ge -> `Le | `Gt -> `Lt
 
 let backward = function
@@ -141,11 +137,8 @@ module Propagate = struct
   open Monad
 
   let setb = setv Boolean.dom
-
   let getb = getv Boolean.dom
-
   let set = updd upd_dom
-
   let get = getd dom
 
   let sub d ~r ~a ~b =
@@ -233,10 +226,10 @@ module Propagate = struct
         attach d
           (set r
              (let+ va = get a in
-              D.mult_cst Q.minus_one va)
+              D.mult_cst A.minus_one va)
           && set a
                (let+ vr = get r in
-                D.mult_cst Q.minus_one vr))
+                D.mult_cst A.minus_one vr))
     | { app = { builtin = Expr.Lt }; tyargs = []; args; _ } ->
         let a, b = IArray.extract2_exn args in
         cmp d `Lt ~r ~a ~b
@@ -276,7 +269,7 @@ let init env =
             (if D.is_integer inter then
              Interp.SeqLim.of_seq d
                (Base.Sequence.filter_map RealValue.int_sequence ~f:(fun z ->
-                    let q = Q.of_bigint z in
+                    let q = A.of_bigint z in
                     if D.mem q inter then Some RealValue.(nodevalue (cst' q))
                     else None))
             else
diff --git a/src_colibri2/theories/LRA/dom_interval.mli b/src_colibri2/theories/LRA/dom_interval.mli
index 108d1a0636ca4d9a29d9339c096bb4037bfe8457..8c230330ac716b16c0a5850092a6cf1eac6d35de 100644
--- a/src_colibri2/theories/LRA/dom_interval.mli
+++ b/src_colibri2/theories/LRA/dom_interval.mli
@@ -23,31 +23,20 @@ val init : Egraph.wt -> unit
 module D : sig
   include Colibri2_theories_LRA_stages_def.Interval_sig.S
 
-  val get_convexe_hull : t -> (Q.t * Bound.t) option * (Q.t * Bound.t) option
-
-  val from_convexe_hull : (Q.t * Bound.t) option * (Q.t * Bound.t) option -> t
+  val get_convexe_hull : t -> (A.t * Bound.t) option * (A.t * Bound.t) option
+  val from_convexe_hull : (A.t * Bound.t) option * (A.t * Bound.t) option -> t
 end
 
 val dom : D.t Dom.Kind.t
-
 val get_dom : _ Egraph.t -> Node.t -> D.t option
-
 val upd_dom : Egraph.wt -> Node.t -> D.t -> unit
-
 val is_zero_or_positive : _ Egraph.t -> Node.t -> bool
-
 val is_not_zero : _ Egraph.t -> Node.t -> bool
-
 val is_strictly_positive : _ Egraph.t -> Node.t -> bool
-
 val is_strictly_negative : _ Egraph.t -> Node.t -> bool
-
 val is_integer : _ Egraph.t -> Node.t -> bool
-
 val zero_is : _ Egraph.t -> Node.t -> D.is_comparable
-
 val assume_positive : Egraph.wt -> Node.t -> unit
-
 val assume_negative : Egraph.wt -> Node.t -> unit
 
 module Propagate : sig
diff --git a/src_colibri2/theories/LRA/dom_polynome.ml b/src_colibri2/theories/LRA/dom_polynome.ml
index db5b7dfdffadc70460d32d0caa0a8231972fccc5..e6b5dcfd2054e17ee52384c08e278381a994a789 100644
--- a/src_colibri2/theories/LRA/dom_polynome.ml
+++ b/src_colibri2/theories/LRA/dom_polynome.ml
@@ -60,12 +60,10 @@ include Pivot.Total (struct
 
   let name = "LRA.polynome"
 
-  type data = Q.t
+  type data = A.t
 
   let nodes p = p.poly
-
-  let of_one_node n = monome Q.one n
-
+  let of_one_node n = monome A.one n
   let subst p n q = fst (subst p n q)
 
   let normalize p ~f =
@@ -90,12 +88,12 @@ include Pivot.Total (struct
     | Cst c ->
         (* 0 = cst <> 0 *)
         Debug.dprintf2 Debug.contradiction
-          "[LRA/Poly] Found 0 = %a when merging" Q.pp c;
+          "[LRA/Poly] Found 0 = %a when merging" A.pp c;
         Contradiction
     | Var (q, x, p') ->
-        assert (not (Q.equal Q.zero q));
+        assert (not (A.equal A.zero q));
         (* diff = qx + p' *)
-        Subst (x, Polynome.mult_cst (Q.div Q.one (Q.neg q)) p')
+        Subst (x, Polynome.mult_cst (A.div A.one (A.neg q)) p')
 end)
 
 let node_of_polynome d p =
@@ -119,17 +117,17 @@ let converter d (f : Ground.t) =
       let a, b = IArray.extract2_exn args in
       reg a;
       reg b;
-      assume_equality d res (Polynome.of_list Q.zero [ (a, Q.one); (b, Q.one) ])
+      assume_equality d res (Polynome.of_list A.zero [ (a, A.one); (b, A.one) ])
   | { app = { builtin = Expr.Sub }; tyargs = []; args; _ } ->
       let a, b = IArray.extract2_exn args in
       reg a;
       reg b;
       assume_equality d res
-        (Polynome.of_list Q.zero [ (a, Q.one); (b, Q.minus_one) ])
+        (Polynome.of_list A.zero [ (a, A.one); (b, A.minus_one) ])
   | { app = { builtin = Expr.Minus }; tyargs = []; args; _ } ->
       let a = IArray.extract1_exn args in
       reg a;
-      assume_equality d res (Polynome.of_list Q.zero [ (a, Q.minus_one) ])
+      assume_equality d res (Polynome.of_list A.zero [ (a, A.minus_one) ])
   | _ -> ()
 
 let init env =
diff --git a/src_colibri2/theories/LRA/dom_product.ml b/src_colibri2/theories/LRA/dom_product.ml
index 5fac1540159d6ae44cb7c8f273c6f3dc7831e9e5..1b61a57f466445fcf24be0c77459427e8527d60d 100644
--- a/src_colibri2/theories/LRA/dom_product.ml
+++ b/src_colibri2/theories/LRA/dom_product.ml
@@ -86,11 +86,8 @@ let set d cl ~old_abs ~old_sign abs sign =
 
 module rec SolveAbs : sig
   val assume_equality : Egraph.wt -> Node.t -> Product.t -> unit
-
   val init : Egraph.wt -> unit
-
   val get_repr : _ Egraph.t -> Node.t -> Product.t option
-
   val iter_eqs : _ Egraph.t -> Node.t -> f:(Product.t -> unit) -> unit
 
   val attach_repr_change :
@@ -104,7 +101,6 @@ end = Pivot.WithUnsolved (struct
   include Product
 
   let pp fmt p = Fmt.pf fmt "|%a|" pp p
-
   let of_one_node _ n = Product.monome n Q.one
 
   let subst p n q =
@@ -178,11 +174,8 @@ end)
 
 and SolveSign : sig
   val assume_equality : Egraph.wt -> Node.t -> Sign_product.t -> unit
-
   val init : Egraph.wt -> unit
-
   val get_repr : _ Egraph.t -> Node.t -> Sign_product.t option
-
   val iter_eqs : _ Egraph.t -> Node.t -> f:(Sign_product.t -> unit) -> unit
 
   val attach_repr_change :
@@ -262,15 +255,15 @@ let factorize res a coef b d _ =
                 | ONE, PLUS_ONE -> (Q.add v cst, acc)
                 | ONE, MINUS_ONE -> (Q.sub v cst, acc)
                 | NODE n, NODE n' when Egraph.is_equal d n n' ->
-                    (cst, (n, v) :: acc)
+                    (cst, (n, A.of_q v) :: acc)
                 | _ ->
                     let n = node_of_product d abs sign in
                     Egraph.register d n;
-                    (cst, (n, v) :: acc))
+                    (cst, (n, A.of_q v) :: acc))
               (Q.zero, [])
               [ (pa, sa, Q.one); (pb, sb, coef) ]
           in
-          let p = Polynome.of_list cst l in
+          let p = Polynome.of_list (A.of_q cst) l in
           let n = Dom_polynome.node_of_polynome d p in
           let pp_coef fmt coef =
             if Q.equal Q.one coef then Fmt.pf fmt "+" else Fmt.pf fmt "-"
@@ -349,9 +342,9 @@ let init env =
       match Dom_polynome.get_repr d n with
       | None -> ()
       | Some p ->
-          if Q.equal p.cst Q.zero && Node.M.is_num_elt 1 p.poly then
+          if A.equal p.cst A.zero && Node.M.is_num_elt 1 p.poly then
             let cl, q = Node.M.choose p.poly in
-            if Q.equal q Q.one then (
+            if A.equal q A.one then (
               let p1 = Product.of_list [ (cl, Q.one) ] in
               Debug.dprintf4 debug "[Polynome->Product] propagate %a is %a"
                 Node.pp n Node.pp cl;
@@ -366,7 +359,7 @@ let init env =
             SolveSign.iter_eqs d n ~f:(fun p ->
                 match Sign_product.is_one_node p with
                 | Some cl' when Egraph.is_equal d cl cl' ->
-                    let p1 = Polynome.of_list Q.zero [ (cl, Q.one) ] in
+                    let p1 = Polynome.of_list A.zero [ (cl, A.one) ] in
                     Debug.dprintf4 debug
                       "[Product->Polynome] propagate %a is %a" Node.pp n Node.pp
                       cl;
diff --git a/src_colibri2/theories/LRA/fourier.ml b/src_colibri2/theories/LRA/fourier.ml
index 1ddd70a4b0878554656c70a1387257d92992280b..57a14ad7851ba03f1643aba69097a58cceac6270 100644
--- a/src_colibri2/theories/LRA/fourier.ml
+++ b/src_colibri2/theories/LRA/fourier.ml
@@ -30,7 +30,6 @@ let debug =
   Debug.register_info_flag ~desc:"Reasoning about <= < in LRA" "fourier"
 
 let stats_run = Debug.register_stats_int "Fourier.run"
-
 let stats_time = Debug.register_stats_time "Fourier.time"
 
 type eq = { p : Polynome.t; bound : Bound.t; origins : Ground.S.t }
@@ -40,7 +39,7 @@ type eq = { p : Polynome.t; bound : Bound.t; origins : Ground.S.t }
 let divide d (p : Polynome.t) =
   try
     (match Polynome.is_cst p with None -> () | Some _ -> raise Exit);
-    if Q.sign p.cst <> 0 then raise Exit;
+    if A.sign p.cst <> 0 then raise Exit;
     let l = Node.M.bindings p.poly in
     let l =
       List.fold_left
@@ -55,7 +54,7 @@ let divide d (p : Polynome.t) =
         [] l
     in
     (* Debug.dprintf4 debug "@[eq:%a@ %a@]" Polynome.pp p
-     *   Fmt.(list ~sep:(any "+") (using CCPair.swap (pair Q.pp Product.pp)))
+     *   Fmt.(list ~sep:(any "+") (using CCPair.swap (pair A.pp Product.pp)))
      *   l; *)
     match l with
     | [] -> raise Exit
@@ -85,17 +84,17 @@ let divide d (p : Polynome.t) =
               let abs = Product.div abs common in
               let pos, sign = Sign_product.extract_cst sign in
               let v =
-                match pos with Zero -> Q.zero | Pos -> v | Neg -> Q.neg v
+                match pos with Zero -> A.zero | Pos -> v | Neg -> A.neg v
               in
               match (Product.classify abs, Sign_product.classify sign) with
               | _, MINUS_ONE -> assert false
-              | ONE, PLUS_ONE -> (Q.add v cst, acc)
+              | ONE, PLUS_ONE -> (A.add v cst, acc)
               | NODE n, NODE n' when Egraph.is_equal d n n' ->
                   (cst, (n, v) :: acc)
               | _ ->
                   let n = Dom_product.node_of_product d abs sign in
                   (cst, (n, v) :: acc))
-            (Q.zero, []) l
+            (A.zero, []) l
         in
         Some (Polynome.of_list cst l, common)
   with Exit -> None
@@ -104,10 +103,10 @@ let delta d eq =
   (* add info to delta *)
   if Node.M.is_num_elt 2 eq.p.poly then
     match Node.M.bindings eq.p.poly with
-    | [ (src, a); (dst, b) ] when Q.equal Q.one a && Q.equal Q.minus_one b ->
-        Delta.add d src (Q.neg eq.p.cst) eq.bound dst
-    | [ (dst, b); (src, a) ] when Q.equal Q.one a && Q.equal Q.minus_one b ->
-        Delta.add d src (Q.neg eq.p.cst) eq.bound dst
+    | [ (src, a); (dst, b) ] when A.equal A.one a && A.equal A.minus_one b ->
+        Delta.add d src (A.neg eq.p.cst) eq.bound dst
+    | [ (dst, b); (src, a) ] when A.equal A.one a && A.equal A.minus_one b ->
+        Delta.add d src (A.neg eq.p.cst) eq.bound dst
     | _ -> ()
 
 let apply d ~f truth g =
@@ -140,7 +139,7 @@ let add_eq d eqs p bound origins =
       let eq = { p; bound; origins } in
       delta d eq;
       eq :: eqs
-  | Some p, Bound.Large when Q.sign p = 0 ->
+  | Some p, Bound.Large when A.sign p = 0 ->
       Ground.S.iter
         (fun g ->
           let truth = Base.Option.value_exn (Boolean.is d (Ground.node g)) in
@@ -150,8 +149,8 @@ let add_eq d eqs p bound origins =
                 | Strict
                   when Dom_interval.is_integer d a
                        && Dom_interval.is_integer d b ->
-                    Polynome.of_list Q.minus_one [ (b, Q.one) ]
-                | Large -> Polynome.monome Q.one b
+                    Polynome.of_list A.minus_one [ (b, A.one) ]
+                | Large -> Polynome.monome A.one b
                 | Strict -> assert false
               in
               Debug.dprintf4 debug "[LRA/Fourier] Found %a = %a" Node.pp a
@@ -159,30 +158,30 @@ let add_eq d eqs p bound origins =
               Dom_polynome.assume_equality d a p))
         origins;
       eqs
-  | Some p, _ when Q.sign p < 0 ->
+  | Some p, _ when A.sign p < 0 ->
       Debug.dprintf2 debug "[Fourier] discard %a" Ground.S.pp origins;
       eqs
   | Some p, bound ->
-      Debug.dprintf6 Debug.contradiction "[LRA/Fourier] Found %a%a0 by %a" Q.pp
+      Debug.dprintf6 Debug.contradiction "[LRA/Fourier] Found %a%a0 by %a" A.pp
         p Bound.pp bound Ground.S.pp origins;
       Egraph.contradiction d
 
 let mk_eq d bound a b =
   let ( ! ) n =
     match Dom_polynome.get_repr d n with
-    | None -> Polynome.monome Q.one (Egraph.find_def d n)
+    | None -> Polynome.monome A.one (Egraph.find_def d n)
     | Some p -> p
   in
   let p, bound' =
     match bound with
     | Bound.Strict
       when Dom_interval.is_integer d a && Dom_interval.is_integer d b ->
-        (Polynome.add_cst (Polynome.sub !a !b) Q.one, Bound.Large)
+        (Polynome.add_cst (Polynome.sub !a !b) A.one, Bound.Large)
     | _ -> (Polynome.sub !a !b, bound)
   in
   ( p,
     bound',
-    Polynome.sub (Polynome.monome Q.one a) (Polynome.monome Q.one b),
+    Polynome.sub (Polynome.monome A.one a) (Polynome.monome A.one b),
     bound )
 
 let make_equations d (eqs, vars) g =
@@ -218,7 +217,7 @@ let fm (d : Egraph.wt) =
         match Node.M.find_opt n eq.p.poly with
         | None -> split n positive negative (eq :: absent) l
         | Some q ->
-            if Q.sign q > 0 then split n ((q, eq) :: positive) negative absent l
+            if A.sign q > 0 then split n ((q, eq) :: positive) negative absent l
             else split n positive ((q, eq) :: negative) absent l)
   in
   let rec aux eqs vars =
@@ -233,8 +232,8 @@ let fm (d : Egraph.wt) =
             let eqs =
               Lists.fold_product
                 (fun eqs (pq, peq) (nq, neq) ->
-                  let q = Q.div pq (Q.neg nq) in
-                  let p = Polynome.cx_p_cy Q.one peq.p q neq.p in
+                  let q = A.div pq (A.neg nq) in
+                  let p = Polynome.cx_p_cy A.one peq.p q neq.p in
                   let bound =
                     match (peq.bound, neq.bound) with
                     | Large, Large -> Bound.Large
@@ -287,7 +286,6 @@ module Daemon = struct
   type runable = unit
 
   let print_runable = Unit.pp
-
   let run d () = fm d
 end
 
diff --git a/src_colibri2/theories/LRA/polynome.ml b/src_colibri2/theories/LRA/polynome.ml
index d9aca9efd583d65b53008fa6e7094c89d2bc1b71..e8d19adbcabb6529448c067a97441fc39e28d2b8 100644
--- a/src_colibri2/theories/LRA/polynome.ml
+++ b/src_colibri2/theories/LRA/polynome.ml
@@ -23,11 +23,11 @@ open Colibri2_core
 
 let print_poly fmt poly =
   let print_not_1 first fmt q =
-    if (not first) && Q.compare q Q.zero >= 0 then
+    if (not first) && A.compare q A.zero >= 0 then
       Format.pp_print_string fmt "+";
-    if Q.equal q Q.zero then Format.pp_print_string fmt "!0!"
-    else if Q.equal Q.minus_one q then Format.pp_print_string fmt "-"
-    else if not (Q.equal Q.one q) then Q.pp fmt q
+    if A.equal q A.zero then Format.pp_print_string fmt "!0!"
+    else if A.equal A.minus_one q then Format.pp_print_string fmt "-"
+    else if not (A.equal A.one q) then A.pp fmt q
   in
   let print_mono k v (fmt, first) =
     Format.fprintf fmt "@[%a%a@]@," (print_not_1 first) v Node.pp k;
@@ -37,14 +37,14 @@ let print_poly fmt poly =
   first
 
 module T = struct
-  type t = { cst : Q.t; poly : Q.t Node.M.t } [@@deriving eq, ord, hash]
+  type t = { cst : A.t; poly : A.t Node.M.t } [@@deriving eq, ord, hash]
 
   let pp fmt v =
     let print_not_0 first fmt q =
-      if first then Q.pp fmt q
-      else if not (Q.equal Q.zero q) then (
-        if Q.compare q Q.zero > 0 then Format.pp_print_string fmt "+";
-        Q.pp fmt q)
+      if first then A.pp fmt q
+      else if not (A.equal A.zero q) then (
+        if A.compare q A.zero > 0 then Format.pp_print_string fmt "+";
+        A.pp fmt q)
     in
 
     Format.fprintf fmt "@[";
@@ -57,22 +57,20 @@ include Popop_stdlib.MkDatatype (T)
 
 (** different invariant *)
 
-let invariant p = Node.M.for_all (fun _ q -> not (Q.equal q Q.zero)) p.poly
+let invariant p = Node.M.for_all (fun _ q -> not (A.equal q A.zero)) p.poly
 
 (** constructor *)
 let cst q = { cst = q; poly = Node.M.empty }
 
-let zero = cst Q.zero
-
+let zero = cst A.zero
 let is_cst p = if Node.M.is_empty p.poly then Some p.cst else None
+let is_zero p = A.equal p.cst A.zero && Node.M.is_empty p.poly
 
-let is_zero p = Q.equal p.cst Q.zero && Node.M.is_empty p.poly
-
-type extract = Zero | Cst of Q.t | Var of Q.t * Node.t * t
+type extract = Zero | Cst of A.t | Var of A.t * Node.t * t
 
 let extract p =
   if Node.M.is_empty p.poly then
-    if Q.equal p.cst Q.zero then Zero else Cst p.cst
+    if A.equal p.cst A.zero then Zero else Cst p.cst
   else
     (* max binding is more interesting than choose (min binding) because it
        force results to be choosen as pivot*)
@@ -83,80 +81,79 @@ let extract p =
 type kind = ZERO | CST | VAR
 
 let classify p =
-  if Node.M.is_empty p.poly then if Q.equal p.cst Q.zero then ZERO else CST
+  if Node.M.is_empty p.poly then if A.equal p.cst A.zero then ZERO else CST
   else VAR
 
 let monome c x =
-  if Q.equal Q.zero c then cst Q.zero
-  else { cst = Q.zero; poly = Node.M.singleton x c }
+  if A.equal A.zero c then cst A.zero
+  else { cst = A.zero; poly = Node.M.singleton x c }
 
 let is_one_node p =
   (* cst = 0 and one empty monome *)
-  if Q.equal Q.zero p.cst && Node.M.is_num_elt 1 p.poly then
+  if A.equal A.zero p.cst && Node.M.is_num_elt 1 p.poly then
     let node, k = Node.M.choose p.poly in
-    if Q.equal Q.one k then Some node else None
+    if A.equal A.one k then Some node else None
   else None
 
-let sub_cst p q = { p with cst = Q.sub p.cst q }
-
-let add_cst p q = { p with cst = Q.add p.cst q }
+let sub_cst p q = { p with cst = A.sub p.cst q }
+let add_cst p q = { p with cst = A.add p.cst q }
 
 let mult_cst c p1 =
-  if Q.equal Q.one c then p1
+  if A.equal A.one c then p1
   else
-    let poly_mult c m = Node.M.map (fun c1 -> Q.mul c c1) m in
-    if Q.equal Q.zero c then cst Q.zero
-    else { cst = Q.mul c p1.cst; poly = poly_mult c p1.poly }
+    let poly_mult c m = Node.M.map (fun c1 -> A.mul c c1) m in
+    if A.equal A.zero c then cst A.zero
+    else { cst = A.mul c p1.cst; poly = poly_mult c p1.poly }
 
-let none_zero c = if Q.equal Q.zero c then None else Some c
+let none_zero c = if A.equal A.zero c then None else Some c
 
 (** Warning Node.M.union can be used only for defining an operation [op]
     that verifies [op 0 p = p] and [op p 0 = p] *)
 let add p1 p2 =
   let poly_add m1 m2 =
-    Node.M.union (fun _ c1 c2 -> none_zero (Q.add c1 c2)) m1 m2
+    Node.M.union (fun _ c1 c2 -> none_zero (A.add c1 c2)) m1 m2
   in
-  { cst = Q.add p1.cst p2.cst; poly = poly_add p1.poly p2.poly }
+  { cst = A.add p1.cst p2.cst; poly = poly_add p1.poly p2.poly }
 
 let sub p1 p2 =
   let poly_sub m1 m2 =
     Node.M.union_merge
       (fun _ c1 c2 ->
         match c1 with
-        | None -> Some (Q.neg c2)
-        | Some c1 -> none_zero (Q.sub c1 c2))
+        | None -> Some (A.neg c2)
+        | Some c1 -> none_zero (A.sub c1 c2))
       m1 m2
   in
-  { cst = Q.sub p1.cst p2.cst; poly = poly_sub p1.poly p2.poly }
+  { cst = A.sub p1.cst p2.cst; poly = poly_sub p1.poly p2.poly }
 
 let x_p_cy p1 c p2 =
-  assert (not (Q.equal c Q.zero));
-  let f a b = Q.add a (Q.mul c b) in
+  assert (not (A.equal c A.zero));
+  let f a b = A.add a (A.mul c b) in
   let poly m1 m2 =
     Node.M.union_merge
       (fun _ c1 c2 ->
         match c1 with
-        | None -> Some (Q.mul c c2)
+        | None -> Some (A.mul c c2)
         | Some c1 -> none_zero (f c1 c2))
       m1 m2
   in
   { cst = f p1.cst p2.cst; poly = poly p1.poly p2.poly }
 
 let cx_p_cy c1 p1 c2 p2 =
-  let c1_iszero = Q.equal c1 Q.zero in
-  let c2_iszero = Q.equal c2 Q.zero in
+  let c1_iszero = A.equal c1 A.zero in
+  let c2_iszero = A.equal c2 A.zero in
   if c1_iszero && c2_iszero then zero
   else if c1_iszero then p2
   else if c2_iszero then p1
   else
-    let f e1 e2 = Q.add (Q.mul c1 e1) (Q.mul c2 e2) in
+    let f e1 e2 = A.add (A.mul c1 e1) (A.mul c2 e2) in
     let poly m1 m2 =
       Node.M.merge
         (fun _ e1 e2 ->
           match (e1, e2) with
           | None, None -> assert false
-          | None, Some e2 -> Some (Q.mul c2 e2)
-          | Some e1, None -> Some (Q.mul c1 e1)
+          | None, Some e2 -> Some (A.mul c2 e2)
+          | Some e1, None -> Some (A.mul c1 e1)
           | Some e1, Some e2 -> none_zero (f e1 e2))
         m1 m2
     in
@@ -165,33 +162,32 @@ let cx_p_cy c1 p1 c2 p2 =
 let subst_node p x y =
   let poly, qo = Node.M.find_remove x p.poly in
   match qo with
-  | None -> (p, Q.zero)
+  | None -> (p, A.zero)
   | Some q ->
       let poly =
         Node.M.change
-          (function None -> qo | Some q' -> none_zero (Q.add q q'))
+          (function None -> qo | Some q' -> none_zero (A.add q q'))
           y poly
       in
       ({ p with poly }, q)
 
 let subst p x s =
   let poly, q = Node.M.find_remove x p.poly in
-  match q with None -> (p, Q.zero) | Some q -> (x_p_cy { p with poly } q s, q)
+  match q with None -> (p, A.zero) | Some q -> (x_p_cy { p with poly } q s, q)
 
 let fold f acc p = Node.M.fold_left f acc p.poly
-
 let iter f p = Node.M.iter f p.poly
 
 let of_list cst l =
   let fold acc (node, q) =
     Node.M.change
-      (function None -> Some q | Some q' -> none_zero (Q.add q q'))
+      (function None -> Some q | Some q' -> none_zero (A.add q q'))
       node acc
   in
   { cst; poly = List.fold_left fold Node.M.empty l }
 
 let of_map cst poly =
-  assert (Node.M.for_all (fun _ q -> not (Q.equal Q.zero q)) poly);
+  assert (Node.M.for_all (fun _ q -> not (A.equal A.zero q)) poly);
   { cst; poly }
 
 module ClM = Extmap.Make (Node)
@@ -206,19 +202,23 @@ let get_tree p =
     p.cst )
 
 let normalize p =
-  if Node.M.is_empty p.poly then cst (Q.of_int (Q.sign p.cst))
+  if Node.M.is_empty p.poly then cst (A.of_int (A.sign p.cst))
   else
     let init =
-      if Q.equal Q.zero p.cst then snd (Node.M.choose p.poly) else p.cst
+      if A.equal A.zero p.cst then snd (Node.M.choose p.poly) else p.cst
     in
     let num, den =
       Node.M.fold_left
-        (fun (num, den) _ q -> (Z.gcd num q.Q.num, Z.gcd den q.Q.den))
-        (init.Q.num, init.Q.den) p.poly
+        (fun (num, den) _ (q : A.t) ->
+          ( (match q with Q q -> Z.gcd num q.num | A _ -> num),
+            match q with Q q -> Z.gcd den q.den | A _ -> den ))
+        ( (match init with Q q -> q.num | A _ -> Z.one),
+          match init with Q q -> q.den | A _ -> Z.one )
+        p.poly
     in
     if Z.equal Z.one num && Z.equal Z.one den then p
     else
-      let conv q = Q.make (Z.divexact q.Q.num num) (Z.divexact q.Q.den den) in
+      let conv q = A.mul (A.of_z den) (A.div (A.of_z num) q) in
       { poly = Node.M.map conv p.poly; cst = conv p.cst }
 
 let print_poly fmt poly =
diff --git a/src_colibri2/theories/LRA/polynome.mli b/src_colibri2/theories/LRA/polynome.mli
index 2d5aa6c3981b464ae33aad58a73c0ee404af6263..0f82ee508d6f5d5c47c924c49a89a0bfc9662cea 100644
--- a/src_colibri2/theories/LRA/polynome.mli
+++ b/src_colibri2/theories/LRA/polynome.mli
@@ -23,66 +23,47 @@ open Colibri2_popop_lib
 open Colibri2_core
 (** Polynome *)
 
-type t = private { cst : Q.t; poly : Q.t Node.M.t }
+type t = private { cst : A.t; poly : A.t Node.M.t }
 
 include Popop_stdlib.Datatype with type t := t
 
 val invariant : t -> bool
-
 val zero : t
-
 val is_zero : t -> bool
-
-val cst : Q.t -> t
-
-val is_cst : t -> Q.t option
-
-val monome : Q.t -> Node.t -> t
-
+val cst : A.t -> t
+val is_cst : t -> A.t option
+val monome : A.t -> Node.t -> t
 val is_one_node : t -> Node.t option
 
 type extract =
   | Zero  (** p = 0 *)
-  | Cst of Q.t  (** p = q *)
-  | Var of Q.t * Node.t * t  (** p = qx + p' *)
+  | Cst of A.t  (** p = q *)
+  | Var of A.t * Node.t * t  (** p = qx + p' *)
 
 val extract : t -> extract
 
 type kind = ZERO | CST | VAR
 
 val classify : t -> kind
-
-val sub_cst : t -> Q.t -> t
-
-val add_cst : t -> Q.t -> t
-
-val mult_cst : Q.t -> t -> t
-
+val sub_cst : t -> A.t -> t
+val add_cst : t -> A.t -> t
+val mult_cst : A.t -> t -> t
 val add : t -> t -> t
-
 val sub : t -> t -> t
-
-val of_list : Q.t -> (Node.t * Q.t) list -> t
-
-val of_map : Q.t -> Q.t Node.M.t -> t
-
-val x_p_cy : t -> Q.t -> t -> t
-
-val cx_p_cy : Q.t -> t -> Q.t -> t -> t
-
-val subst : t -> Node.t -> t -> t * Q.t
-
-val subst_node : t -> Node.t -> Node.t -> t * Q.t
-
-val fold : ('a -> Node.t -> Q.t -> 'a) -> 'a -> t -> 'a
-
-val iter : (Node.t -> Q.t -> unit) -> t -> unit
+val of_list : A.t -> (Node.t * A.t) list -> t
+val of_map : A.t -> A.t Node.M.t -> t
+val x_p_cy : t -> A.t -> t -> t
+val cx_p_cy : A.t -> t -> A.t -> t -> t
+val subst : t -> Node.t -> t -> t * A.t
+val subst_node : t -> Node.t -> Node.t -> t * A.t
+val fold : ('a -> Node.t -> A.t -> 'a) -> 'a -> t -> 'a
+val iter : (Node.t -> A.t -> unit) -> t -> unit
 
 type 'a tree = Empty | Node of 'a tree * Node.t * 'a * 'a tree * int
 
-val get_tree : t -> Q.t tree * Q.t
+val get_tree : t -> A.t tree * A.t
 
 val normalize : t -> t
 (** divide by the pgcd *)
 
-val print_poly : Q.t Node.M.t Fmt.t
+val print_poly : A.t Node.M.t Fmt.t
diff --git a/src_colibri2/theories/LRA/product.ml b/src_colibri2/theories/LRA/product.ml
index 87cef75a21c1dea5ab8e0afbcf0bfcbce4a64eb4..2652156e8e8dae84b6fe49b0c37793c221461bfa 100644
--- a/src_colibri2/theories/LRA/product.ml
+++ b/src_colibri2/theories/LRA/product.ml
@@ -182,7 +182,6 @@ let subst p x s =
   match q with None -> (p, Q.zero) | Some q -> (x_m_yc { poly } s q, q)
 
 let fold f acc p = Node.M.fold_left f acc p.poly
-
 let iter f p = Node.M.iter f p.poly
 
 let of_list (* cst  *) l =
diff --git a/src_colibri2/theories/LRA/product.mli b/src_colibri2/theories/LRA/product.mli
index 32c5916cf3f6f2a293eba5fe6227ca6259bb2fc2..042123e4a42132a429177c31b97f5ba353e523e5 100644
--- a/src_colibri2/theories/LRA/product.mli
+++ b/src_colibri2/theories/LRA/product.mli
@@ -28,13 +28,9 @@ type t = private { (* cst : Q.t;  *) poly : Q.t Node.M.t }
 include Popop_stdlib.Datatype with type t := t
 
 val invariant : t -> bool
-
 val one : t
-
 val monome : Node.t -> Q.t -> t
-
 val is_one_node : t -> Node.t option
-
 val remove : Node.t -> t -> t
 
 type extract =
@@ -46,27 +42,16 @@ val extract : t -> extract
 type kind = ONE | NODE of Node.t | PRODUCT
 
 val classify : t -> kind
-
 val power_cst : Q.t -> t -> t
-
 val of_list : (Node.t * Q.t) list -> t
-
 val mul : t -> t -> t
-
 val div : t -> t -> t
-
 val x_m_yc : t -> t -> Q.t -> t
-
 val xc_m_yc : t -> Q.t -> t -> Q.t -> t
-
 val subst : t -> Node.t -> t -> t * Q.t
-
 val subst_node : t -> Node.t -> Node.t -> t * Q.t
-
 val fold : ('a -> Node.t -> Q.t -> 'a) -> 'a -> t -> 'a
-
 val iter : (Node.t -> Q.t -> unit) -> t -> unit
-
 val of_map : Q.t Node.M.t -> t
 
 val common : t -> t -> t
diff --git a/src_colibri2/theories/LRA/realValue.ml b/src_colibri2/theories/LRA/realValue.ml
index a33543f22766f4c910ba939796dead289f1d14d8..5b4b7bedc712842b3e092749f8f1183b555578e8 100644
--- a/src_colibri2/theories/LRA/realValue.ml
+++ b/src_colibri2/theories/LRA/realValue.ml
@@ -146,9 +146,9 @@ module Builtin = struct
 end
 
 module RealValue = Value.Register (struct
-  include Q
+  include A
 
-  let name = "Q"
+  let name = "A"
 end)
 
 include RealValue
@@ -156,13 +156,16 @@ include RealValue
 let () =
   Interp.Register.print_value_smt RealValue.key (fun _ fmt v ->
       let v = RealValue.value v in
-      if Z.equal v.den Z.one then Z.pp_print fmt v.num
-      else Fmt.pf fmt "(/ %a %a)" Z.pp_print v.num Z.pp_print v.den)
+      match v with
+      | Q v ->
+          if Z.equal v.den Z.one then Z.pp_print fmt v.num
+          else Fmt.pf fmt "(/ %a %a)" Z.pp_print v.num Z.pp_print v.den
+      | A v -> Fmt.pf fmt "(epsilon x. %s)" (Ocaml_poly.A.to_string v))
 
-let cst' c = index ~basename:(Format.asprintf "%aR" Q.pp c) c
+let cst' c = index ~basename:(Format.asprintf "%aR" A.pp c) c
 let cst c = node (cst' c)
-let zero = cst Q.zero
-let one = cst Q.one
+let zero = cst A.zero
+let one = cst A.one
 
 let positive_int_sequence =
   let open Base.Sequence.Generator in
@@ -182,7 +185,8 @@ let int_sequence = Base.Sequence.shift_right int_sequence_without_zero Z.zero
 let q_sequence d =
   let open Interp.SeqLim in
   let+ num = of_seq d int_sequence and* den = of_seq d positive_int_sequence in
-  Q.make num den
+  (** algebraic non rational are not generated *)
+  A.of_q (Q.make num den)
 
 let init_ty d =
   Interp.Register.ty d (fun d ty ->
@@ -190,20 +194,20 @@ let init_ty d =
       | { app = { builtin = Expr.Int; _ }; _ } ->
           Some
             (Interp.SeqLim.map (Interp.SeqLim.of_seq d int_sequence)
-               ~f:(fun i -> nodevalue (cst' (Q.of_bigint i))))
+               ~f:(fun i -> nodevalue (cst' (A.of_bigint i))))
       | { app = { builtin = Expr.Real; _ }; _ } ->
           let seq = q_sequence d in
           let seq =
-            Interp.SeqLim.unfold_with seq ~init:Q.S.empty ~f:(fun s v ->
-                if Q.S.mem v s then Skip s
-                else Yield (nodevalue (cst' v), Q.S.add v s))
+            Interp.SeqLim.unfold_with seq ~init:A.S.empty ~f:(fun s v ->
+                if A.S.mem v s then Skip s
+                else Yield (nodevalue (cst' v), A.S.add v s))
           in
           Some seq
       | { app = { builtin = Expr.Bitv n; _ }; _ } ->
           let open Base.Sequence.Generator in
           let rec loop i =
             if Z.numbits i <= n then
-              yield (nodevalue (cst' (Q.of_bigint i))) >>= fun () ->
+              yield (nodevalue (cst' (A.of_bigint i))) >>= fun () ->
               loop (Z.succ i)
             else return ()
           in
@@ -214,8 +218,8 @@ let init_ty d =
 exception Wrong_arg
 
 let unsigned_bitv n t =
-  if not (Q.is_unsigned_integer n t) then raise Wrong_arg;
-  t.Q.num
+  if not (A.is_unsigned_integer n t) then raise Wrong_arg;
+  A.to_z t
 
 let signed_bitv n t = Z.signed_extract (unsigned_bitv n t) 0 n
 
@@ -231,14 +235,14 @@ module Check = struct
       let r = if b then Boolean.values_true else Boolean.values_false in
       `Some r
     in
-    let extract n t = !<(Q.of_bigint (Z.extract t 0 n)) in
+    let extract n t = !<(A.of_bigint (Z.extract t 0 n)) in
     let from_bitv n t =
-      let t' = Q.of_bigint t in
-      if not (Q.is_unsigned_integer n t') then
+      let t' = A.of_bigint t in
+      if not (A.is_unsigned_integer n t') then
         Fmt.epr "@[[BV] %s(%a) is not of size %i@]@."
           (Z.format (Fmt.str "%%0+#%ib" n) t)
           Z.pp_print t n;
-      assert (Q.is_unsigned_integer n t');
+      assert (A.is_unsigned_integer n t');
       !<t'
     in
     match Ground.sem t with
@@ -259,92 +263,92 @@ module Check = struct
         !<(!>a)
     | { app = { builtin = Expr.Integer s }; tyargs = []; args; ty = _ } ->
         assert (IArray.is_empty args);
-        !<(Q.of_string s)
+        !<(A.of_string s)
     | { app = { builtin = Expr.Decimal s }; tyargs = []; args; ty = _ } ->
         assert (IArray.is_empty args);
-        !<(Q.of_string_decimal s)
+        !<(A.of_string_decimal s)
     | { app = { builtin = Expr.Rational s }; tyargs = []; args; ty = _ } ->
         assert (IArray.is_empty args);
-        !<(Q.of_string_decimal s)
+        !<(A.of_string_decimal s)
     | { app = { builtin = Expr.Add }; tyargs = []; args; ty = _ } ->
         let a, b = IArray.extract2_exn args in
-        !<(Q.add !>a !>b)
+        !<(A.add !>a !>b)
     | { app = { builtin = Expr.Sub }; tyargs = []; args; ty = _ } ->
         let a, b = IArray.extract2_exn args in
-        !<(Q.sub !>a !>b)
+        !<(A.sub !>a !>b)
     | { app = { builtin = Expr.Minus }; tyargs = []; args; ty = _ } ->
         let a = IArray.extract1_exn args in
-        !<(Q.neg !>a)
+        !<(A.neg !>a)
     | { app = { builtin = Expr.Mul }; tyargs = []; args; ty = _ } ->
         let a, b = IArray.extract2_exn args in
-        !<(Q.mul !>a !>b)
+        !<(A.mul !>a !>b)
     | { app = { builtin = Expr.Div }; tyargs = []; args; ty = _ } ->
         let a, b = IArray.extract2_exn args in
-        if Q.is_zero !>b then `Uninterp else !<(Q.div !>a !>b)
+        if A.is_zero !>b then `Uninterp else !<(A.div !>a !>b)
     | { app = { builtin = Expr.Div_e }; tyargs = []; args; ty = _ } ->
         let a, b = IArray.extract2_exn args in
         let b = !>b in
-        let s = Q.sign b in
-        if s = 0 then `Uninterp else !<(Q.div_e !>a b)
+        let s = A.sign b in
+        if s = 0 then `Uninterp else !<(A.div_e !>a b)
     | { app = { builtin = Expr.Div_f }; tyargs = []; args; ty = _ } ->
         let a, b = IArray.extract2_exn args in
         let b = !>b in
-        let s = Q.sign b in
-        if s = 0 then `Uninterp else !<(Q.div_f !>a b)
+        let s = A.sign b in
+        if s = 0 then `Uninterp else !<(A.div_f !>a b)
     | { app = { builtin = Expr.Div_t }; tyargs = []; args; ty = _ } ->
         let a, b = IArray.extract2_exn args in
         let b = !>b in
-        let s = Q.sign b in
-        if s = 0 then `Uninterp else !<(Q.div_t !>a b)
+        let s = A.sign b in
+        if s = 0 then `Uninterp else !<(A.div_t !>a b)
     | { app = { builtin = Expr.Modulo_e }; tyargs = []; args; ty = _ } ->
         let a, b = IArray.extract2_exn args in
         let b = !>b in
-        let s = Q.sign b in
-        if s = 0 then `Uninterp else !<(Q.mod_e !>a b)
+        let s = A.sign b in
+        if s = 0 then `Uninterp else !<(A.mod_e !>a b)
     | { app = { builtin = Expr.Modulo_f }; tyargs = []; args; ty = _ } ->
         let a, b = IArray.extract2_exn args in
         let b = !>b in
-        let s = Q.sign b in
-        if s = 0 then `Uninterp else !<(Q.mod_f !>a b)
+        let s = A.sign b in
+        if s = 0 then `Uninterp else !<(A.mod_f !>a b)
     | { app = { builtin = Expr.Modulo_t }; tyargs = []; args; ty = _ } ->
         let a, b = IArray.extract2_exn args in
         let b = !>b in
-        let s = Q.sign b in
-        if s = 0 then `Uninterp else !<(Q.mod_t !>a b)
+        let s = A.sign b in
+        if s = 0 then `Uninterp else !<(A.mod_t !>a b)
     | { app = { builtin = Builtin.Pow_int_int }; tyargs = []; args; ty = _ } ->
         let a, b = IArray.extract2_exn args in
         let a = !>a in
         let b = !>b in
-        if Q.sign b < 0 then `Uninterp else !<(Q.pow a (Q.to_int b))
+        if A.sign b < 0 then `Uninterp else !<(A.pow a (A.to_int b))
     | { app = { builtin = Builtin.Pow_real_int }; tyargs = []; args; ty = _ } ->
         let a, b = IArray.extract2_exn args in
         let a = !>a in
         let b = !>b in
-        if Q.sign b < 0 then `Uninterp else !<(Q.pow a (Q.to_int b))
+        if A.sign b < 0 then `Uninterp else !<(A.pow a (A.to_int b))
     | { app = { builtin = Expr.Lt }; tyargs = []; args; ty = _ } ->
         let a, b = IArray.extract2_exn args in
-        !<<(Q.lt !>a !>b)
+        !<<(A.lt !>a !>b)
     | { app = { builtin = Expr.Leq }; tyargs = []; args; ty = _ } ->
         let a, b = IArray.extract2_exn args in
-        !<<(Q.leq !>a !>b)
+        !<<(A.le !>a !>b)
     | { app = { builtin = Expr.Gt }; tyargs = []; args; ty = _ } ->
         let a, b = IArray.extract2_exn args in
-        !<<(Q.gt !>a !>b)
+        !<<(A.gt !>a !>b)
     | { app = { builtin = Expr.Geq }; tyargs = []; args; ty = _ } ->
         let a, b = IArray.extract2_exn args in
-        !<<(Q.geq !>a !>b)
+        !<<(A.ge !>a !>b)
     | { app = { builtin = Expr.Floor_to_int }; tyargs = []; args; _ } ->
         let a = IArray.extract1_exn args in
-        !<(Q.floor !>a)
+        !<(A.floor !>a)
     | { app = { builtin = Expr.Abs }; tyargs = []; args; _ } ->
         let a = IArray.extract1_exn args in
-        !<(Q.abs !>a)
+        !<(A.abs !>a)
     | { app = { builtin = Expr.Ceiling }; tyargs = []; args; _ } ->
         let a = IArray.extract1_exn args in
-        !<(Q.ceil !>a)
+        !<(A.ceil !>a)
     | { app = { builtin = Expr.Floor }; tyargs = []; args; _ } ->
         let a = IArray.extract1_exn args in
-        !<(Q.floor !>a)
+        !<(A.floor !>a)
     | { app = { builtin = Expr.Bitvec s }; tyargs = []; args; ty = _ } ->
         assert (IArray.is_empty args);
         from_bitv (String.length s) (Z.of_string_base 2 s)
@@ -493,10 +497,10 @@ module Check = struct
         !<<(Z.geq (signed_bitv n a) (signed_bitv n b))
     | { app = { builtin = Builtin.BV2Nat n }; tyargs = []; args; _ } ->
         let a = IArray.extract1_exn args in
-        !<(Q.of_bigint (bitv n a))
+        !<(A.of_bigint (bitv n a))
     | { app = { builtin = Builtin.Int2BV n }; tyargs = []; args; _ } ->
         let a = IArray.extract1_exn args in
-        extract n !>a.num
+        extract n (A.to_z (!>a))
     | _ -> `None
 
   let init d =
@@ -507,11 +511,11 @@ module Check = struct
         with
         | { builtin = Expr.Int; _ }, None -> Wrong
         | { builtin = Expr.Int; _ }, Some v
-          when not (Q.is_integer (RealValue.value v)) ->
+          when not (A.is_integer (RealValue.value v)) ->
             Wrong
         | { builtin = Expr.Bitv _; _ }, None -> Wrong
         | { builtin = Expr.Bitv n; _ }, Some v
-          when not (Q.is_unsigned_integer n (RealValue.value v)) ->
+          when not (A.is_unsigned_integer n (RealValue.value v)) ->
             Wrong
         | _ -> (
             let check r = Value.equal r (interp d (Ground.node t)) in
@@ -586,13 +590,13 @@ let converter d (f : Ground.t) =
       Check.attach d f
   | { app = { builtin = Expr.Integer s }; tyargs = []; args; _ } ->
       assert (IArray.is_empty args);
-      merge (cst (Q.of_string s))
+      merge (cst (A.of_string s))
   | { app = { builtin = Expr.Decimal s }; tyargs = []; args; _ } ->
       assert (IArray.is_empty args);
-      merge (cst (Q.of_string_decimal s))
+      merge (cst (A.of_string_decimal s))
   | { app = { builtin = Expr.Rational s }; tyargs = []; args; _ } ->
       assert (IArray.is_empty args);
-      merge (cst (Q.of_string_decimal s))
+      merge (cst (A.of_string_decimal s))
   | { app = { builtin = Expr.Add }; tyargs = []; args; _ } ->
       let a, b = IArray.extract2_exn args in
       reg a;
@@ -601,13 +605,13 @@ let converter d (f : Ground.t) =
       attach d
         (set r
            (let+ va = get a and+ vb = get b in
-            Q.add va vb)
+            A.add va vb)
         && set a
              (let+ vb = get b and+ vr = get r in
-              Q.sub vr vb)
+              A.sub vr vb)
         && set b
              (let+ va = get a and+ vr = get r in
-              Q.sub vr va))
+              A.sub vr va))
   | { app = { builtin = Expr.Sub }; tyargs = []; args; _ } ->
       let a, b = IArray.extract2_exn args in
       reg a;
@@ -616,13 +620,13 @@ let converter d (f : Ground.t) =
       attach d
         (set r
            (let+ va = get a and+ vb = get b in
-            Q.sub va vb)
+            A.sub va vb)
         && set a
              (let+ vb = get b and+ vr = get r in
-              Q.add vr vb)
+              A.add vr vb)
         && set b
              (let+ va = get a and+ vr = get r in
-              Q.sub va vr))
+              A.sub va vr))
   | { app = { builtin = Expr.Mul }; tyargs = []; args; _ } ->
       let a, b = IArray.extract2_exn args in
       reg a;
@@ -631,13 +635,13 @@ let converter d (f : Ground.t) =
       attach d
         (set r
            (let+ va = get a and+ vb = get b in
-            Q.mul va vb)
+            A.mul va vb)
         && set a
              (let* vb = get b and+ vr = get r in
-              if Q.is_zero vb then None else Some (Q.div vr vb))
+              if A.is_zero vb then None else Some (A.div vr vb))
         && set b
              (let* va = get a and+ vr = get r in
-              if Q.is_zero va then None else Some (Q.div vr va)))
+              if A.is_zero va then None else Some (A.div vr va)))
   | { app = { builtin = Expr.Div }; tyargs = []; args; _ } ->
       let a, b = IArray.extract2_exn args in
       reg a;
@@ -646,14 +650,14 @@ let converter d (f : Ground.t) =
       attach d
         (set r
            (let* va = get a and+ vb = get b in
-            if Q.is_zero vb then None else Some (Q.div va vb))
+            if A.is_zero vb then None else Some (A.div va vb))
         && set a
              (let* vb = get b and+ vr = get r in
-              if Q.is_zero vb then None else Some (Q.mul vr vb))
+              if A.is_zero vb then None else Some (A.mul vr vb))
         && (* if va is 0, and vr is not 0, b can't be not zero because vr would be 0. So b is 0. *)
         set b
           (let* va = get a and+ vr = get r in
-           if Q.is_zero vr then None else Some (Q.div va vr)))
+           if A.is_zero vr then None else Some (A.div va vr)))
   | { app = { builtin = Expr.Minus }; tyargs = []; args; _ } ->
       let a = IArray.extract1_exn args in
       reg a;
@@ -661,25 +665,25 @@ let converter d (f : Ground.t) =
       attach d
         (set r
            (let+ va = get a in
-            Q.neg va)
+            A.neg va)
         && set a
              (let+ vr = get r in
-              Q.neg vr))
+              A.neg vr))
   | { app = { builtin = Expr.Lt }; tyargs = []; args; _ } ->
       let a, b = IArray.extract2_exn args in
-      cmp Q.lt a b;
+      cmp A.lt a b;
       Check.attach d f
   | { app = { builtin = Expr.Leq }; tyargs = []; args; _ } ->
       let a, b = IArray.extract2_exn args in
-      cmp Q.le a b;
+      cmp A.le a b;
       Check.attach d f
   | { app = { builtin = Expr.Gt }; tyargs = []; args; _ } ->
       let a, b = IArray.extract2_exn args in
-      cmp Q.gt a b;
+      cmp A.gt a b;
       Check.attach d f
   | { app = { builtin = Expr.Geq }; tyargs = []; args; _ } ->
       let a, b = IArray.extract2_exn args in
-      cmp Q.ge a b;
+      cmp A.ge a b;
       Check.attach d f
   | { app = { builtin = Expr.Floor_to_int }; tyargs = []; args; _ } ->
       let a = IArray.extract1_exn args in
@@ -691,7 +695,7 @@ let converter d (f : Ground.t) =
       Check.attach d f
   | { app = { builtin = Expr.Bitvec s }; tyargs = []; args; ty = _ } ->
       assert (IArray.is_empty args);
-      merge (cst (Q.of_bigint (Z.of_string_base 2 s)))
+      merge (cst (A.of_bigint (Z.of_string_base 2 s)))
   | { app = { builtin = Expr.Bitv_concat (_n, _m) }; tyargs = []; args; _ } ->
       let a, b = IArray.extract2_exn args in
       reg a;
diff --git a/src_colibri2/theories/LRA/realValue.mli b/src_colibri2/theories/LRA/realValue.mli
index 9b8794bd712213fdbb28597448c0881f2a9ace83..092aab0c570a44b9bd31e29d1000474801c94b4a 100644
--- a/src_colibri2/theories/LRA/realValue.mli
+++ b/src_colibri2/theories/LRA/realValue.mli
@@ -22,26 +22,17 @@ module Builtin : sig
   type _ Expr.t += BV2Nat of int
 
   val abs_real : Colibri2_core.Expr.Term.Const.t
-
   val abs_int : Colibri2_core.Expr.Term.Const.t
-
   val bv2nat : int -> Colibri2_core.Expr.Term.Const.t
 end
 
-include Value.S with type s = Q.t
-
-val cst' : Q.t -> t
-
-val cst : Q.t -> Node.t
+include Value.S with type s = A.t
 
+val cst' : A.t -> t
+val cst : A.t -> Node.t
 val zero : Node.t
-
 val init : Egraph.wt -> unit
-
 val int_sequence : Z.t Base.Sequence.t
-
-val q_sequence : _ Egraph.t -> Q.t Interp.SeqLim.t
-
-val unsigned_bitv : int -> Q.t -> Z.t
-
-val signed_bitv : int -> Q.t -> Z.t
+val q_sequence : _ Egraph.t -> A.t Interp.SeqLim.t
+val unsigned_bitv : int -> A.t -> Z.t
+val signed_bitv : int -> A.t -> Z.t
diff --git a/src_colibri2/theories/LRA/simplex.ml b/src_colibri2/theories/LRA/simplex.ml
index 534aae787d467c8262731da08d32cd0d846eb79f..56edb11b5cfa9078b59d10cb173b86ec3148d1b5 100644
--- a/src_colibri2/theories/LRA/simplex.ml
+++ b/src_colibri2/theories/LRA/simplex.ml
@@ -31,16 +31,13 @@ let debug =
   Debug.register_info_flag ~desc:"Reasoning about <= < in LRA" "simplex"
 
 let stats_run = Debug.register_stats_int "Simplex.run"
-
 let stats_maximization = Debug.register_stats_int "Simplex.maximization"
-
 let stats_time = Debug.register_stats_time "Simplex.time"
 
 module Var = struct
   include Node
 
   let is_int _ = false
-
   let print = pp
 end
 
@@ -48,45 +45,36 @@ module Ex = struct
   type t = unit
 
   let print fmt () = Fmt.pf fmt "()"
-
   let empty = ()
-
   let union () () = ()
 end
 
 module Rat = struct
-  include Q
-
-  let m_one = Q.of_int (-1)
-
-  let print fmt t = Fmt.pf fmt "%s" (Q.to_string t)
-
-  let is_int x = Z.equal Z.one x.Q.den
-
-  let is_zero v = Q.equal v Q.zero
-
-  let is_one v = Q.equal v Q.one
-
-  let mult = Q.mul
-
-  let minus = Q.neg
-
-  let is_m_one v = Q.equal v m_one
+  include A
+
+  let m_one = A.minus_one
+  let print = A.pp
+  let is_int = A.is_integer
+  let is_zero v = A.equal v A.zero
+  let is_one v = A.equal v A.one
+  let mult = A.mul
+  let minus = A.neg
+  let is_m_one v = A.equal v m_one
 end
 
 module Sim = OcplibSimplex.Basic.Make (Var) (Rat) (Ex)
 
-type bound = No | Large of Q.t | Strict of Q.t
+type bound = No | Large of A.t | Strict of A.t
 
 let pp_bound_inf fmt = function
   | No -> ()
-  | Large q -> Fmt.pf fmt "%a ≤" Q.pp q
-  | Strict q -> Fmt.pf fmt "%a <" Q.pp q
+  | Large q -> Fmt.pf fmt "%a ≤" A.pp q
+  | Strict q -> Fmt.pf fmt "%a <" A.pp q
 
 let pp_bound_sup fmt = function
   | No -> ()
-  | Large q -> Fmt.pf fmt "≤ %a" Q.pp q
-  | Strict q -> Fmt.pf fmt "< %a" Q.pp q
+  | Large q -> Fmt.pf fmt "≤ %a" A.pp q
+  | Strict q -> Fmt.pf fmt "< %a" A.pp q
 
 let to_bound = function
   | None -> No
@@ -97,21 +85,21 @@ let inter_inf inf1 inf2 =
   match (inf1, inf2) with
   | No, inf | inf, No -> inf
   | (Large q1, (Strict q2 as inf) | (Strict q2 as inf), Large q1)
-    when Q.equal q1 q2 ->
+    when A.equal q1 q2 ->
       inf
   | ((Large q1 | Strict q1) as inf1), ((Strict q2 | Large q2) as inf2) ->
-      if Q.leq q2 q1 then inf1 else inf2
+      if A.le q2 q1 then inf1 else inf2
 
 let inter_sup inf1 inf2 =
   match (inf1, inf2) with
   | No, inf | inf, No -> inf
   | (Large q1, (Strict q2 as inf) | (Strict q2 as inf), Large q1)
-    when Q.equal q1 q2 ->
+    when A.equal q1 q2 ->
       inf
   | ((Large q1 | Strict q1) as inf1), ((Strict q2 | Large q2) as inf2) ->
-      if Q.leq q2 q1 then inf2 else inf1
+      if A.le q2 q1 then inf2 else inf1
 
-type eq = { inf : bound; p : Q.t Node.M.t; sup : bound }
+type eq = { inf : bound; p : A.t Node.M.t; sup : bound }
 
 let pp_eq fmt { inf; p; sup } =
   Fmt.pf fmt "%a%a%a" pp_bound_inf inf Polynome.print_poly p pp_bound_sup sup
@@ -126,16 +114,16 @@ let delta d eq =
   (* add info to delta *)
   if Node.M.is_num_elt 2 eq.p then
     match Node.M.bindings eq.p with
-    | [ (src, a); (dst, b) ] when Q.equal Q.one a && Q.equal Q.minus_one b ->
+    | [ (src, a); (dst, b) ] when A.equal A.one a && A.equal A.minus_one b ->
         add d src eq.sup dst;
         add d dst eq.inf src
-    | [ (dst, b); (src, a) ] when Q.equal Q.one a && Q.equal Q.minus_one b ->
+    | [ (dst, b); (src, a) ] when A.equal A.one a && A.equal A.minus_one b ->
         add d src eq.sup dst;
         add d dst eq.inf src
     | _ -> ()
 
 let add_eq _ eqs eq =
-  let p = Polynome.of_map Q.zero eq.p in
+  let p = Polynome.of_map A.zero eq.p in
   Polynome.H.change
     (function
       | None -> Some eq
@@ -152,14 +140,14 @@ let add_eq _ eqs eq =
 let mk_eq _ p dom =
   assert (not (Node.M.is_empty p.Polynome.poly));
   let _, q = Node.M.choose p.poly in
-  assert (not (Q.equal q Q.zero));
-  let p = Polynome.mult_cst (Q.inv q) p in
+  assert (not (A.equal q A.zero));
+  let p = Polynome.mult_cst (A.inv q) p in
   let inf, sup = Dom_interval.D.get_convexe_hull dom in
-  let inf, sup = if Q.sign q < 0 then (sup, inf) else (inf, sup) in
+  let inf, sup = if A.sign q < 0 then (sup, inf) else (inf, sup) in
   let translate = function
     | No -> No
-    | Strict c -> Strict (Q.sub (Q.div c q) p.cst)
-    | Large c -> Large (Q.sub (Q.div c q) p.cst)
+    | Strict c -> Strict (A.sub (A.div c q) p.cst)
+    | Large c -> Large (A.sub (A.div c q) p.cst)
   in
   let inf = translate @@ to_bound inf in
   let sup = translate @@ to_bound sup in
@@ -173,7 +161,7 @@ let make_equations d (eqs, vars) n =
     | Some dom ->
         let p =
           match Dom_polynome.get_repr d n with
-          | None -> Polynome.monome Q.one (Egraph.find_def d n)
+          | None -> Polynome.monome A.one (Egraph.find_def d n)
           | Some p -> p
         in
         if Node.M.is_empty p.poly then (eqs, vars)
@@ -223,20 +211,20 @@ end
 let of_bound_sup = function
   | No -> None
   | Large q ->
-      assert (Q.is_real q);
-      Some (q, Q.zero)
+      assert (A.is_real q);
+      Some (q, A.zero)
   | Strict q ->
-      assert (Q.is_real q);
-      Some (q, Q.minus_one)
+      assert (A.is_real q);
+      Some (q, A.minus_one)
 
 let of_bound_inf = function
   | No -> None
   | Large q ->
-      assert (Q.is_real q);
-      Some (q, Q.zero)
+      assert (A.is_real q);
+      Some (q, A.zero)
   | Strict q ->
-      assert (Q.is_real q);
-      Some (q, Q.one)
+      assert (A.is_real q);
+      Some (q, A.one)
 
 let find_equalities d vars (env : Sim.Core.t) (s : Sim.Core.solution Lazy.t) =
   (* Env must be sat *)
@@ -257,7 +245,7 @@ let find_equalities d vars (env : Sim.Core.t) (s : Sim.Core.solution Lazy.t) =
           (fun to_ ->
             let is_int_to = Dom_interval.is_integer d to_ in
             Edge.H.add_new Impossible under_approx { Edge.from; to_ }
-              (is_int_from, is_int_to, Q.inf, Q.minus_inf))
+              (is_int_from, is_int_to, A.inf, A.minus_inf))
           acc;
         acc)
       vars vars
@@ -266,22 +254,22 @@ let find_equalities d vars (env : Sim.Core.t) (s : Sim.Core.solution Lazy.t) =
     let h = val_of_sol s in
     Edge.H.filter_mapi
       (fun { from; to_ } (is_int_from, is_int_to, inf, sup) ->
-        let dist = Q.sub (Node.H.find h to_) (Node.H.find h from) in
+        let dist = A.sub (Node.H.find h to_) (Node.H.find h from) in
         (* Debug.dprintf10 debug "[Simplex] under_approx: %a <= %a - %a <= %a : %a"
-         *   Q.pp inf Node.pp to_ Node.pp from Q.pp sup Q.pp dist; *)
-        let inf = Q.min inf dist in
-        let sup = Q.max sup dist in
+         *   A.pp inf Node.pp to_ Node.pp from A.pp sup A.pp dist; *)
+        let inf = A.min inf dist in
+        let sup = A.max sup dist in
         if is_int_from || is_int_to then
-          if Q.le inf Q.minus_one || Q.le Q.one sup then None
+          if A.le inf A.minus_one || A.le A.one sup then None
           else Some (is_int_from, is_int_to, inf, sup)
-        else if Q.lt inf Q.zero || Q.lt Q.zero sup then None
+        else if A.lt inf A.zero || A.lt A.zero sup then None
         else Some (is_int_from, is_int_to, inf, sup))
       under_approx
   in
   let one_dist env is_int a b =
     Debug.incr stats_maximization;
     Debug.dprintf4 debug "Check max %a - %a" Node.pp a Node.pp b;
-    let p = Sim.Core.P.from_list [ (a, Q.one); (b, Q.minus_one) ] in
+    let p = Sim.Core.P.from_list [ (a, A.one); (b, A.minus_one) ] in
     let env, opt = Sim.Solve.maximize env p in
     match Sim.Result.get opt env with
     | Sim.Core.Unknown -> assert false
@@ -291,10 +279,10 @@ let find_equalities d vars (env : Sim.Core.t) (s : Sim.Core.solution Lazy.t) =
         update_under_approx s;
         (* s is often not interesting for the update; all at zero, so the
            distance is pushed a little further *)
-        let p' = Polynome.of_list Q.zero [ (a, Q.one); (b, Q.minus_one) ] in
+        let p' = Polynome.of_list A.zero [ (a, A.one); (b, A.minus_one) ] in
         let n = Dom_polynome.node_of_polynome d p' in
         let env', _ =
-          Sim.Assert.poly env p n (of_bound_inf (Large (Q.of_int 2))) () None ()
+          Sim.Assert.poly env p n (of_bound_inf (Large (A.of_int 2))) () None ()
         in
         let env' = Sim.Solve.solve env' in
         let s =
@@ -306,10 +294,10 @@ let find_equalities d vars (env : Sim.Core.t) (s : Sim.Core.solution Lazy.t) =
         (`Distinct, env, s)
     | Sim.Core.Max (m, s) ->
         let m = Lazy.force m in
-        (* Debug.dprintf2 debug "Max %a" Q.pp m.max_v; *)
+        (* Debug.dprintf2 debug "Max %a" A.pp m.max_v; *)
         (if m.is_le then Delta.add_le else Delta.add_lt) d a m.max_v b;
         let notdistinct =
-          if is_int then Q.lt (Q.abs m.max_v) Q.one else Q.equal m.max_v Q.zero
+          if is_int then A.lt (A.abs m.max_v) A.one else A.equal m.max_v A.zero
         in
         if notdistinct then (`NotDistinct, env, s) else (`Distinct, env, s)
   in
@@ -355,7 +343,7 @@ let update_domains d env =
       let inf =
         Base.Option.map
           ~f:(fun (q1, q2) ->
-            let s = Q.sign q2 in
+            let s = A.sign q2 in
             let b =
               if s = 0 then Bound.Large
               else if s > 0 then Strict
@@ -368,7 +356,7 @@ let update_domains d env =
       let sup =
         Base.Option.map
           ~f:(fun (q1, q2) ->
-            let s = Q.sign q2 in
+            let s = A.sign q2 in
             let b =
               if s = 0 then Bound.Large
               else if s < 0 then Strict
@@ -426,7 +414,7 @@ let simplex (d : Egraph.wt) =
     Debug.dprintf2 debug "%a@." pp_eq eq;
     if Node.M.is_num_elt 1 eq.p then (
       let n, q = Node.M.choose eq.p in
-      assert (Q.equal q Q.one);
+      assert (A.equal q A.one);
       let inf = of_bound_inf eq.inf in
       let sup = of_bound_sup eq.sup in
       let env, _ = Sim.Assert.var env n inf () sup () in
@@ -434,7 +422,7 @@ let simplex (d : Egraph.wt) =
     else
       let inf = of_bound_inf eq.inf in
       let sup = of_bound_sup eq.sup in
-      let p = Polynome.of_map Q.zero eq.p in
+      let p = Polynome.of_map A.zero eq.p in
       let n = Dom_polynome.node_of_polynome d p in
       let vars = Node.S.add n vars in
       let env, _ = Sim.Assert.poly env (of_poly p) n inf () sup () in
@@ -478,7 +466,6 @@ module DaemonSimplex = struct
   type runable = unit
 
   let print_runable = Unit.pp
-
   let run d () = simplex d
 end
 
@@ -532,7 +519,7 @@ let converter d (f : Ground.t) =
             if Node.compare a b < 0 then (a, b, builtin)
             else (b, a, ord_inv builtin)
           in
-          let p = Polynome.of_list Q.zero [ (a, Q.one); (b, Q.minus_one) ] in
+          let p = Polynome.of_list A.zero [ (a, A.one); (b, A.minus_one) ] in
 
           let n = Dom_polynome.node_of_polynome d p in
           if not (Node.HC.mem seen d n) then (
diff --git a/src_colibri2/theories/LRA/stages/dune b/src_colibri2/theories/LRA/stages/dune
index c5ba75543ee95a95ce7067351debe9fb7504ecfc..adbc8699013467fa4c2941a543124fca8a99c71e 100644
--- a/src_colibri2/theories/LRA/stages/dune
+++ b/src_colibri2/theories/LRA/stages/dune
@@ -2,7 +2,7 @@
  (name colibri2_theories_LRA_stages)
  (public_name colibri2.theories.LRA.stages)
  (virtual_modules interval_domain)
- (libraries colibri2.popop_lib colibri2.theories.LRA.stages.def)
+ (libraries colibri2.popop_lib colibri2.theories.LRA.stages.def colibri2.stdlib)
  (modules interval_domain)
 )
 
@@ -10,7 +10,7 @@
  (name colibri2_theories_LRA_stages_def)
  (public_name colibri2.theories.LRA.stages.def)
  (modules interval_sig bound)
- (libraries colibri2.popop_lib containers)
+ (libraries colibri2.popop_lib containers colibri2.stdlib)
  (preprocess
   (pps ppx_deriving.std ppx_hash))
 )
diff --git a/src_colibri2/theories/LRA/stages/interval_sig.ml b/src_colibri2/theories/LRA/stages/interval_sig.ml
index f0894e63eefa33f3414b56584e2f9ea93cd63f88..b096d67b03e08af82b1e14c9bd16660a6932cf80 100644
--- a/src_colibri2/theories/LRA/stages/interval_sig.ml
+++ b/src_colibri2/theories/LRA/stages/interval_sig.ml
@@ -19,6 +19,7 @@
 (*************************************************************************)
 
 open Colibri2_popop_lib
+open Colibri2_stdlib.Std
 
 module type S = sig
   include Popop_stdlib.Datatype
@@ -28,51 +29,35 @@ module type S = sig
   type is_comparable = Gt | Lt | Ge | Le | Eq | Uncomparable
 
   val is_comparable : t -> t -> is_comparable
-
   val is_included : t -> t -> bool
-
-  val mult_cst : Q.t -> t -> t
-
-  val add_cst : Q.t -> t -> t
-
+  val mult_cst : A.t -> t -> t
+  val add_cst : A.t -> t -> t
   val add : t -> t -> t
-
   val minus : t -> t -> t
+  val mem : A.t -> t -> bool
 
-  val mem : Q.t -> t -> bool
+  val singleton : A.t -> t
+  (** from A.t *)
 
-  val singleton : Q.t -> t
-  (** from Q.t *)
+  val is_singleton : t -> A.t option
+  val except : t -> A.t -> t option
 
-  val is_singleton : t -> Q.t option
-
-  val except : t -> Q.t -> t option
-
-  type split_heuristic = Singleton of Q.t | Splitted of t * t | NotSplitted
+  type split_heuristic = Singleton of A.t | Splitted of t * t | NotSplitted
 
   val split_heuristic : t -> split_heuristic
-
-  val absent : Q.t -> t -> bool
-
+  val absent : A.t -> t -> bool
   val is_integer : t -> bool
-
   val integers : t
+  val gt : A.t -> t
+  val ge : A.t -> t
+  val lt : A.t -> t
 
-  val gt : Q.t -> t
-
-  val ge : Q.t -> t
-
-  val lt : Q.t -> t
-
-  val le : Q.t -> t
+  val le : A.t -> t
   (** > q, >= q, < q, <= q *)
 
   val le' : t -> t
-
   val lt' : t -> t
-
   val ge' : t -> t
-
   val gt' : t -> t
 
   val union : t -> t -> t
@@ -84,23 +69,21 @@ module type S = sig
   *)
 
   val zero : t
-
   val reals : t
 
   val is_reals : t -> bool
   (** R *)
 
-  val choose : t -> Q.t
+  val choose : t -> A.t
   (** Nothing smart in this choosing *)
 
   val invariant : t -> bool
 
-  (* val choose_rnd : (int -> int) -> t -> Q.t
+  (* val choose_rnd : (int -> int) -> t -> A.t
    * (\** choose an element randomly (but non-uniformly), the given function is
    *       the random generator *\)
    *)
 
-  val get_convexe_hull : t -> (Q.t * Bound.t) option * (Q.t * Bound.t) option
-
-  val from_convexe_hull : (Q.t * Bound.t) option * (Q.t * Bound.t) option -> t
+  val get_convexe_hull : t -> (A.t * Bound.t) option * (A.t * Bound.t) option
+  val from_convexe_hull : (A.t * Bound.t) option * (A.t * Bound.t) option -> t
 end
diff --git a/src_colibri2/theories/LRA/stages/stage0/integer_sign_domain.ml b/src_colibri2/theories/LRA/stages/stage0/integer_sign_domain.ml
index 4d538b1a900082d78b4f1faee7bcbc2a6ab99647..d7c1aebd54a36ba89c73965625c1e746a3b07790 100644
--- a/src_colibri2/theories/LRA/stages/stage0/integer_sign_domain.ml
+++ b/src_colibri2/theories/LRA/stages/stage0/integer_sign_domain.ml
@@ -49,7 +49,7 @@ include Colibri2_popop_lib.Popop_stdlib.MkDatatype (T)
 
 let invariant t = Sign_domain.invariant t.sign
 
-type split_heuristic = Singleton of Q.t | Splitted of t * t | NotSplitted
+type split_heuristic = Singleton of A.t | Splitted of t * t | NotSplitted
 
 let split_heuristic t =
   match Sign_domain.split_heuristic t.sign with
@@ -61,16 +61,12 @@ let split_heuristic t =
   | NotSplitted -> NotSplitted
 
 let absent q t =
-  ((not t.noninteger) && not (Q.is_integer q)) || Sign_domain.absent q t.sign
+  ((not t.noninteger) && not (A.is_integer q)) || Sign_domain.absent q t.sign
 
 let le' t = { noninteger = true; sign = Sign_domain.le' t.sign }
-
 let lt' t = { noninteger = true; sign = Sign_domain.lt' t.sign }
-
 let ge' t = { noninteger = true; sign = Sign_domain.ge' t.sign }
-
 let gt' t = { noninteger = true; sign = Sign_domain.gt' t.sign }
-
 let is_distinct t1 t2 = Sign_domain.is_distinct t1.sign t2.sign
 
 type is_comparable = Sign_domain.is_comparable =
@@ -89,7 +85,7 @@ let is_included t1 t2 =
 
 let mult_cst q t =
   {
-    noninteger = t.noninteger && Q.is_not_zero q;
+    noninteger = t.noninteger && A.is_not_zero q;
     sign = Sign_domain.mult_cst q t.sign;
   }
 
@@ -108,10 +104,10 @@ let minus t1 t2 =
     sign = Sign_domain.minus t1.sign t2.sign;
   }
 
-let mem q t = (Q.is_integer q || t.noninteger) && Sign_domain.mem q t.sign
+let mem q t = (A.is_integer q || t.noninteger) && Sign_domain.mem q t.sign
 
 let singleton q =
-  { noninteger = not (Q.is_integer q); sign = Sign_domain.singleton q }
+  { noninteger = not (A.is_integer q); sign = Sign_domain.singleton q }
 
 let is_singleton t = Sign_domain.is_singleton t.sign
 
@@ -121,11 +117,8 @@ let except t q =
   | Some sign -> Some { noninteger = t.noninteger; sign }
 
 let gt q = { noninteger = true; sign = Sign_domain.gt q }
-
 let ge q = { noninteger = true; sign = Sign_domain.ge q }
-
 let lt q = { noninteger = true; sign = Sign_domain.lt q }
-
 let le q = { noninteger = true; sign = Sign_domain.le q }
 
 let union t1 t2 =
@@ -140,15 +133,10 @@ let inter t1 t2 =
   | None -> None
 
 let zero = { noninteger = false; sign = Sign_domain.zero }
-
 let reals = { noninteger = true; sign = Sign_domain.reals }
-
 let integers = { noninteger = false; sign = Sign_domain.reals }
-
 let is_reals t = t.noninteger && Sign_domain.is_reals t.sign
-
 let choose t = Sign_domain.choose t.sign
-
 let is_integer t = not t.noninteger
 
 let get_convexe_hull t =
@@ -156,10 +144,10 @@ let get_convexe_hull t =
   let checkint dir = function
     | x when t.noninteger -> x
     | None -> None
-    | Some (z, Bound.Strict) when Q.is_zero z -> Some (dir, Large)
+    | Some (z, Bound.Strict) when A.is_zero z -> Some (dir, Large)
     | x -> x
   in
-  (checkint Q.one inf, checkint Q.minus_one sup)
+  (checkint A.one inf, checkint A.minus_one sup)
 
 let from_convexe_hull ch =
   { sign = Sign_domain.from_convexe_hull ch; noninteger = true }
diff --git a/src_colibri2/theories/LRA/stages/stage0/integer_sign_domain.mli b/src_colibri2/theories/LRA/stages/stage0/integer_sign_domain.mli
index 265e418b6ee3ed1051d1590b76e83cff5fac6818..f011060db037a4b5cf8ea609c7dfecd66f7db142 100644
--- a/src_colibri2/theories/LRA/stages/stage0/integer_sign_domain.mli
+++ b/src_colibri2/theories/LRA/stages/stage0/integer_sign_domain.mli
@@ -20,19 +20,13 @@
 
 include Interval_sig.S
 
-type split_heuristic =
-  | Singleton of Q.t
-  | Splitted of t * t
-  | NotSplitted
+type split_heuristic = Singleton of A.t | Splitted of t * t | NotSplitted
 
-val split_heuristic: t -> split_heuristic
-
-val absent: Q.t -> t -> bool
-
-val le': t -> t
-val lt': t -> t
-val ge': t -> t
-val gt': t -> t
-
-val is_integer: t -> bool
-val integers: t
+val split_heuristic : t -> split_heuristic
+val absent : A.t -> t -> bool
+val le' : t -> t
+val lt' : t -> t
+val ge' : t -> t
+val gt' : t -> t
+val is_integer : t -> bool
+val integers : t
diff --git a/src_colibri2/theories/LRA/stages/stage0/sign_domain.ml b/src_colibri2/theories/LRA/stages/stage0/sign_domain.ml
index 0b1574fab8f7a5d1bb6903c05339313341b0afbd..dc25fc92ab2b553ca71e9cc27d2ab69d838d62c2 100644
--- a/src_colibri2/theories/LRA/stages/stage0/sign_domain.ml
+++ b/src_colibri2/theories/LRA/stages/stage0/sign_domain.ml
@@ -50,34 +50,22 @@ include T
 include Colibri2_popop_lib.Popop_stdlib.MkDatatype (T)
 
 let invariant t = t.neg || t.zero || t.pos
-
 let top = { pos = true; zero = true; neg = true }
-
 let pos_or_zero = { pos = true; zero = true; neg = false }
-
 let pos = { pos = true; zero = false; neg = false }
-
 let neg_or_zero = { pos = false; zero = true; neg = true }
-
 let neg = { pos = false; zero = false; neg = true }
-
 let zero = { pos = false; zero = true; neg = false }
-
 let one = { pos = true; zero = false; neg = false }
-
 let non_zero = { pos = true; zero = false; neg = true }
-
 let ge_zero v = not v.neg
-
 let le_zero v = not v.pos
 
 (* Bottom is a special value (`Bottom) in Eva, and need not be part of
    the lattice. Here, we have a value which is equivalent to it, defined
    there only for commodity. *)
 let empty = { pos = false; zero = false; neg = false }
-
 let is_empty t = equal t empty
-
 let is_reals t = equal t top
 
 (* Inclusion: test inclusion of each field. *)
@@ -103,20 +91,20 @@ let narrow v1 v2 =
   if is_empty r then None else Some r
 
 let mem q v =
-  let c = Q.sign q in
+  let c = A.sign q in
   (c = 0 && v.zero) || (c < 0 && v.neg) || (c > 0 && v.pos)
 
 let absent q v =
-  let c = Q.sign q in
+  let c = A.sign q in
   (c = 0 && not v.zero) || (c < 0 && not v.neg) || (c > 0 && not v.pos)
 
 let reals = top
 
 (* [singleton] creates an abstract value corresponding to the singleton [i]. *)
 let singleton i =
-  if Q.lt i Q.zero then neg else if Q.gt i Q.zero then pos else zero
+  if A.lt i A.zero then neg else if A.gt i A.zero then pos else zero
 
-let is_singleton v = if equal v zero then Some Q.zero else None
+let is_singleton v = if equal v zero then Some A.zero else None
 
 (** {2 Forward transfer functions} *)
 
@@ -126,7 +114,6 @@ let is_singleton v = if equal v zero then Some Q.zero else None
    the functions [truncate_integer] and [rewrap_integer]. *)
 
 let neg_unop v = { v with neg = v.pos; pos = v.neg }
-
 let logical_not v = { pos = v.zero; neg = false; zero = v.pos || v.neg }
 
 let add v1 v2 =
@@ -139,7 +126,7 @@ let add v1 v2 =
   { neg; pos; zero }
 
 let add_cst q v =
-  let c = Q.sign q in
+  let c = A.sign q in
   if c = 0 then v
   else if c > 0 then
     { neg = v.neg; zero = v.zero && v.neg; pos = v.pos || v.zero || v.neg }
@@ -154,7 +141,7 @@ let mul v1 v2 =
 let minus v1 v2 = add v1 { neg = v2.pos; zero = v2.zero; pos = v2.neg }
 
 let mult_cst q v =
-  let c = Q.sign q in
+  let c = A.sign q in
   if c = 0 then zero
   else if c > 0 then v
   else { neg = v.pos; zero = v.zero; pos = v.neg }
@@ -334,35 +321,34 @@ let is_included x y =
   Bool.(x.neg <= y.neg && x.zero <= y.zero && x.pos <= y.pos)
 
 let union = join
-
 let inter = narrow
 
-type split_heuristic = Singleton of Q.t | Splitted of t * t | NotSplitted
+type split_heuristic = Singleton of A.t | Splitted of t * t | NotSplitted
 
 let split_heuristic _ = NotSplitted
 
 let except t x =
-  if Q.sign x = 0 && t.zero then
+  if A.sign x = 0 && t.zero then
     let t = { t with zero = false } in
     if is_empty t then None else Some t
   else Some t
 
-let choose t = if t.zero then Q.zero else if t.pos then Q.one else Q.minus_one
+let choose t = if t.zero then A.zero else if t.pos then A.one else A.minus_one
 
 let le q =
-  let c = Q.sign q in
+  let c = A.sign q in
   if c < 0 then neg else if c = 0 then neg_or_zero else top
 
 let lt q =
-  let c = Q.sign q in
+  let c = A.sign q in
   if c <= 0 then neg else top
 
 let ge q =
-  let c = Q.sign q in
+  let c = A.sign q in
   if c < 0 then top else if c = 0 then pos_or_zero else pos
 
 let gt q =
-  let c = Q.sign q in
+  let c = A.sign q in
   if c >= 0 then pos else top
 
 let le' v =
@@ -374,25 +360,23 @@ let ge' v =
   { neg = v.neg; zero = v.zero || v.neg; pos = v.pos || v.zero || v.neg }
 
 let gt' v = { neg = v.neg; zero = v.neg; pos = v.pos || v.zero || v.neg }
-
 let integers = reals
-
 let is_integer _ = false
 
 let get_convexe_hull v =
   let inf =
     match (v.neg, v.zero, v.pos) with
     | true, _, _ -> None
-    | false, true, _ -> Some (Q.zero, Bound.Large)
-    | false, false, true -> Some (Q.zero, Bound.Strict)
+    | false, true, _ -> Some (A.zero, Bound.Large)
+    | false, false, true -> Some (A.zero, Bound.Strict)
     | false, false, false -> assert false
     (* absurd: bottom *)
   in
   let sup =
     match (v.neg, v.zero, v.pos) with
     | _, _, true -> None
-    | _, true, false -> Some (Q.zero, Bound.Large)
-    | true, false, false -> Some (Q.zero, Bound.Strict)
+    | _, true, false -> Some (A.zero, Bound.Large)
+    | true, false, false -> Some (A.zero, Bound.Strict)
     | false, false, false -> assert false
     (* absurd: bottom *)
   in
@@ -403,7 +387,7 @@ let from_convexe_hull (inf, sup) =
     match inf with
     | None -> reals
     | Some (q, b) ->
-        let s = Q.sign q in
+        let s = A.sign q in
         if s > 0 then pos
         else if s = 0 then
           match b with Bound.Large -> pos_or_zero | Strict -> pos
@@ -413,7 +397,7 @@ let from_convexe_hull (inf, sup) =
     match sup with
     | None -> reals
     | Some (q, b) ->
-        let s = Q.sign q in
+        let s = A.sign q in
         if s < 0 then neg
         else if s = 0 then
           match b with Bound.Large -> neg_or_zero | Strict -> neg
diff --git a/src_colibri2/theories/LRA/stages/stage2/union.ml b/src_colibri2/theories/LRA/stages/stage2/union.ml
index 2a71230d2c520bbe079f90dda832dbf6ace49a17..f15769f19f1ceee79e37b063df53ec6a45611141 100644
--- a/src_colibri2/theories/LRA/stages/stage2/union.ml
+++ b/src_colibri2/theories/LRA/stages/stage2/union.ml
@@ -21,8 +21,12 @@
 open Colibri2_popop_lib
 open Colibri2_stdlib.Std
 
+let compare_ord a b : Colibrics_lib.Ord.t =
+  let c = A.compare a b in
+  Int.(if c = 0 then Eq else if c <= 0 then Lt else Gt)
+
 module P = Colibrics_lib.Interval.Union.Make (struct
-  include Q
+  include A
 
   let infix_eq = equal
   let infix_lseq = le
@@ -31,22 +35,18 @@ module P = Colibrics_lib.Interval.Union.Make (struct
   let infix_mn = sub
   let infix_as = mul
   let infix_sl = div
-
-  let compare a b : Colibrics_lib.Ord.t =
-    let c = Q.compare a b in
-    Int.(if c = 0 then Eq else if c <= 0 then Lt else Gt)
-
-  let of_int = Q.of_bigint
-  let floor a = Z.fdiv a.num a.den
-  let ceil a = Z.cdiv a.num a.den
+  let compare = compare_ord
+  let of_int = A.of_bigint
+  let floor a = A.to_z (A.floor a)
+  let ceil a = A.to_z (A.ceil a)
 end)
 
 open P
 
 include struct
-  type q = Q.t [@@deriving eq, ord, hash]
+  type q = A.t [@@deriving eq, ord, hash]
 
-  let gen_q = Q.gen
+  let gen_q = A.gen
 
   type bound = Colibrics_lib.Interval.Bound.t = Strict | Large
   [@@deriving eq, ord, hash, qcheck]
@@ -70,7 +70,7 @@ include struct
     let l =
       List.sort_uniq l ~cmp:(fun a b ->
           let extract = function `Sin q -> q | `End (q, _) -> q in
-          -Q.compare (extract a) (extract b))
+          -A.compare (extract a) (extract b))
     in
     let rec convert acc = function
       | [] -> acc
@@ -92,21 +92,21 @@ let print_bound fmt = function
 
 let rec pp_on fmt = function
   | Sin (q, on) ->
-      Format.fprintf fmt "%a[∪]%a;" Q.pp q Q.pp q;
+      Format.fprintf fmt "%a[∪]%a;" A.pp q A.pp q;
       pp_on fmt on
   | End (q, b, off) ->
-      Format.fprintf fmt "%a%a" Q.pp q print_bound b;
+      Format.fprintf fmt "%a%a" A.pp q print_bound b;
       pp_off ~first:false fmt off
   | Inf -> Format.fprintf fmt "+∞["
 
 and pp_off ~first fmt = function
   | Sin (q, off) ->
       if not first then Format.fprintf fmt "∪";
-      Format.fprintf fmt "{%a}" Q.pp q;
+      Format.fprintf fmt "{%a}" A.pp q;
       pp_off ~first:false fmt off
   | End (q, b, on) ->
       if not first then Format.fprintf fmt "∪";
-      Format.fprintf fmt "%a%a;" print_bound b Q.pp q;
+      Format.fprintf fmt "%a%a;" print_bound b A.pp q;
       pp_on fmt on
   | Inf -> ()
 
@@ -188,7 +188,7 @@ let to_bound : Bound.t -> Colibrics_lib.Interval.Bound.t = function
   | Large -> Large
 
 (** type invariant *)
-let get_convexe_hull : t -> (Q.t * Bound.t) option * (Q.t * Bound.t) option =
+let get_convexe_hull : t -> (A.t * Bound.t) option * (A.t * Bound.t) option =
  fun t ->
   let inf, sup = get_convexe_hull t.u in
   let conv c = Base.Option.map ~f:(fun (q, b) -> (q, of_bound b)) c in
@@ -196,10 +196,10 @@ let get_convexe_hull : t -> (Q.t * Bound.t) option * (Q.t * Bound.t) option =
     match (b, t.integrability) with
     | x, MaybeReal -> x
     | None, _ -> None
-    | Some (z, Bound.Strict), _ when Q.is_integer z ->
-        Some (Q.add (if dir then Q.one else Q.minus_one) z, Large)
-    | Some (z, Bound.Large), _ when Q.is_integer z -> b
-    | Some (z, _), _ -> Some ((if dir then Q.ceil else Q.floor) z, Large)
+    | Some (z, Bound.Strict), _ when A.is_integer z ->
+        Some (A.add (if dir then A.one else A.minus_one) z, Large)
+    | Some (z, Bound.Large), _ when A.is_integer z -> b
+    | Some (z, _), _ -> Some ((if dir then A.ceil else A.floor) z, Large)
   in
   (checkint true (conv inf), checkint false (conv sup))
 
@@ -208,22 +208,22 @@ let from_convexe_hull (c1, c2) : t =
   let ch = (conv c1, conv c2) in
   { u = from_convexe_hull ch; integrability = MaybeReal }
 
-type split_heuristic = Singleton of Q.t | Splitted of t * t | NotSplitted
+type split_heuristic = Singleton of A.t | Splitted of t * t | NotSplitted
 
 let split_heuristic _ = NotSplitted
 
-let choose : t -> Q.t =
+let choose : t -> A.t =
   let get_first_on = function
-    | Sin (q, _) | End (q, Strict, _) -> Q.sub q Q.one
+    | Sin (q, _) | End (q, Strict, _) -> A.sub q A.one
     | End (q, Large, off) -> q
-    | Inf -> Q.zero
+    | Inf -> A.zero
   in
   let get_after_on q' = function
     | Sin (q, _) | End (q, Strict, _) ->
-        let p = Q.sub q Q.one in
-        if Q.lt q' p then p else Q.div_2exp (Q.add q' q) 1
+        let p = A.sub q A.one in
+        if A.lt q' p then p else A.div (A.add q' q) A.two
     | End (q, Large, _) -> q
-    | Inf -> Q.add q' Q.one
+    | Inf -> A.add q' A.one
   in
   let get_first_off = function
     | Sin (q, _) | End (q, Large, _) -> q
@@ -243,7 +243,7 @@ let is_integer = function
 
 let reals = { u = On Inf; integrability = MaybeReal }
 let integers = { u = On Inf; integrability = Integer }
-let zero = { u = Off (Sin (Q.zero, Inf)); integrability = Integer }
+let zero = { u = Off (Sin (A.zero, Inf)); integrability = Integer }
 let gt q = { u = gt q; integrability = MaybeReal }
 let ge q = { u = ge q; integrability = MaybeReal }
 let lt q = { u = lt q; integrability = MaybeReal }
@@ -285,14 +285,14 @@ let add t1 t2 =
   }
 
 let mem q t =
-  (match t.integrability with Integer -> Q.is_integer q | MaybeReal -> true)
+  (match t.integrability with Integer -> A.is_integer q | MaybeReal -> true)
   && mem q t.u
 
 let absent q t = not (mem q t)
 
 let except t q =
   match t.integrability with
-  | Integer when not (Q.is_integer q) -> Some t
+  | Integer when not (A.is_integer q) -> Some t
   | _ -> (
       match except t.u q with
       | Some u -> Some { integrability = t.integrability; u }
@@ -303,25 +303,26 @@ let add_cst q t =
     u = add_cst t.u q;
     integrability =
       (match t.integrability with
-      | Integer when Q.is_integer q -> Integer
+      | Integer when A.is_integer q -> Integer
       | _ -> MaybeReal);
   }
 
 let singleton q =
   {
     u = singleton q;
-    integrability = (if Q.is_integer q then Integer else MaybeReal);
+    integrability = (if A.is_integer q then Integer else MaybeReal);
   }
 
 let is_singleton t = is_singleton t.u
+let count = 20
 
-let%test "singleton" =
+let%test_unit "singleton" =
+  (* Ocaml_poly.PolyUtils.trace_enable "algebraic_number"; *)
   let test =
-    QCheck.Test.make_cell ~count:1000 (QCheck.make Q.gen) (fun q ->
-        Option.is_some (is_singleton (singleton q)))
+    QCheck.Test.make_cell ~count (QCheck.make ~print:A.to_string A.gen)
+      (fun q -> Option.is_some (is_singleton (singleton q)))
   in
-  let res = QCheck.Test.check_cell test in
-  QCheck.TestResult.is_success res
+  QCheck.Test.check_cell_exn test
 
 let interesting_values acc =
   let add q acc = q :: acc in
@@ -348,14 +349,14 @@ let%test_unit "gen_compare" =
     let+ q =
       oneofl
         (interesting_values
-           (interesting_values [ Q.zero; Q.one; Q.minus_one ] t2)
+           (interesting_values [ A.zero; A.one; A.minus_one ] t2)
            t1)
     in
     (true_true, false_true, true_false, false_false, t1, t2, q)
   in
   let pp fmt (true_true, false_true, true_false, false_false, t1, t2, q) =
     Fmt.pf fmt "%b %b %b %b: %a and %a at %a" true_true false_true true_false
-      false_false pp_t' t1 pp_t' t2 Q.pp q
+      false_false pp_t' t1 pp_t' t2 A.pp q
   in
   let shrink (true_true, false_true, true_false, false_false, t1, t2, q) =
     let open QCheck.Iter in
@@ -371,7 +372,7 @@ let%test_unit "gen_compare" =
   in
   let print x = Fmt.str "%a" pp x in
   let test =
-    QCheck.Test.make_cell ~name:"on interesting values" ~count:5000
+    QCheck.Test.make_cell ~name:"on interesting values" ~count
       (QCheck.make ~small ~shrink ~print gen) ~max_fail:10
       (fun (true_true, false_true, true_false, false_false, t1, t2, q) ->
         let b1 = P.mem q t1 in
@@ -387,7 +388,7 @@ let%test_unit "gen_compare" =
         let b' = test b1 b2 in
         (* Format.printf "b = %b; b' = %b; b1 = %b; b2 = %b; %b; r=%a@." b b' b1
          *   b2
-         *   (Q.lt (Q.of_int 4) q)
+         *   (A.lt (A.of_int 4) q)
          *   pp r; *)
         (not b) || b')
   in
@@ -418,29 +419,29 @@ let is_comparable t1 t2 =
       if equal_integrability t1.integrability t2.integrability then Eq
       else Uncomparable
 
-let rec mult_cst_pos (x : Q.t) (l : t'') : t'' =
+let rec mult_cst_pos (x : A.t) (l : t'') : t'' =
   match l with
-  | Sin (q, l') -> Sin (Q.(x * q), mult_cst_pos x l')
-  | End (q, bv, l') -> End (Q.(x * q), bv, mult_cst_pos x l')
+  | Sin (q, l') -> Sin (A.(x * q), mult_cst_pos x l')
+  | End (q, bv, l') -> End (A.(x * q), bv, mult_cst_pos x l')
   | Inf -> Inf
 
-let rec mult_cst_neg if_ (x : Q.t) (l0 : t'') (l : t'') : t' =
+let rec mult_cst_neg if_ (x : A.t) (l0 : t'') (l : t'') : t' =
   match l with
-  | Sin (q, l') -> mult_cst_neg if_ x (Sin (Q.(x * q), l0)) l'
+  | Sin (q, l') -> mult_cst_neg if_ x (Sin (A.(x * q), l0)) l'
   | End (q, bv, l') ->
       mult_cst_neg (not if_) x
-        (End (Q.(x * q), Colibrics_lib__Interval__Bound.inv_bound bv, l0))
+        (End (A.(x * q), Colibrics_lib__Interval__Bound.inv_bound bv, l0))
         l'
   | Inf -> if if_ then On l0 else Off l0
 
 let mult_cst x l =
   let integrability =
     match l.integrability with
-    | Integer -> if Q.is_integer x then Integer else MaybeReal
+    | Integer -> if A.is_integer x then Integer else MaybeReal
     | MaybeReal -> MaybeReal
   in
-  match Colibrics_lib__Q_extra.compare x Q.(of_int 0) with
-  | Eq -> singleton Q.(of_int 0)
+  match compare_ord x A.(of_int 0) with
+  | Eq -> singleton A.(of_int 0)
   | Lt -> (
       match l.u with
       | On l -> { u = mult_cst_neg true x Inf l; integrability }
@@ -452,33 +453,33 @@ let mult_cst x l =
           let l = mult_cst_pos x l in
           { u = Off l; integrability })
 
-let minus a b = add a (mult_cst Q.minus_one b)
+let minus a b = add a (mult_cst A.minus_one b)
 
 let%test_unit "mult_cst" =
   let gen =
     let open QCheck.Gen in
-    let* t1 = gen and* cst = Q.gen in
+    let* t1 = gen and* cst = A.gen in
     let+ q =
-      oneofl (interesting_values [ Q.zero; Q.one; Q.minus_one; cst ] t1.u)
+      oneofl (interesting_values [ A.zero; A.one; A.minus_one; cst ] t1.u)
     in
     (t1, cst, q)
   in
   let print' fmt (t1, cst, q) =
-    Fmt.pf fmt "%a and %a at %a" pp t1 Q.pp cst Q.pp q
+    Fmt.pf fmt "%a and %a at %a" pp t1 A.pp cst A.pp q
   in
   let shrink (t1, cst, q) =
     let open QCheck.Iter in
     map (fun (t1, cst) -> (t1, cst, q))
-    @@ QCheck.Shrink.pair shrink_t Q.shrink (t1, cst)
+    @@ QCheck.Shrink.pair shrink_t A.shrink (t1, cst)
   in
   let small (t1, cst, q) = List.length (interesting_values [] t1.u) in
   let print x = Fmt.str "%a" print' x in
   let test =
-    QCheck.Test.make_cell ~name:"on interesting values" ~count:5000
-      (QCheck.make ~small ~shrink ~print gen) ~max_fail:10 (fun (t1, cst, q) ->
+    QCheck.Test.make_cell ~name:"on interesting values" ~count
+      (QCheck.make ~small ~shrink ~print gen) ~max_fail:1 (fun (t1, cst, q) ->
         let b1 = mem q t1 in
         let t2 = mult_cst cst t1 in
-        let b2 = mem Q.(cst * q) t2 in
+        let b2 = mem (A.mul cst q) t2 in
         (not b1) || b2)
   in
   QCheck.Test.check_cell_exn test
diff --git a/src_colibri2/theories/LRA/stages/stage2/union.mli b/src_colibri2/theories/LRA/stages/stage2/union.mli
index fc4ced47ccf8dcc8d27b409b3f62b8a3d6ccaf19..390d58a04769659fcc8d34d0a8ad0169750d31ac 100644
--- a/src_colibri2/theories/LRA/stages/stage2/union.mli
+++ b/src_colibri2/theories/LRA/stages/stage2/union.mli
@@ -20,6 +20,6 @@
 
 include Interval_sig.S
 
-type split_heuristic = Singleton of Q.t | Splitted of t * t | NotSplitted
+type split_heuristic = Singleton of A.t | Splitted of t * t | NotSplitted
 
 val split_heuristic : t -> split_heuristic
diff --git a/src_common/dune b/src_common/dune
index 71901f3d15fbdc52a7e3be4d359760308b347d46..d0906686a7421be386c527f572f56923e5f0a702 100644
--- a/src_common/dune
+++ b/src_common/dune
@@ -27,13 +27,13 @@
     interval.Convexe interval.Bound))
  (mode promote))
 
-(rule
- (targets interval_with_divider__T.ml)
- (deps q.mlw modulo.mlw interval.mlw interval_with_divider.mlw)
- (action
-  (run why3 extract -D ocaml64 -D %{dep:common.drv} --modular -o . -L .
-    interval_with_divider.T))
- (mode promote))
+; (rule
+;  (targets interval_with_divider__T.ml)
+;  (deps q.mlw modulo.mlw interval.mlw interval_with_divider.mlw)
+;  (action
+;   (run why3 extract -D ocaml64 -D %{dep:common.drv} --modular -o . -L .
+;     interval_with_divider.T))
+;  (mode promote))
 
 (rule
  (targets union__Union.ml)
diff --git a/src_common/interval.mlw b/src_common/interval.mlw
index f5f8ef4c01e4b82a7c7333fd6486336a83c7b910..0005a66092792a65bad17ed1398c0555ec26f3f3 100644
--- a/src_common/interval.mlw
+++ b/src_common/interval.mlw
@@ -9,10 +9,13 @@ end
 module Convexe
   use bool.Bool
   use option.Option
-  use q.Q as Q
   use Bound
   use real.RealInfix
 
+  scope Make
+  clone q.Intf as Q
+    with axiom equal_is_eq
+
   type t =
   | Finite Q.t Bound.t Q.t Bound.t
   | InfFinite Q.t Bound.t
@@ -550,7 +553,7 @@ module Convexe
     ensures { result <-> (forall q. mem q e -> exists z. q = FromInt.from_int z) }
    =
    match e.a with
-   | Finite v1 Large v2 Large    -> andb Q.(v1 = v2) Int.(v1.Q.den = 1)
+   | Finite v1 Large v2 Large    -> andb Q.(v1 = v2) (Q.is_integer v1)
    | Inf
    | InfFinite _ _
    | FiniteInf _ _
@@ -567,10 +570,10 @@ module Convexe
    | FiniteInf v Large
    | Finite v Large _ _
    | Finite _ _ v Large    -> v
-   | InfFinite v Strict    -> Q.(v - (of_int 1)) 
+   | InfFinite v Strict    -> Q.(v - (of_int 1))
    | FiniteInf v Strict    -> Q.(v + (of_int 1))
    | Finite v1 Strict v2 Strict ->
-     let half = Q.make 1 2 in
+     let half = Q.((of_int 1) / (of_int 2)) in
      Q.(v1 * half + v2 * half)
    end
 
@@ -618,10 +621,10 @@ module Convexe
       | _, _, Ord.Eq, Large, _ ->
         Splitted { a = Finite v1 b1 qzero Strict } zero
       | _ ->
-        let half = Q.make 1 2 in
+        let half = Q.((of_int 1) / (of_int 2)) in
         let m = Q.(half * v1 + half * v2) in
         Splitted { a = Finite v1 b1 m Strict } { a = Finite m Large v2 b2 }
       end
     end
-
+  end
 end
diff --git a/src_common/interval__Convexe.ml b/src_common/interval__Convexe.ml
index 44427230b1e06aa369eff2f7ed5d4e1f2f02b85e..12c681205d8275a573d25f141e481b649ede93b7 100644
--- a/src_common/interval__Convexe.ml
+++ b/src_common/interval__Convexe.ml
@@ -1,560 +1,591 @@
-type t =
-  | Finite of (Q.t) * Interval__Bound.t * (Q.t) * Interval__Bound.t
-  | InfFinite of (Q.t) * Interval__Bound.t
-  | FiniteInf of (Q.t) * Interval__Bound.t
-  | Inf
-
-type t' = t
-
-let is_singleton (e: t') : (Q.t) option =
-  match e with
-  | Inf -> None 
-  | InfFinite (v, _) -> None 
-  | FiniteInf (v, _) -> None 
-  | Finite (v, b, v', b') -> if (Q.equal v v') then Some v else None 
-
-let singleton (q: Q.t) : t' =
-  Finite (q, Interval__Bound.Large, q, Interval__Bound.Large)
-
-let except (e: t') (x: Q.t) : t' option =
-  match e with
-  | (Inf | (InfFinite (_, Interval__Bound.Strict) | FiniteInf (_,
-            Interval__Bound.Strict))) ->
-    Some e
-  | InfFinite (v,
-    Interval__Bound.Large) ->
-    if (Q.equal v x)
-    then Some (InfFinite (v, Interval__Bound.Strict))
-    else Some e
-  | FiniteInf (v,
-    Interval__Bound.Large) ->
-    if (Q.equal v x)
-    then Some (FiniteInf (v, Interval__Bound.Strict))
-    else Some e
-  | Finite (_, Interval__Bound.Strict, _, Interval__Bound.Strict) -> Some e
-  | Finite (v,
-    Interval__Bound.Strict,
-    v',
-    Interval__Bound.Large) ->
-    if (Q.equal v' x)
-    then
-      Some (Finite (v, Interval__Bound.Strict, v', Interval__Bound.Strict))
-    else Some e
-  | Finite (v,
-    Interval__Bound.Large,
-    v',
-    Interval__Bound.Strict) ->
-    if (Q.equal v x)
-    then
-      Some (Finite (v, Interval__Bound.Strict, v', Interval__Bound.Strict))
-    else Some e
-  | Finite (v,
-    Interval__Bound.Large,
-    v',
-    Interval__Bound.Large) ->
-    (let is_min = (Q.equal v x) in let is_max = (Q.equal v' x) in
-     if is_min && is_max
-     then None 
-     else
-       begin
-         if is_min
-         then
-           Some (Finite (v, Interval__Bound.Strict, v',
-                 Interval__Bound.Large))
-         else
-           begin
-             if is_max
-             then
-               Some (Finite (v, Interval__Bound.Large, v',
-                     Interval__Bound.Strict))
-             else Some e end end)
-
-type is_comparable =
-  | Gt
-  | Lt
-  | Ge
-  | Le
-  | Eq
-  | Uncomparable
-
-let is_comparable (e1: t') (e2: t') : is_comparable =
-  match (e1, e2) with
-  | ((Inf,
-     Inf) | ((Inf,
-             _) | ((_,
-                   Inf) | ((InfFinite (_, _), InfFinite (_,
-                           _)) | (FiniteInf (_, _), FiniteInf (_, _)))))) ->
-    Uncomparable
-  | ((FiniteInf (v1, b1), InfFinite (v2,
-     b2)) | ((Finite (v1, b1, _, _), InfFinite (v2, b2)) | (FiniteInf (v1,
-             b1), Finite (_, _, v2, b2)))) ->
-    begin match (Q_extra.compare v1 v2) with
-    | Ord.Eq ->
-      begin match (b1, b2) with
-      | (Interval__Bound.Large, Interval__Bound.Large) -> Ge
-      | _ -> Gt
+module Make(Q: sig
+  type t
+  val infix_eq : t -> t -> bool
+  val infix_lseq : t -> t -> bool
+  val infix_ls : t -> t -> bool
+  val abs : t -> t
+  val compare : t -> t -> Ord.t
+  val infix_pl : t -> t -> t
+  val infix_mn : t -> t -> t
+  val infix_as : t -> t -> t
+  val infix_sl : t -> t -> t
+  val of_int : Z.t -> t
+  val floor : t -> Z.t
+  val ceil : t -> Z.t
+  val is_integer : t -> bool end) =
+struct
+  type t =
+    | Finite of Q.t * Interval__Bound.t * Q.t * Interval__Bound.t
+    | InfFinite of Q.t * Interval__Bound.t
+    | FiniteInf of Q.t * Interval__Bound.t
+    | Inf
+  
+  type t' = t
+  
+  let is_singleton (e: t') : Q.t option =
+    match e with
+    | Inf -> None 
+    | InfFinite (v, _) -> None 
+    | FiniteInf (v, _) -> None 
+    | Finite (v, b, v', b') -> if Q.infix_eq v v' then Some v else None 
+  
+  let singleton (q: Q.t) : t' =
+    Finite (q, Interval__Bound.Large, q, Interval__Bound.Large)
+  
+  let except (e: t') (x: Q.t) : t' option =
+    match e with
+    | (Inf | (InfFinite (_, Interval__Bound.Strict) | FiniteInf (_,
+              Interval__Bound.Strict))) ->
+      Some e
+    | InfFinite (v,
+      Interval__Bound.Large) ->
+      if Q.infix_eq v x
+      then Some (InfFinite (v, Interval__Bound.Strict))
+      else Some e
+    | FiniteInf (v,
+      Interval__Bound.Large) ->
+      if Q.infix_eq v x
+      then Some (FiniteInf (v, Interval__Bound.Strict))
+      else Some e
+    | Finite (_, Interval__Bound.Strict, _, Interval__Bound.Strict) -> Some e
+    | Finite (v,
+      Interval__Bound.Strict,
+      v',
+      Interval__Bound.Large) ->
+      if Q.infix_eq v' x
+      then
+        Some (Finite (v, Interval__Bound.Strict, v', Interval__Bound.Strict))
+      else Some e
+    | Finite (v,
+      Interval__Bound.Large,
+      v',
+      Interval__Bound.Strict) ->
+      if Q.infix_eq v x
+      then
+        Some (Finite (v, Interval__Bound.Strict, v', Interval__Bound.Strict))
+      else Some e
+    | Finite (v,
+      Interval__Bound.Large,
+      v',
+      Interval__Bound.Large) ->
+      (let is_min = Q.infix_eq v x in let is_max = Q.infix_eq v' x in
+       if is_min && is_max
+       then None 
+       else
+         begin
+           if is_min
+           then
+             Some (Finite (v, Interval__Bound.Strict, v',
+                   Interval__Bound.Large))
+           else
+             begin
+               if is_max
+               then
+                 Some (Finite (v, Interval__Bound.Large, v',
+                       Interval__Bound.Strict))
+               else Some e end end)
+  
+  type is_comparable =
+    | Gt
+    | Lt
+    | Ge
+    | Le
+    | Eq
+    | Uncomparable
+  
+  let is_comparable (e1: t') (e2: t') : is_comparable =
+    match (e1, e2) with
+    | ((Inf,
+       Inf) | ((Inf,
+               _) | ((_,
+                     Inf) | ((InfFinite (_, _), InfFinite (_,
+                             _)) | (FiniteInf (_, _), FiniteInf (_, _)))))) ->
+      Uncomparable
+    | ((FiniteInf (v1, b1), InfFinite (v2,
+       b2)) | ((Finite (v1, b1, _, _), InfFinite (v2, b2)) | (FiniteInf (v1,
+               b1), Finite (_, _, v2, b2)))) ->
+      begin match Q.compare v1 v2 with
+      | Ord.Eq ->
+        begin match (b1, b2) with
+        | (Interval__Bound.Large, Interval__Bound.Large) -> Ge
+        | _ -> Gt
+        end
+      | Ord.Lt -> Uncomparable
+      | Ord.Gt -> Gt
       end
-    | Ord.Lt -> Uncomparable
-    | Ord.Gt -> Gt
-    end
-  | ((Finite (_, _, v1, b1), FiniteInf (v2,
-     b2)) | ((InfFinite (v1, b1), FiniteInf (v2, b2)) | (InfFinite (v1, b1),
-             Finite (v2, b2, _, _)))) ->
-    begin match (Q_extra.compare v1 v2) with
-    | Ord.Eq ->
-      begin match (b1, b2) with
-      | (Interval__Bound.Large, Interval__Bound.Large) -> Le
-      | _ -> Lt
+    | ((Finite (_, _, v1, b1), FiniteInf (v2,
+       b2)) | ((InfFinite (v1, b1), FiniteInf (v2, b2)) | (InfFinite (v1,
+               b1), Finite (v2, b2, _, _)))) ->
+      begin match Q.compare v1 v2 with
+      | Ord.Eq ->
+        begin match (b1, b2) with
+        | (Interval__Bound.Large, Interval__Bound.Large) -> Le
+        | _ -> Lt
+        end
+      | Ord.Lt -> Lt
+      | Ord.Gt -> Uncomparable
       end
-    | Ord.Lt -> Lt
-    | Ord.Gt -> Uncomparable
-    end
-  | (Finite (v1,
-    b1,
-    v1',
-    b1'),
-    Finite (v2,
-    b2,
-    v2',
-    b2')) ->
-    begin match ((Q_extra.compare v1' v2), (Q_extra.compare v1 v2')) with
-    | (Ord.Eq, Ord.Eq) -> Eq
-    | (Ord.Eq,
-      _) ->
-      begin match (b1', b2) with
-      | (Interval__Bound.Large, Interval__Bound.Large) -> Le
-      | _ -> Lt
+    | (Finite (v1,
+      b1,
+      v1',
+      b1'),
+      Finite (v2,
+      b2,
+      v2',
+      b2')) ->
+      begin match (Q.compare v1' v2, Q.compare v1 v2') with
+      | (Ord.Eq, Ord.Eq) -> Eq
+      | (Ord.Eq,
+        _) ->
+        begin match (b1', b2) with
+        | (Interval__Bound.Large, Interval__Bound.Large) -> Le
+        | _ -> Lt
+        end
+      | (_,
+        Ord.Eq) ->
+        begin match (b1, b2') with
+        | (Interval__Bound.Large, Interval__Bound.Large) -> Ge
+        | _ -> Gt
+        end
+      | (Ord.Lt, _) -> Lt
+      | (_, Ord.Gt) -> Gt
+      | _ -> Uncomparable
       end
-    | (_,
-      Ord.Eq) ->
-      begin match (b1, b2') with
-      | (Interval__Bound.Large, Interval__Bound.Large) -> Ge
-      | _ -> Gt
+  
+  let is_distinct (e1: t') (e2: t') : bool =
+    match is_comparable e1 e2 with
+    | (Uncomparable | (Le | (Ge | Eq))) -> false
+    | _ -> true
+  
+  let is_included (e1: t') (e2: t') : bool =
+    match (e1, e2) with
+    | (Inf, Inf) -> true
+    | ((Inf,
+       _) | ((InfFinite (_, _),
+             (FiniteInf (_, _) | Finite (_, _, _, _))) | (FiniteInf (_, _),
+             (InfFinite (_, _) | Finite (_, _, _, _))))) ->
+      false
+    | (_, Inf) -> true
+    | ((InfFinite (v1, b1), InfFinite (v2, b2)) | (Finite (_, _, v1, b1),
+       InfFinite (v2, b2))) ->
+      begin match Q.compare v1 v2 with
+      | Ord.Eq ->
+        begin match (b1, b2) with
+        | (Interval__Bound.Large, Interval__Bound.Strict) -> false
+        | _ -> true
+        end
+      | Ord.Lt -> true
+      | Ord.Gt -> false
       end
-    | (Ord.Lt, _) -> Lt
-    | (_, Ord.Gt) -> Gt
-    | _ -> Uncomparable
-    end
-
-let is_distinct (e1: t') (e2: t') : bool =
-  match is_comparable e1 e2 with
-  | (Uncomparable | (Le | (Ge | Eq))) -> false
-  | _ -> true
-
-let is_included (e1: t') (e2: t') : bool =
-  match (e1, e2) with
-  | (Inf, Inf) -> true
-  | ((Inf,
-     _) | ((InfFinite (_, _),
-           (FiniteInf (_, _) | Finite (_, _, _, _))) | (FiniteInf (_, _),
-           (InfFinite (_, _) | Finite (_, _, _, _))))) ->
-    false
-  | (_, Inf) -> true
-  | ((InfFinite (v1, b1), InfFinite (v2, b2)) | (Finite (_, _, v1, b1),
-     InfFinite (v2, b2))) ->
-    begin match (Q_extra.compare v1 v2) with
-    | Ord.Eq ->
-      begin match (b1, b2) with
-      | (Interval__Bound.Large, Interval__Bound.Strict) -> false
-      | _ -> true
+    | ((FiniteInf (v1, b1), FiniteInf (v2, b2)) | (Finite (v1, b1, _, _),
+       FiniteInf (v2, b2))) ->
+      begin match Q.compare v1 v2 with
+      | Ord.Eq ->
+        begin match (b1, b2) with
+        | (Interval__Bound.Large, Interval__Bound.Strict) -> false
+        | _ -> true
+        end
+      | Ord.Lt -> false
+      | Ord.Gt -> true
       end
-    | Ord.Lt -> true
-    | Ord.Gt -> false
-    end
-  | ((FiniteInf (v1, b1), FiniteInf (v2, b2)) | (Finite (v1, b1, _, _),
-     FiniteInf (v2, b2))) ->
-    begin match (Q_extra.compare v1 v2) with
-    | Ord.Eq ->
-      begin match (b1, b2) with
-      | (Interval__Bound.Large, Interval__Bound.Strict) -> false
-      | _ -> true
+    | (Finite (v1,
+      b1,
+      v1',
+      b1'),
+      Finite (v2,
+      b2,
+      v2',
+      b2')) ->
+      begin match (Q.compare v2 v1, Q.compare v1' v2', b1, b2, b1', b2') with
+      | (Ord.Eq,
+        _,
+        Interval__Bound.Large,
+        Interval__Bound.Strict,
+        _,
+        _) ->
+        false
+      | (_,
+        Ord.Eq,
+        _,
+        _,
+        Interval__Bound.Large,
+        Interval__Bound.Strict) ->
+        false
+      | ((Ord.Lt | Ord.Eq), (Ord.Lt | Ord.Eq), _, _, _, _) -> true
+      | _ -> false
       end
-    | Ord.Lt -> false
-    | Ord.Gt -> true
-    end
-  | (Finite (v1,
-    b1,
-    v1',
-    b1'),
-    Finite (v2,
-    b2,
-    v2',
-    b2')) ->
-    begin
-      match
-      ((Q_extra.compare v2 v1), (Q_extra.compare v1' v2'), b1, b2, b1', b2')
-    with
-    | (Ord.Eq,
-      _,
-      Interval__Bound.Large,
-      Interval__Bound.Strict,
-      _,
-      _) ->
-      false
-    | (_,
-      Ord.Eq,
-      _,
-      _,
-      Interval__Bound.Large,
-      Interval__Bound.Strict) ->
-      false
-    | ((Ord.Lt | Ord.Eq), (Ord.Lt | Ord.Eq), _, _, _, _) -> true
-    | _ -> false
-    end
-
-let cmp (x: Q.t) (b: Interval__Bound.t) (y: Q.t) : bool =
-  match b with
-  | Interval__Bound.Large -> (Q.(<=) x y)
-  | Interval__Bound.Strict -> (Q.(<) x y)
-
-let mem (x: Q.t) (e: t') : bool =
-  match e with
-  | Inf -> true
-  | InfFinite (v, b) -> cmp x b v
-  | FiniteInf (v, b) -> cmp v b x
-  | Finite (v, b, v', b') -> cmp v b x && cmp x b' v'
-
-let absent (x: Q.t) (e: t') : bool = not (mem x e)
-
-let mult_pos (q: Q.t) (e: t') : t' =
-  match e with
-  | Inf -> Inf
-  | InfFinite (v, b) -> InfFinite ((Q.( * ) q v), b)
-  | FiniteInf (v, b) -> FiniteInf ((Q.( * ) q v), b)
-  | Finite (v, b, v', b') -> Finite ((Q.( * ) q v), b, (Q.( * ) q v'), b')
-
-let mult_neg (q: Q.t) (e: t') : t' =
-  match e with
-  | Inf -> Inf
-  | InfFinite (v, b) -> FiniteInf ((Q.( * ) q v), b)
-  | FiniteInf (v, b) -> InfFinite ((Q.( * ) q v), b)
-  | Finite (v, b, v', b') -> Finite ((Q.( * ) q v'), b', (Q.( * ) q v), b)
-
-let mult_cst (c: Q.t) (e: t') : t' =
-  if (Q.equal c (Q.of_bigint Z.zero))
-  then singleton (Q.of_bigint Z.zero)
-  else
-    begin
-      if (Q.(<) (Q.of_bigint Z.zero) c) then mult_pos c e else mult_neg c e end
-
-let add_cst (q: Q.t) (e: t') : t' =
-  match e with
-  | Inf -> Inf
-  | InfFinite (v, b) -> InfFinite ((Q.(+) q v), b)
-  | FiniteInf (v, b) -> FiniteInf ((Q.(+) q v), b)
-  | Finite (v, b, v', b') -> Finite ((Q.(+) q v), b, (Q.(+) q v'), b')
-
-let add_bound (b1: Interval__Bound.t) (b2: Interval__Bound.t) :
-  Interval__Bound.t =
-  match (b1, b2) with
-  | (Interval__Bound.Large, Interval__Bound.Large) -> Interval__Bound.Large
-  | (Interval__Bound.Large, Interval__Bound.Strict) -> Interval__Bound.Strict
-  | (Interval__Bound.Strict, Interval__Bound.Large) -> Interval__Bound.Strict
-  | (Interval__Bound.Strict,
-    Interval__Bound.Strict) ->
-    Interval__Bound.Strict
-
-let add (e1: t') (e2: t') : t' =
-  match (e1, e2) with
-  | ((Inf, _) | (_, Inf)) -> Inf
-  | ((InfFinite (_, _), FiniteInf (_, _)) | (FiniteInf (_, _), InfFinite (_,
-     _))) ->
-    Inf
-  | ((InfFinite (v1, b1),
-     (InfFinite (v2, b2) | Finite (_, _, v2, b2))) | (Finite (_, _, v2, b2),
-     InfFinite (v1, b1))) ->
-    InfFinite ((Q.(+) v1 v2), add_bound b1 b2)
-  | ((FiniteInf (v1, b1),
-     (FiniteInf (v2, b2) | Finite (v2, b2, _, _))) | (Finite (v2, b2, _, _),
-     FiniteInf (v1, b1))) ->
-    FiniteInf ((Q.(+) v1 v2), add_bound b1 b2)
-  | (Finite (v1,
-    b1,
-    v1',
-    b1'),
-    Finite (v2,
-    b2,
-    v2',
-    b2')) ->
-    Finite ((Q.(+) v1 v2),
-    add_bound b1 b2,
-    (Q.(+) v1' v2'),
-    add_bound b1' b2')
-
-let minus (e1: t') (e2: t') : t' =
-  add e1 (mult_neg (Q.of_bigint (Z.of_string "-1")) e2)
-
-let gt (c: Q.t) : t' = FiniteInf (c, Interval__Bound.Strict)
-
-let ge (c: Q.t) : t' = FiniteInf (c, Interval__Bound.Large)
-
-let lt (c: Q.t) : t' = InfFinite (c, Interval__Bound.Strict)
-
-let le (c: Q.t) : t' = InfFinite (c, Interval__Bound.Large)
-
-let gt' (c: t') : t' =
-  match c with
-  | Finite (v, _, _, _) -> FiniteInf (v, Interval__Bound.Strict)
-  | InfFinite (_, _) -> Inf
-  | FiniteInf (_, Interval__Bound.Strict) -> c
-  | FiniteInf (v,
-    Interval__Bound.Large) ->
-    FiniteInf (v, Interval__Bound.Strict)
-  | Inf -> Inf
-
-let ge' (c: t') : t' =
-  match c with
-  | Finite (v, b, _, _) -> FiniteInf (v, b)
-  | InfFinite (_, _) -> Inf
-  | FiniteInf (_, _) -> c
-  | Inf -> Inf
-
-let lt' (c: t') : t' =
-  match c with
-  | Finite (_, _, v, _) -> InfFinite (v, Interval__Bound.Strict)
-  | InfFinite (_, Interval__Bound.Strict) -> c
-  | InfFinite (v,
-    Interval__Bound.Large) ->
-    InfFinite (v, Interval__Bound.Strict)
-  | FiniteInf (_, _) -> Inf
-  | Inf -> Inf
-
-let le' (c: t') : t' =
-  match c with
-  | Finite (_, _, v, b) -> InfFinite (v, b)
-  | InfFinite (_, _) -> c
-  | FiniteInf (_, _) -> Inf
-  | Inf -> Inf
-
-let min_bound_sup (v1: Q.t) (b1: Interval__Bound.t) (v2: Q.t)
-                  (b2: Interval__Bound.t) : (Q.t) * Interval__Bound.t =
-  match ((Q_extra.compare v1 v2), b1, b2) with
-  | (Ord.Eq,
-    Interval__Bound.Large,
-    Interval__Bound.Large) ->
-    (v1, Interval__Bound.Large)
-  | (Ord.Eq, _, _) -> (v1, Interval__Bound.Strict)
-  | (Ord.Lt, _, _) -> (v1, b1)
-  | (Ord.Gt, _, _) -> (v2, b2)
-
-let min_bound_inf (v1: Q.t) (b1: Interval__Bound.t) (v2: Q.t)
-                  (b2: Interval__Bound.t) : (Q.t) * Interval__Bound.t =
-  match ((Q_extra.compare v1 v2), b1, b2) with
-  | (Ord.Eq,
-    Interval__Bound.Strict,
-    Interval__Bound.Strict) ->
-    (v1, Interval__Bound.Strict)
-  | (Ord.Eq, _, _) -> (v1, Interval__Bound.Large)
-  | (Ord.Lt, _, _) -> (v1, b1)
-  | (Ord.Gt, _, _) -> (v2, b2)
-
-let max_bound_sup (v1: Q.t) (b1: Interval__Bound.t) (v2: Q.t)
-                  (b2: Interval__Bound.t) : (Q.t) * Interval__Bound.t =
-  match ((Q_extra.compare v1 v2), b1, b2) with
-  | (Ord.Eq,
-    Interval__Bound.Strict,
-    Interval__Bound.Strict) ->
-    (v1, Interval__Bound.Strict)
-  | (Ord.Eq, _, _) -> (v1, Interval__Bound.Large)
-  | (Ord.Lt, _, _) -> (v2, b2)
-  | (Ord.Gt, _, _) -> (v1, b1)
-
-let max_bound_inf (v1: Q.t) (b1: Interval__Bound.t) (v2: Q.t)
-                  (b2: Interval__Bound.t) : (Q.t) * Interval__Bound.t =
-  match ((Q_extra.compare v1 v2), b1, b2) with
-  | (Ord.Eq,
-    Interval__Bound.Large,
-    Interval__Bound.Large) ->
-    (v1, Interval__Bound.Large)
-  | (Ord.Eq, _, _) -> (v1, Interval__Bound.Strict)
-  | (Ord.Lt, _, _) -> (v2, b2)
-  | (Ord.Gt, _, _) -> (v1, b1)
-
-let union (e1: t') (e2: t') : t' =
-  match (e1, e2) with
-  | ((Inf, _) | (_, Inf)) -> Inf
-  | ((InfFinite (_, _), FiniteInf (_, _)) | (FiniteInf (_, _), InfFinite (_,
-     _))) ->
-    Inf
-  | ((InfFinite (v1, b1),
-     (InfFinite (v2, b2) | Finite (_, _, v2, b2))) | (Finite (_, _, v2, b2),
-     InfFinite (v1, b1))) ->
-    (let (v3, b3) = max_bound_sup v1 b1 v2 b2 in InfFinite (v3, b3))
-  | ((FiniteInf (v1, b1),
-     (FiniteInf (v2, b2) | Finite (v2, b2, _, _))) | (Finite (v2, b2, _, _),
-     FiniteInf (v1, b1))) ->
-    (let (v31, b31) = min_bound_inf v1 b1 v2 b2 in FiniteInf (v31, b31))
-  | (Finite (v1,
-    b1,
-    v1',
-    b1'),
-    Finite (v2,
-    b2,
-    v2',
-    b2')) ->
-    (let (v32, b32) = min_bound_inf v1 b1 v2 b2 in
-     let (v4,
-     b4) =
-     max_bound_sup v1' b1' v2' b2' in
-     Finite (v32, b32, v4, b4))
-
-let mk_finite (v1: Q.t) (b1: Interval__Bound.t) (v2: Q.t)
-              (b2: Interval__Bound.t) : t' option =
-  match (Q_extra.compare v1 v2) with
-  | Ord.Eq ->
-    begin match (b1, b2) with
+  
+  let cmp (x: Q.t) (b: Interval__Bound.t) (y: Q.t) : bool =
+    match b with
+    | Interval__Bound.Large -> Q.infix_lseq x y
+    | Interval__Bound.Strict -> Q.infix_ls x y
+  
+  let mem (x: Q.t) (e: t') : bool =
+    match e with
+    | Inf -> true
+    | InfFinite (v, b) -> cmp x b v
+    | FiniteInf (v, b) -> cmp v b x
+    | Finite (v, b, v', b') -> cmp v b x && cmp x b' v'
+  
+  let absent (x: Q.t) (e: t') : bool = not (mem x e)
+  
+  let mult_pos (q: Q.t) (e: t') : t' =
+    match e with
+    | Inf -> Inf
+    | InfFinite (v, b) -> InfFinite (Q.infix_as q v, b)
+    | FiniteInf (v, b) -> FiniteInf (Q.infix_as q v, b)
+    | Finite (v,
+      b,
+      v',
+      b') ->
+      Finite (Q.infix_as q v, b, Q.infix_as q v', b')
+  
+  let mult_neg (q: Q.t) (e: t') : t' =
+    match e with
+    | Inf -> Inf
+    | InfFinite (v, b) -> FiniteInf (Q.infix_as q v, b)
+    | FiniteInf (v, b) -> InfFinite (Q.infix_as q v, b)
+    | Finite (v,
+      b,
+      v',
+      b') ->
+      Finite (Q.infix_as q v', b', Q.infix_as q v, b)
+  
+  let mult_cst (c: Q.t) (e: t') : t' =
+    if Q.infix_eq c (Q.of_int Z.zero)
+    then singleton (Q.of_int Z.zero)
+    else
+      begin
+        if Q.infix_ls (Q.of_int Z.zero) c then mult_pos c e else mult_neg c e end
+  
+  let add_cst (q: Q.t) (e: t') : t' =
+    match e with
+    | Inf -> Inf
+    | InfFinite (v, b) -> InfFinite (Q.infix_pl q v, b)
+    | FiniteInf (v, b) -> FiniteInf (Q.infix_pl q v, b)
+    | Finite (v,
+      b,
+      v',
+      b') ->
+      Finite (Q.infix_pl q v, b, Q.infix_pl q v', b')
+  
+  let add_bound (b1: Interval__Bound.t) (b2: Interval__Bound.t) :
+    Interval__Bound.t =
+    match (b1, b2) with
+    | (Interval__Bound.Large, Interval__Bound.Large) -> Interval__Bound.Large
     | (Interval__Bound.Large,
+      Interval__Bound.Strict) ->
+      Interval__Bound.Strict
+    | (Interval__Bound.Strict,
       Interval__Bound.Large) ->
-      Some (Finite (v1, Interval__Bound.Large, v2, Interval__Bound.Large))
-    | _ -> None 
-    end
-  | Ord.Lt -> Some (Finite (v1, b1, v2, b2))
-  | Ord.Gt -> None 
-
-let inter (e1: t') (e2: t') : t' option =
-  match (e1, e2) with
-  | (Inf, _) -> Some e2
-  | (_, Inf) -> Some e1
-  | ((InfFinite (v1, b1), FiniteInf (v2, b2)) | (FiniteInf (v2, b2),
-     InfFinite (v1, b1))) ->
-    mk_finite v2 b2 v1 b1
-  | (InfFinite (v1,
-    b1),
-    InfFinite (v2,
-    b2)) ->
-    (let (v33, b33) = min_bound_sup v1 b1 v2 b2 in
-     Some (InfFinite (v33, b33)))
-  | ((InfFinite (v1, b1), Finite (v2, b2, v34, b34)) | (Finite (v2, b2, v34,
-     b34), InfFinite (v1, b1))) ->
-    (let (v41, b41) = min_bound_sup v1 b1 v34 b34 in mk_finite v2 b2 v41 b41)
-  | (FiniteInf (v1,
-    b1),
-    FiniteInf (v2,
-    b2)) ->
-    (let (v34, b34) = max_bound_inf v1 b1 v2 b2 in
-     let r = FiniteInf (v34, b34) in Some r)
-  | ((FiniteInf (v1, b1), Finite (v2, b2, v35, b35)) | (Finite (v2, b2, v35,
-     b35), FiniteInf (v1, b1))) ->
-    (let (v42, b42) = max_bound_inf v1 b1 v2 b2 in mk_finite v42 b42 v35 b35)
-  | (Finite (v1,
-    b1,
-    v1',
-    b1'),
-    Finite (v2,
-    b2,
-    v2',
-    b2')) ->
-    (let (v35, b35) = max_bound_inf v1 b1 v2 b2 in
-     let (v43,
-     b43) =
-     min_bound_sup v1' b1' v2' b2' in
-     mk_finite v35 b35 v43 b43)
-
-let zero = singleton (Q.of_bigint Z.zero)
-
-let reals = Inf
-
-let is_reals (e: t') : bool =
-  match e with
-  | Inf -> true
-  | InfFinite (v, _) -> false
-  | FiniteInf (v, _) -> false
-  | Finite (v, _, _, _) -> false
-
-let integers = reals
-
-let is_integer (e: t') : bool =
-  match e with
-  | Finite (v1,
-    Interval__Bound.Large,
-    v2,
-    Interval__Bound.Large) ->
-    (Q.equal v1 v2) && Z.equal (v1.Q.den) Z.one
-  | (Inf | (InfFinite (_, _) | (FiniteInf (_, _) | Finite (_, _, _, _)))) ->
-    false
-
-let choose (e: t') : Q.t =
-  match e with
-  | Inf -> (Q.of_bigint Z.zero)
-  | (InfFinite (v,
-     Interval__Bound.Large) | (FiniteInf (v,
-                               Interval__Bound.Large) | (Finite (v,
-                                                         Interval__Bound.Large,
-                                                         _, _) | Finite (_,
-                                                         _, v,
-                                                         Interval__Bound.Large)))) ->
-    v
-  | InfFinite (v, Interval__Bound.Strict) -> (Q.(-) v (Q.of_bigint Z.one))
-  | FiniteInf (v, Interval__Bound.Strict) -> (Q.(+) v (Q.of_bigint Z.one))
-  | Finite (v1,
-    Interval__Bound.Strict,
-    v2,
-    Interval__Bound.Strict) ->
-    (let half = (Q.make Z.one (Z.of_string "2")) in
-     (Q.(+) (Q.( * ) v1 half) (Q.( * ) v2 half)))
-
-type split_heuristic =
-  | Singleton of (Q.t)
-  | Splitted of t' * t'
-  | NotSplitted
-
-let split_heuristic (c: t') : split_heuristic =
-  let qzero = (Q.of_bigint Z.zero) in
-  let zero = singleton qzero in
-  match c with
-  | Inf ->
-    Splitted (InfFinite (qzero, Interval__Bound.Strict),
-    FiniteInf (qzero, Interval__Bound.Large))
-  | InfFinite (v,
-    b) ->
-    begin match ((Q_extra.compare qzero v), b) with
-    | (Ord.Eq,
+      Interval__Bound.Strict
+    | (Interval__Bound.Strict,
+      Interval__Bound.Strict) ->
+      Interval__Bound.Strict
+  
+  let add (e1: t') (e2: t') : t' =
+    match (e1, e2) with
+    | ((Inf, _) | (_, Inf)) -> Inf
+    | ((InfFinite (_, _), FiniteInf (_, _)) | (FiniteInf (_, _),
+       InfFinite (_, _))) ->
+      Inf
+    | ((InfFinite (v1, b1),
+       (InfFinite (v2, b2) | Finite (_, _, v2, b2))) | (Finite (_, _, v2,
+       b2), InfFinite (v1, b1))) ->
+      InfFinite (Q.infix_pl v1 v2, add_bound b1 b2)
+    | ((FiniteInf (v1, b1),
+       (FiniteInf (v2, b2) | Finite (v2, b2, _, _))) | (Finite (v2, b2, _,
+       _), FiniteInf (v1, b1))) ->
+      FiniteInf (Q.infix_pl v1 v2, add_bound b1 b2)
+    | (Finite (v1,
+      b1,
+      v1',
+      b1'),
+      Finite (v2,
+      b2,
+      v2',
+      b2')) ->
+      Finite (Q.infix_pl v1 v2,
+      add_bound b1 b2,
+      Q.infix_pl v1' v2',
+      add_bound b1' b2')
+  
+  let minus (e1: t') (e2: t') : t' =
+    add e1 (mult_neg (Q.of_int (Z.of_string "-1")) e2)
+  
+  let gt (c: Q.t) : t' = FiniteInf (c, Interval__Bound.Strict)
+  
+  let ge (c: Q.t) : t' = FiniteInf (c, Interval__Bound.Large)
+  
+  let lt (c: Q.t) : t' = InfFinite (c, Interval__Bound.Strict)
+  
+  let le (c: Q.t) : t' = InfFinite (c, Interval__Bound.Large)
+  
+  let gt' (c: t') : t' =
+    match c with
+    | Finite (v, _, _, _) -> FiniteInf (v, Interval__Bound.Strict)
+    | InfFinite (_, _) -> Inf
+    | FiniteInf (_, Interval__Bound.Strict) -> c
+    | FiniteInf (v,
       Interval__Bound.Large) ->
-      Splitted (InfFinite (qzero, Interval__Bound.Strict), zero)
-    | ((Ord.Eq, Interval__Bound.Strict) | (Ord.Gt, _)) -> NotSplitted
-    | (Ord.Lt,
-      _) ->
-      Splitted (InfFinite (qzero, Interval__Bound.Strict),
-      Finite (qzero, Interval__Bound.Large, v, b))
-    end
-  | FiniteInf (v,
-    b) ->
-    begin match ((Q_extra.compare v qzero), b) with
+      FiniteInf (v, Interval__Bound.Strict)
+    | Inf -> Inf
+  
+  let ge' (c: t') : t' =
+    match c with
+    | Finite (v, b, _, _) -> FiniteInf (v, b)
+    | InfFinite (_, _) -> Inf
+    | FiniteInf (_, _) -> c
+    | Inf -> Inf
+  
+  let lt' (c: t') : t' =
+    match c with
+    | Finite (_, _, v, _) -> InfFinite (v, Interval__Bound.Strict)
+    | InfFinite (_, Interval__Bound.Strict) -> c
+    | InfFinite (v,
+      Interval__Bound.Large) ->
+      InfFinite (v, Interval__Bound.Strict)
+    | FiniteInf (_, _) -> Inf
+    | Inf -> Inf
+  
+  let le' (c: t') : t' =
+    match c with
+    | Finite (_, _, v, b) -> InfFinite (v, b)
+    | InfFinite (_, _) -> c
+    | FiniteInf (_, _) -> Inf
+    | Inf -> Inf
+  
+  let min_bound_sup (v1: Q.t) (b1: Interval__Bound.t) (v2: Q.t)
+                    (b2: Interval__Bound.t) : Q.t * Interval__Bound.t =
+    match (Q.compare v1 v2, b1, b2) with
     | (Ord.Eq,
+      Interval__Bound.Large,
       Interval__Bound.Large) ->
-      Splitted (zero, FiniteInf (v, Interval__Bound.Strict))
-    | ((Ord.Eq, Interval__Bound.Strict) | (Ord.Gt, _)) -> NotSplitted
-    | (Ord.Lt,
-      _) ->
-      Splitted (Finite (v, b, qzero, Interval__Bound.Strict),
-      FiniteInf (qzero, Interval__Bound.Large))
-    end
-  | Finite (v1,
-    b1,
-    v2,
-    b2) ->
-    begin
-      match
-      ((Q_extra.compare v1 qzero), b1, (Q_extra.compare v2 qzero), b2,
-      (Q_extra.compare v1 v2))
-    with
-    | (_, _, _, _, Ord.Eq) -> Singleton v1
+      (v1, Interval__Bound.Large)
+    | (Ord.Eq, _, _) -> (v1, Interval__Bound.Strict)
+    | (Ord.Lt, _, _) -> (v1, b1)
+    | (Ord.Gt, _, _) -> (v2, b2)
+  
+  let min_bound_inf (v1: Q.t) (b1: Interval__Bound.t) (v2: Q.t)
+                    (b2: Interval__Bound.t) : Q.t * Interval__Bound.t =
+    match (Q.compare v1 v2, b1, b2) with
+    | (Ord.Eq,
+      Interval__Bound.Strict,
+      Interval__Bound.Strict) ->
+      (v1, Interval__Bound.Strict)
+    | (Ord.Eq, _, _) -> (v1, Interval__Bound.Large)
+    | (Ord.Lt, _, _) -> (v1, b1)
+    | (Ord.Gt, _, _) -> (v2, b2)
+  
+  let max_bound_sup (v1: Q.t) (b1: Interval__Bound.t) (v2: Q.t)
+                    (b2: Interval__Bound.t) : Q.t * Interval__Bound.t =
+    match (Q.compare v1 v2, b1, b2) with
+    | (Ord.Eq,
+      Interval__Bound.Strict,
+      Interval__Bound.Strict) ->
+      (v1, Interval__Bound.Strict)
+    | (Ord.Eq, _, _) -> (v1, Interval__Bound.Large)
+    | (Ord.Lt, _, _) -> (v2, b2)
+    | (Ord.Gt, _, _) -> (v1, b1)
+  
+  let max_bound_inf (v1: Q.t) (b1: Interval__Bound.t) (v2: Q.t)
+                    (b2: Interval__Bound.t) : Q.t * Interval__Bound.t =
+    match (Q.compare v1 v2, b1, b2) with
     | (Ord.Eq,
       Interval__Bound.Large,
-      _,
-      _,
-      _) ->
-      Splitted (zero, Finite (qzero, Interval__Bound.Strict, v2, b2))
-    | (_,
-      _,
-      Ord.Eq,
+      Interval__Bound.Large) ->
+      (v1, Interval__Bound.Large)
+    | (Ord.Eq, _, _) -> (v1, Interval__Bound.Strict)
+    | (Ord.Lt, _, _) -> (v2, b2)
+    | (Ord.Gt, _, _) -> (v1, b1)
+  
+  let union (e1: t') (e2: t') : t' =
+    match (e1, e2) with
+    | ((Inf, _) | (_, Inf)) -> Inf
+    | ((InfFinite (_, _), FiniteInf (_, _)) | (FiniteInf (_, _),
+       InfFinite (_, _))) ->
+      Inf
+    | ((InfFinite (v1, b1),
+       (InfFinite (v2, b2) | Finite (_, _, v2, b2))) | (Finite (_, _, v2,
+       b2), InfFinite (v1, b1))) ->
+      (let (v3, b3) = max_bound_sup v1 b1 v2 b2 in InfFinite (v3, b3))
+    | ((FiniteInf (v1, b1),
+       (FiniteInf (v2, b2) | Finite (v2, b2, _, _))) | (Finite (v2, b2, _,
+       _), FiniteInf (v1, b1))) ->
+      (let (v31, b31) = min_bound_inf v1 b1 v2 b2 in FiniteInf (v31, b31))
+    | (Finite (v1,
+      b1,
+      v1',
+      b1'),
+      Finite (v2,
+      b2,
+      v2',
+      b2')) ->
+      (let (v32, b32) = min_bound_inf v1 b1 v2 b2 in
+       let (v4,
+       b4) =
+       max_bound_sup v1' b1' v2' b2' in
+       Finite (v32, b32, v4, b4))
+  
+  let mk_finite (v1: Q.t) (b1: Interval__Bound.t) (v2: Q.t)
+                (b2: Interval__Bound.t) : t' option =
+    match Q.compare v1 v2 with
+    | Ord.Eq ->
+      begin match (b1, b2) with
+      | (Interval__Bound.Large,
+        Interval__Bound.Large) ->
+        Some (Finite (v1, Interval__Bound.Large, v2, Interval__Bound.Large))
+      | _ -> None 
+      end
+    | Ord.Lt -> Some (Finite (v1, b1, v2, b2))
+    | Ord.Gt -> None 
+  
+  let inter (e1: t') (e2: t') : t' option =
+    match (e1, e2) with
+    | (Inf, _) -> Some e2
+    | (_, Inf) -> Some e1
+    | ((InfFinite (v1, b1), FiniteInf (v2, b2)) | (FiniteInf (v2, b2),
+       InfFinite (v1, b1))) ->
+      mk_finite v2 b2 v1 b1
+    | (InfFinite (v1,
+      b1),
+      InfFinite (v2,
+      b2)) ->
+      (let (v33, b33) = min_bound_sup v1 b1 v2 b2 in
+       Some (InfFinite (v33, b33)))
+    | ((InfFinite (v1, b1), Finite (v2, b2, v34, b34)) | (Finite (v2, b2,
+       v34, b34), InfFinite (v1, b1))) ->
+      (let (v41, b41) = min_bound_sup v1 b1 v34 b34 in
+       mk_finite v2 b2 v41 b41)
+    | (FiniteInf (v1,
+      b1),
+      FiniteInf (v2,
+      b2)) ->
+      (let (v34, b34) = max_bound_inf v1 b1 v2 b2 in
+       let r = FiniteInf (v34, b34) in Some r)
+    | ((FiniteInf (v1, b1), Finite (v2, b2, v35, b35)) | (Finite (v2, b2,
+       v35, b35), FiniteInf (v1, b1))) ->
+      (let (v42, b42) = max_bound_inf v1 b1 v2 b2 in
+       mk_finite v42 b42 v35 b35)
+    | (Finite (v1,
+      b1,
+      v1',
+      b1'),
+      Finite (v2,
+      b2,
+      v2',
+      b2')) ->
+      (let (v35, b35) = max_bound_inf v1 b1 v2 b2 in
+       let (v43,
+       b43) =
+       min_bound_sup v1' b1' v2' b2' in
+       mk_finite v35 b35 v43 b43)
+  
+  let zero = singleton (Q.of_int Z.zero)
+  
+  let reals = Inf
+  
+  let is_reals (e: t') : bool =
+    match e with
+    | Inf -> true
+    | InfFinite (v, _) -> false
+    | FiniteInf (v, _) -> false
+    | Finite (v, _, _, _) -> false
+  
+  let integers = reals
+  
+  let is_integer (e: t') : bool =
+    match e with
+    | Finite (v1,
       Interval__Bound.Large,
-      _) ->
-      Splitted (Finite (v1, b1, qzero, Interval__Bound.Strict), zero)
-    | _ ->
-      (let half = (Q.make Z.one (Z.of_string "2")) in
-       let m = (Q.(+) (Q.( * ) half v1) (Q.( * ) half v2)) in
-       Splitted (Finite (v1, b1, m, Interval__Bound.Strict),
-       Finite (m, Interval__Bound.Large, v2, b2)))
-    end
+      v2,
+      Interval__Bound.Large) ->
+      Q.infix_eq v1 v2 && Q.is_integer v1
+    | (Inf | (InfFinite (_, _) | (FiniteInf (_, _) | Finite (_, _, _, _)))) ->
+      false
+  
+  let choose (e: t') : Q.t =
+    match e with
+    | Inf -> Q.of_int Z.zero
+    | (InfFinite (v,
+       Interval__Bound.Large) | (FiniteInf (v,
+                                 Interval__Bound.Large) | (Finite (v,
+                                                           Interval__Bound.Large,
+                                                           _, _) | Finite (_,
+                                                           _, v,
+                                                           Interval__Bound.Large)))) ->
+      v
+    | InfFinite (v, Interval__Bound.Strict) -> Q.infix_mn v (Q.of_int Z.one)
+    | FiniteInf (v, Interval__Bound.Strict) -> Q.infix_pl v (Q.of_int Z.one)
+    | Finite (v1,
+      Interval__Bound.Strict,
+      v2,
+      Interval__Bound.Strict) ->
+      (let half = Q.infix_sl (Q.of_int Z.one) (Q.of_int (Z.of_string "2")) in
+       Q.infix_pl (Q.infix_as v1 half) (Q.infix_as v2 half))
+  
+  type split_heuristic =
+    | Singleton of Q.t
+    | Splitted of t' * t'
+    | NotSplitted
+  
+  let split_heuristic (c: t') : split_heuristic =
+    let qzero = Q.of_int Z.zero in
+    let zero = singleton qzero in
+    match c with
+    | Inf ->
+      Splitted (InfFinite (qzero, Interval__Bound.Strict),
+      FiniteInf (qzero, Interval__Bound.Large))
+    | InfFinite (v,
+      b) ->
+      begin match (Q.compare qzero v, b) with
+      | (Ord.Eq,
+        Interval__Bound.Large) ->
+        Splitted (InfFinite (qzero, Interval__Bound.Strict), zero)
+      | ((Ord.Eq, Interval__Bound.Strict) | (Ord.Gt, _)) -> NotSplitted
+      | (Ord.Lt,
+        _) ->
+        Splitted (InfFinite (qzero, Interval__Bound.Strict),
+        Finite (qzero, Interval__Bound.Large, v, b))
+      end
+    | FiniteInf (v,
+      b) ->
+      begin match (Q.compare v qzero, b) with
+      | (Ord.Eq,
+        Interval__Bound.Large) ->
+        Splitted (zero, FiniteInf (v, Interval__Bound.Strict))
+      | ((Ord.Eq, Interval__Bound.Strict) | (Ord.Gt, _)) -> NotSplitted
+      | (Ord.Lt,
+        _) ->
+        Splitted (Finite (v, b, qzero, Interval__Bound.Strict),
+        FiniteInf (qzero, Interval__Bound.Large))
+      end
+    | Finite (v1,
+      b1,
+      v2,
+      b2) ->
+      begin
+        match
+        (Q.compare v1 qzero, b1, Q.compare v2 qzero, b2, Q.compare v1 v2)
+      with
+      | (_, _, _, _, Ord.Eq) -> Singleton v1
+      | (Ord.Eq,
+        Interval__Bound.Large,
+        _,
+        _,
+        _) ->
+        Splitted (zero, Finite (qzero, Interval__Bound.Strict, v2, b2))
+      | (_,
+        _,
+        Ord.Eq,
+        Interval__Bound.Large,
+        _) ->
+        Splitted (Finite (v1, b1, qzero, Interval__Bound.Strict), zero)
+      | _ ->
+        (let half = Q.infix_sl (Q.of_int Z.one) (Q.of_int (Z.of_string "2")) in
+         let m = Q.infix_pl (Q.infix_as half v1) (Q.infix_as half v2) in
+         Splitted (Finite (v1, b1, m, Interval__Bound.Strict),
+         Finite (m, Interval__Bound.Large, v2, b2)))
+      end
+end
 
diff --git a/src_common/interval_with_divider.mlw b/src_common/interval_with_divider.mlw
index e36702d2b835c8c0a95e7d0c157e355f6130d25f..0e7500a6827ed2d191e0100b9d92f5fb0c3a94b3 100644
--- a/src_common/interval_with_divider.mlw
+++ b/src_common/interval_with_divider.mlw
@@ -6,9 +6,14 @@ module T
   use q.Q as Q
   use option.Option
   use interval.Bound
-  use interval.Convexe
   use modulo.Divisible
 
+  scope Make
+  clone q.Intf as Q
+    with axiom equal_is_eq
+
+     clone interval.Convexe with type Q.t = Q.t ..
+
   predicate best_convexe (c: Convexe.t') (d:real) =
    match c.a with
      | Inf -> true
diff --git a/src_common/interval_with_divider__T.ml b/src_common/interval_with_divider__T.ml
deleted file mode 100644
index 7863d6252b54589cc9d1590a7f8f8939c1ddd5f2..0000000000000000000000000000000000000000
--- a/src_common/interval_with_divider__T.ml
+++ /dev/null
@@ -1,88 +0,0 @@
-type t = {
-  c: Interval__Convexe.t';
-  divider: (Q.t) option;
-  }
-
-let is_singleton (e: t) : (Q.t) option = Interval__Convexe.is_singleton e.c
-
-let singleton (q: Q.t) : t =
-  { c = Interval__Convexe.singleton q; divider = Some (Q.abs q) }
-
-let round_down_to (v: Q.t) (b: Interval__Bound.t) (d: Q.t) : Q.t =
-  let v' = Modulo__Divisible.round_down_to v d in
-  match b with
-  | Interval__Bound.Strict ->
-    if (Q.equal v v') then let v'' = (Q.(-) v d) in v'' else v'
-  | Interval__Bound.Large -> v'
-
-let round_up_to (v: Q.t) (b: Interval__Bound.t) (d: Q.t) : Q.t =
-  let v' = Modulo__Divisible.round_up_to v d in
-  match b with
-  | Interval__Bound.Strict ->
-    if (Q.equal v v') then let v'' = (Q.(+) v d) in v'' else v'
-  | Interval__Bound.Large -> v'
-
-let tighten_bounds (c: Interval__Convexe.t') (d: Q.t) : t option =
-  let qzero = (Q.of_bigint Z.zero) in
-  if (Q.equal d qzero)
-  then
-    if Interval__Convexe.mem qzero c then Some (singleton qzero) else None 
-  else
-    begin match c with
-    | Interval__Convexe.Inf -> Some { c = c; divider = Some d }
-    | Interval__Convexe.InfFinite (v,
-      b) ->
-      (let r = round_down_to v b d in
-       let c1 = Interval__Convexe.InfFinite (r, Interval__Bound.Large) in
-       Some { c = c1; divider = Some d })
-    | Interval__Convexe.FiniteInf (v,
-      b) ->
-      (let r = round_up_to v b d in
-       let c1 = Interval__Convexe.FiniteInf (r, Interval__Bound.Large) in
-       Some { c = c1; divider = Some d })
-    | Interval__Convexe.Finite (v1,
-      b1,
-      v2,
-      b2) ->
-      (let v11 = round_up_to v1 b1 d in let v21 = round_down_to v2 b2 d in
-       match
-         Interval__Convexe.mk_finite v11
-         Interval__Bound.Large
-         v21
-         Interval__Bound.Large
-       with
-       | None -> None 
-       | Some c1 -> Some { c = c1; divider = Some d })
-    end
-
-let except (e: t) (x: Q.t) : t option =
-  match Interval__Convexe.except e.c x with
-  | None -> None 
-  | Some o ->
-    begin match e.divider with
-    | Some d -> tighten_bounds o d
-    | None -> Some { c = o; divider = None  }
-    end
-
-let is_comparable (e1: t) (e2: t) : Interval__Convexe.is_comparable =
-  Interval__Convexe.is_comparable e1.c e2.c
-
-let is_distinct (e1: t) (e2: t) : bool =
-  Interval__Convexe.is_distinct e1.c e2.c
-
-let is_included (e1: t) (e2: t) : bool =
-  Interval__Convexe.is_included e1.c e2.c && begin
-                                               match
-                                               (e1.divider, e2.divider)
-                                             with
-  | (_, None) -> true
-  | (None, Some _) -> false
-  | (Some d1, Some d2) -> (let b = Modulo__Divisible.divisible d1 d2 in b)
-  end
-
-let mem (x: Q.t) (e: t) : bool =
-  Interval__Convexe.mem x e.c && begin match e.divider with
-  | None -> true
-  | Some d -> (let b = Modulo__Divisible.divisible x d in b)
-  end
-
diff --git a/src_common/q.mlw b/src_common/q.mlw
index db92cea2d26a34c0e30cae723cbce2a64afadf62..4c8ce8d4b75a473ea7464c6b9632248a603b3647 100644
--- a/src_common/q.mlw
+++ b/src_common/q.mlw
@@ -367,6 +367,7 @@ module Q
      let ceil (a:t) : int
        ensures { result = ceil a.real } =
         Z.cdiv a.num a.den
+
 end
 
 module Intf
@@ -435,4 +436,7 @@ module Intf
 
      val ceil (a:t) : int
        ensures { result = ceil a.real }
+
+     val is_integer (a:t) : bool
+       ensures { result = (exists z. a = FromInt.from_int z) }
 end
diff --git a/src_common/union__Union.ml b/src_common/union__Union.ml
index acff0205b71b5073686a89f47eeb840acd8f1fa8..810eda2ded05d8387aac6065f61cb8a96b344b63 100644
--- a/src_common/union__Union.ml
+++ b/src_common/union__Union.ml
@@ -11,7 +11,8 @@ module Make(Q: sig
   val infix_sl : t -> t -> t
   val of_int : Z.t -> t
   val floor : t -> Z.t
-  val ceil : t -> Z.t end) =
+  val ceil : t -> Z.t
+  val is_integer : t -> bool end) =
 struct
   type t'' =
     | Sin of Q.t * t''