diff --git a/src/plugins/qed/term.ml b/src/plugins/qed/term.ml
index 4802b27d25093b9c9f2c11ede869d029dd324f8a..ea395a42ef1aa19c58aa4a70f9269ef7fcfc6024 100644
--- a/src/plugins/qed/term.ml
+++ b/src/plugins/qed/term.ml
@@ -1197,6 +1197,20 @@ struct
     | x::ts -> r_ground f c (x::xs) ts
     | [] -> c , xs
 
+  let q_times k z =
+    if Z.equal k Z.one then z else
+    if Z.equal k Z.zero then Q.zero else
+      Q.(make (Z.mul k z.num) z.den)
+
+  let rec times z e =
+    if Z.equal z Z.one then e else
+    if Z.equal z Z.zero then e_zint Z.zero else
+      match e.repr with
+      | Kint z' -> e_zint (Z.mul z z')
+      | Kreal r -> e_real (q_times z r)
+      | Times(z',t) -> times (Z.mul z z') t
+      | _ -> c_times z e
+
   (* -------------------------------------------------------------------------- *)
   (* --- Affine Comparisons                                                 --- *)
   (* -------------------------------------------------------------------------- *)
@@ -1241,43 +1255,137 @@ struct
 
   (* --- Affine Ratios --- *)
 
-  (*
-  let i_ratio = function
-    | [] -> ZERO
-    | [{ repr=Div(a,b) }] ->
-        begin match b.repr with
-          | Kint k when not Z.(equal k zero) -> DIV(a,k)
-          | _ -> ANY
-        end
-    | _ -> ANY
-  *)
+  type i_form = Z.t * term list
+  type ratio = POS of i_form * Z.t | NEG of i_form * Z.t | NONE
 
-  let i_affine_ratio_leq c xs ys = i_affine_leq c xs ys
+  let i_form = function
+    | { repr = Kint c } -> c,[]
+    | { repr = Add es } ->
+        ( match es with
+          | x::xs ->
+              ( match x with
+                | { repr = Kint c } -> c , xs
+                | _ -> Z.zero , es )
+          | [] -> Z.zero,[] )
+    | e -> Z.zero,[e]
 
-  let i_affine_ratio_lt c xs ys = i_affine_lt c xs ys
+  let i_ratio = function
+    | [{ repr=Div(a,b) }] ->
+        (match b.repr with
+         | Kint k ->
+             (match sign k with
+              | Positive -> POS(i_form a,k)
+              | Negative -> NEG(i_form a,Z.neg k)
+              | Null -> NONE)
+         | _ -> NONE)
+    | _ -> NONE
+
+  let i_opp xs = List.map (times Z.minus_one) xs
+  let i_times k xs = List.map (times k) xs
+
+  (* [LC] we can do better here *)
+  let i_pos0 = function c,[] -> Z.(leq zero c) | _ -> false
+  let i_pos1 = function c,[] -> Z.(lt zero c)  | _ -> false
+  let i_neg0 = function c,[] -> Z.(leq c zero) | _ -> false
+  let i_neg1 = function c,[] -> Z.(lt c zero)  | _ -> false
+
+  (* k < 0 *)
+  let rec i_ratio_max a k b =
+    if i_pos0 a || i_pos0 b then
+      (* [pos_max] (0 <= a || 0 <= b) -> ( a/k <= b <-> a < b*k + k ) *)
+      let x,xs = a in
+      let y,ys = b in
+      (* x+xs < k.(y+ys) + k <==> x-k.(y+1) + xs < k.ys *)
+      i_affine_ratio_lt Z.(sub x (mul k (succ y))) xs (i_times k ys)
+    else
+    if i_neg0 a || i_neg1 b then
+      (* [neg_max] (a <= 0 || b < 0) -> ( a/k <= b <-> a <= b*k ) *)
+      let x,xs = a in
+      let y,ys = b in
+      (* x+xs <= k.(y+ys) <==> x-k.y + xs <= k.ys *)
+      i_affine_ratio_leq Z.(sub x (mul k y)) xs (i_times k ys)
+    else
+      raise Not_found
+
+  and i_ratio_min b a k =
+    if i_pos0 a || i_pos1 b then
+      (* [pos_min] (0 <= a || 0 < b) -> ( b <= a/k <-> b*k <= a ) *)
+      let x,xs = a in
+      let y,ys = b in
+      (* k.(y+ys) <= x+xs <==> k.y-x + k.ys <= xs *)
+      i_affine_ratio_leq Z.(sub (mul k y) x) (i_times k ys) xs
+    else
+    if i_neg0 a || i_neg0 b then
+      (* [neg_min] (a <= 0 || b <= 0) -> ( b <= a/k <-> b*k - k < a ) *)
+      let x,xs = a in
+      let y,ys = b in
+      (* k.(y+ys)-k < x+xs <==> k.(y-1)-x + k.ys < xs *)
+      i_affine_ratio_lt Z.(sub (mul k (pred y)) x) (i_times k ys) xs
+    else
+      raise Not_found
+
+  and i_affine_ratio_leq c xs ys =
+    try match i_ratio xs , i_ratio ys with
+      | POS(a,k) , NONE ->
+        (* c + a/k <= ys <==>  a/k <= -c+ys *)
+          i_ratio_max a k (Z.neg c,ys)
+      | NEG(a,k) , NONE ->
+          (* c - a/k <= ys <==> c-ys <= a/k  *)
+          i_ratio_min (c,i_opp ys) a k
+      | NONE , POS(a,k) ->
+          (* c + xs <= a/k *)
+          i_ratio_min (c,xs) a k
+      | NONE , NEG(a,k) ->
+          (* c + xs <= -a/k <==> a/k <= -c-xs *)
+          i_ratio_max a k (Z.neg c,i_opp xs)
+      | _ ->
+          (* c+xs <= ys *)
+          i_affine_leq c xs ys
+    with Not_found ->
+      i_affine_leq c xs ys
+
+  and i_affine_ratio_lt c xs ys =
+    try match i_ratio xs , i_ratio ys with
+      | POS(a,k) , NONE ->
+          (* c + a/k < ys <==> a/k <= -c-1+ys *)
+          i_ratio_max a k (Z.pred (Z.neg c),ys)
+      | NEG(a,k) , NONE ->
+          (* c - a/k < ys <==> c+1-ys <= a/k *)
+          i_ratio_min (Z.succ c,i_opp ys) a k
+      | NONE , POS(a,k) ->
+          (* c + xs < a/k <==> c+1+xs <= a/k *)
+          i_ratio_min (Z.succ c,xs) a k
+      | NONE , NEG(a,k) ->
+          (* c + xs < -a/k <==> a/k <= -c-1-xs *)
+          i_ratio_max a k (Z.pred (Z.neg c),i_opp xs)
+      | _ ->
+          (* c+xs < ys *)
+          i_affine_lt c xs ys
+    with Not_found ->
+      i_affine_lt c xs ys
 
   (* --- Affine Dispatch --- *)
 
-  let i_affine xs ys =
+  let is_affine xs ys =
     not (List.exists is_real xs || List.exists is_real ys)
 
   let affine_eq c xs ys =
-    if i_affine xs ys
+    if is_affine xs ys
     then i_affine_rel Z.equal c_builtin_eq c xs ys
     else r_affine_rel Q.equal c_builtin_eq c xs ys
 
   let affine_neq c xs ys =
-    if i_affine xs ys
+    if is_affine xs ys
     then i_affine_rel (fun x y -> not (Z.equal x y)) c_builtin_neq c xs ys
     else r_affine_rel (fun x y -> not (Q.equal x y)) c_builtin_neq c xs ys
 
   let affine_leq c xs ys =
-    if i_affine xs ys
+    if is_affine xs ys
     then i_affine_ratio_leq c xs ys
     else r_affine_rel Q.leq c_builtin_leq c xs ys
 
   let affine_lt c xs ys =
-    if i_affine xs ys
+    if is_affine xs ys
     then i_affine_ratio_lt c xs ys
     else r_affine_rel Q.lt c_builtin_lt c xs ys
 
@@ -1287,23 +1395,9 @@ struct
     | NEQ -> affine_neq
     | LEQ -> affine_leq
 
-  (* --- Times --- *)
-
-  let q_times k z =
-    if Z.equal k Z.one then z else
-    if Z.equal k Z.zero then Q.zero else
-      Q.(make (Z.mul k z.num) z.den)
-
-  let rec times z e =
-    if Z.equal z Z.one then e else
-    if Z.equal z Z.zero then e_zint Z.zero else
-      match e.repr with
-      | Kint z' -> e_zint (Z.mul z z')
-      | Kreal r -> e_real (q_times z r)
-      | Times(z',t) -> times (Z.mul z z') t
-      | _ -> c_times z e
-
-  (* --- Additions --- *)
+  (* -------------------------------------------------------------------------- *)
+  (* --- Affine Form                                                        --- *)
+  (* -------------------------------------------------------------------------- *)
 
   let rec unfold_affine acc k = function
     | [] -> acc