diff --git a/Src/COLIBRI/QF_LRA b/Src/COLIBRI/QF_LRA
new file mode 120000
index 0000000000000000000000000000000000000000..fc098200d87d9d6a8ec14daa19572a3e3275ad3d
--- /dev/null
+++ b/Src/COLIBRI/QF_LRA
@@ -0,0 +1 @@
+../../../svn_gatel/trunk/Src/COLIBRI/QF_LRA
\ No newline at end of file
diff --git a/Src/COLIBRI/arith.pl b/Src/COLIBRI/arith.pl
index c9d7be0cbb79736557d8d1ced3f965d8d7c5d3d4..539305cdf03643ed9d914d9443b00a74e63d8059 100755
--- a/Src/COLIBRI/arith.pl
+++ b/Src/COLIBRI/arith.pl
@@ -40,12 +40,12 @@
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 :- export add/3.
 add(A,B,C) :-
-	set_lazy_domain(int,A),
-	set_lazy_domain(int,B),
+    set_lazy_domain(int,A),
+    set_lazy_domain(int,B),
     % un minus cache ??
     (get_type(C,int) ->
         true
-    ;	mfd:dvar_range(A,MinA,MaxA),
+    ;   mfd:dvar_range(A,MinA,MaxA),
         mfd:dvar_range(B,MinB,MaxB),
         MinC is MinA+MinB,
         MaxC is MaxA+MaxB,
@@ -81,7 +81,7 @@ add_int(A,TA,B,TB,C,TC) :-
     wake_if_other_scheduled(Prio).
 
 % on cherche A + (-X) = C --> X + C = A 
-%check_add_opp(A,B,C,1) :- !.
+check_add_opp(A,B,C,1) :- !.
 check_add_opp(A,B,C,Continue) :-
     save_cstr_suspensions((A,B)),
     get_saved_cstr_suspensions(LS),
@@ -1347,7 +1347,10 @@ minus(A,B,C) :-
         MinC is MinA-MaxB,
         MaxC is MaxA-MinB,
         mfd:(C::MinC..MaxC)),
-    add(B,C,A).
+%    add(B,C,A).
+    % ennoncé permettant de garder C en résultat
+    op(B,OpB),
+    add(A,OpB,C).
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %% 							C = A * B
@@ -1385,7 +1388,7 @@ no_lin_mult(A,B,C) :-
 
 
 mult_int(A,_,A,_,C,_) ?- !,
-    power(A,2,C).
+    square(A,C).
 mult_int(A,TA,B,TB,C,TC) :-
     get_priority(Prio),
     set_priority(1),
@@ -1411,6 +1414,7 @@ mult_bis(A,TA,B,TB,C,TC) :-
     mfd:get_intervals(B,IB),
     mfd:get_intervals(C,IC),
     save_cstr_suspensions((A,B,C)),
+    get_saved_cstr_suspensions(LSusp),
     % Point fixe sur les projections de congruence
     % on peut aller jusqu'a instancier A,B ou C
     fp_congr_mult(int,A,B,C),
@@ -1423,30 +1427,47 @@ mult_bis(A,TA,B,TB,C,TC) :-
             true
         ;   % Factorisation avec un mult_int
             clear_Goal(mult_int,A,B,C),
-            % On regarde si on a un div_mod_int(C,A,...)
-            % ou div_mod_int(C,B,...)
-            check_fusion_div_mod_int(mult_int,A,B,C),
-            check_zero_mult_int(A,B,C),
-            check_assoc_dist(mult_int,A,B,C),
-            % On a peut etre reduit A,B,C avant
-            mfd:get_intervals(A,NIA),
-            mfd:get_intervals(B,NIB),
-            mfd:get_intervals(C,NIC),
-            check_reduced(IA,NIA,TA),
-            check_reduced(IB,NIB,TB),
-            check_reduced(IC,NIC,TC),
-            ((true;var(TA),var(TB),var(TC)) ->
-                % Probleme avec arith_sched sans doute
-                TA = 1,
-                TB = 1,
-                TC = 1
-            ;   true),
-            % Calcul des projections
-            mult_free_proj(A,TA,B,TB,C,TC),
-            int_check_notify_constrained(A,IA),
-            int_check_notify_constrained(B,IB),
-            int_check_notify_constrained(C,IC),
-            check_before_susp_mult(A,B,C))).
+            ((member((Susp,mult_int(AA,_,BB,_,CC,_)),LSusp),
+              CC == C,
+              (A == BB ->
+                  exists_diff_Rel(B,AA),
+                  Z = A
+              ;   (A == AA ->
+                      exists_diff_Rel(B,BB),
+                      Z =  A
+                  ;   B == BB,
+                      exists_diff_Rel(A,AA),
+                      Z = B)))
+            ->
+                % cas manquant
+                call(spy_here)@eclipse,
+                kill_suspension(Susp),
+                protected_unify(C,0),
+                protected_unify(Z,0)
+            ;   % On regarde si on a un div_mod_int(C,A,...)
+                % ou div_mod_int(C,B,...)
+                check_fusion_div_mod_int(mult_int,A,B,C),
+                check_zero_mult_int(A,B,C),
+                check_assoc_dist(mult_int,A,B,C),
+                % On a peut etre reduit A,B,C avant
+                mfd:get_intervals(A,NIA),
+                mfd:get_intervals(B,NIB),
+                mfd:get_intervals(C,NIC),
+                check_reduced(IA,NIA,TA),
+                check_reduced(IB,NIB,TB),
+                check_reduced(IC,NIC,TC),
+                ((true;var(TA),var(TB),var(TC)) ->
+                    % Probleme avec arith_sched sans doute
+                    TA = 1,
+                    TB = 1,
+                    TC = 1
+                ;   true),
+                % Calcul des projections
+                mult_free_proj(A,TA,B,TB,C,TC),
+                int_check_notify_constrained(A,IA),
+                int_check_notify_constrained(B,IB),
+                int_check_notify_constrained(C,IC),
+                check_before_susp_mult(A,B,C)))).
 
 
 check_exists_power_int_with_mult_args(X,Y,Z,1,Continue) ?- !,
@@ -4603,30 +4624,64 @@ check_zero_and_div_interval(Val1,Val2,Val) :-
 
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% 							B = A^2
+%% 	B = A^2
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 square(A,B) :-
-	power(A,2,B).
+    power(A,2,B).
 
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% 							B = A^N avec N entier >= 0
+%% 	B = A^N avec N entier >= 0
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 power(A,N,B) :-
-	set_lazy_domain(int,A),
-	integer(N),
-	(N == 0 ->
-		protected_unify(B = 1)
-	;	(N == 1 ->
-			protected_unify(B = A)
-		;	N > 1,
-			(get_type(B,int) ->
-				true
-			;	mfd:dvar_range(A,MinA,MaxA),
-				Mod2 is N mod 2,
-				power_interval_list([MinA..MaxA],N,Mod2,IB),
-				mfd:(B::IB)),
-			power_int(A,1,N,B,1))).
+    get_priority(P),
+    set_priority(1),
+    set_lazy_domain(int,A),
+    set_lazy_domain(int,B),
+    integer(N),
+    (N \== 2 ->
+        (N == 0 ->
+            protected_unify(B = 1)
+        ;   (N == 1 ->
+                protected_unify(B = A)
+            ;   N > 1,
+                (get_type(B,int) ->
+                    true
+                ;   mfd:dvar_range(A,MinA,MaxA),
+                    Mod2 is N mod 2,
+                    power_interval_list([MinA..MaxA],N,Mod2,IB),
+                    mfd:(B::IB)),
+                power_int(A,1,N,B,1)))
+    ;   get_cstr_suspensions(A,LS),
+        ((Goal = add_int(X,_,Y,_,AA,_),
+          member(Susp,LS),
+          get_suspension_data(Susp,goal,Goal),
+          A == AA)
+        ->
+            % Identités remarquables:
+            % (X+Y)^2 ou (X-Y)^2
+            % SATURATION DU STORE
+            ((delayed_goals(Y,DGY),
+              member(op_int(Z,YY),DGY),
+              Y == YY)
+            ->
+                % c'est un minus: (X-Z)^2
+                power(X,2,X2),
+                power(Z,2,Z2),
+                add(X2,Z2,X2pZ2),
+                mult(X,Z,XZ),
+                mult(-2,XZ,MDXZ),
+                add(X2pZ2,MDXZ,B)
+            ;   power(X,2,X2),
+                power(Y,2,Y2),
+                add(X2,Y2,X2pY2),
+                mult(X,Y,XY),
+                mult(2,XY,DXY),
+                add(X2pY2,DXY,B))
+        ;   power_int(A,1,2,B,1),
+            lin_mult_int(A,A,B))),
+    set_priority(P),
+    wake_if_other_scheduled(P).
 
 
 power_int(A,TA,N,B,TB) :-
diff --git a/Src/COLIBRI/arith_sched.pl b/Src/COLIBRI/arith_sched.pl
index 5f79db330e9c86f5c4b1467080cf9e5e287c1809..dc9b35cd11a0beeb9bb5dc5ce43422168717637b 100755
--- a/Src/COLIBRI/arith_sched.pl
+++ b/Src/COLIBRI/arith_sched.pl
@@ -81,6 +81,22 @@ set_touched_arg_from_goal(mult_real1(_,A,B,C),_Var,S) :- !,
         NInst = NInst0),
     change_prio_if_inst_arg(NInst,2,S,LP,4).
 
+set_touched_arg_from_goal(square_real1(_,A,B),_Var,S) :- !,
+    ((nonvar(A);
+      nonvar(B);
+      A == B)
+    ->
+        change_prio_if_not_RC(S,2)
+    ;   true).
+
+set_touched_arg_from_goal(sqrt_real1(_,A,B),_Var,S) :- !,
+    ((nonvar(A);
+      nonvar(B);
+      A == B)
+    ->
+        change_prio_if_not_RC(S,2)
+    ;   true).
+
 set_touched_arg_from_goal(div_mod_int(A,B,C,_BC,R),_Var,S) :- !,
     term_variables((A,B,C,R),L),
     NInst0 is 4 - length(L),
@@ -127,10 +143,14 @@ set_touched_arg_from_goal(op_int(A,B),_Var,S) :- !,
         ->
             change_prio_if_not_RC(S,2)
         ;   true)).
-set_touched_arg_from_goal(op_real1(_,A,B),_Var,S) :- !,
+set_touched_arg_from_goal(op_real1(Type,A,B),_Var,S) :- !,
     (nonvar(A) ->
         (nonvar(B) ->
-            B is -A
+            ((Type == real,
+              B == 0.0)
+            ->
+                B == A
+            ;   B is -A)
         ;   change_prio_if_not_RC(S,2))
     ;   ((nonvar(B);
           A == B)
diff --git a/Src/COLIBRI/check_lin_expr.pl b/Src/COLIBRI/check_lin_expr.pl
index a1cbfe23481b434ab55b60b8e755e2f5e046f6aa..b51c5c62ccb66a97e2833f53b82df2e6f4cea308 100755
--- a/Src/COLIBRI/check_lin_expr.pl
+++ b/Src/COLIBRI/check_lin_expr.pl
@@ -26,8 +26,8 @@ check_exists_lin_expr_giving_diff_args(Type,A,B,Stop) :-
     ->
         true
     ;   getval(gdbg,1)@eclipse,
-        call(spy_here)@eclipse,
-        try_check_exists_lin_expr_giving_diff_args(Type,A,B,Stop),
+        %call(spy_here)@eclipse,
+        %try_check_exists_lin_expr_giving_diff_args(Type,A,B,Stop),
         writeln(output,fail_lin_expr_giving_diff_args),
         fail).
 check_exists_lin_expr_giving_diff_args(_,_,_,_).
@@ -100,6 +100,7 @@ try_check_exists_lin_expr_giving_diff_args(Type,A,B,Stop) :-
                 launch_congr(B,Rest2,Mod2)
             ;   true))
     ;   true),
+    check_same_lin_sum(Res1,Res2),
     protected_find_square_ids(Res1,NRes1),
     protected_find_square_ids(Res2,NRes2),
     %remove_common_vars(L1,L2,NL1,NL2,Work),
@@ -211,20 +212,21 @@ get_single_var_square_ids(LS,NL,EndNL,Cst0,NCst,Work) :-
       % X^2 + X + 1_4 -> 1_4*(4*X2 +2*(4/2)*X +1)
       % 1_4*((2*X + 1)^2 + (4-4)X^2)
       % 1_4*(2*X + 1)^2
-      Factor = Cst1,
       CX2 is safe_div_rat(CX21,Cst1),
       CX is safe_div_rat(CX1,Cst1),
       NCX2 is safe_div_rat(CX,2_1),
       RemCX20 is safe_minus_rat(CX2,safe_mult_rat(NCX2,NCX2)),
-      RemCX20 >= 0,
-      RemCX2 is (Factor*Sign)*RemCX20,
-      RemCst is Factor*Sign)
+      RemCX20 >= 0)
     ->
         Work = 1,
+        Factor = Cst1,
+        RemCX2 is (Factor*Sign)*RemCX20,
         NX = NCX2*X,
         Sum = NX + 1,
         SId = sqr(Sum),
         CSum is Factor*Sign,
+        % On a consommé CSum de Cst0
+        RemCst is Cst0 - CSum,
         ((member_begin_end(CS*Sqr1,NEndNL,NNEndNL,ES,ES),
           nonvar(Sqr1),
           Sqr1 = sqr(SSum),
@@ -854,173 +856,173 @@ get_args_from_other_add_op_mult(Type,LC,V,LArgs) :-
 
 
 remove_common_vars([],L2,[],NL2,_) :- !,
-	remove_null_fact(L2,NL2).
+    remove_null_fact(L2,NL2).
 remove_common_vars(L1,[],NL1,[],_) :- !,
-	remove_null_fact(L1,NL1).
+    remove_null_fact(L1,NL1).
 remove_common_vars([N1*X|L1],L2,NewL1,NewL2,Work) :-
-	((occurs(X,L2),
-	  member_begin_end(N2*XX,L2,NL2,End,End),
-	  X == XX)
-	->
-		Work = 1,
-		(N1 > N2 ->
-			Diff is N1 - N2,
-			NewL1 = [Diff*X|EndNewL1],
-			remove_common_vars(L1,NL2,EndNewL1,NewL2,_)
-		;	(N1 == N2 ->
-				remove_common_vars(L1,NL2,NewL1,NewL2,_)
-			;	%% N1 < N2
-				Diff is N2 - N1,
-				NewL2 = [Diff*X|EndNewL2],
-				remove_common_vars(L1,NL2,NewL1,EndNewL2,_)))
-	;	(N1 == 0 ->
-			remove_common_vars(L1,L2,NewL1,NewL2,Work)
-		;	NewL1 = [N1*X|EndNewL1],
-			remove_common_vars(L1,L2,EndNewL1,NewL2,Work))).
+    ((occurs(X,L2),
+      member_begin_end(N2*XX,L2,NL2,End,End),
+      X == XX)
+    ->
+        Work = 1,
+        (N1 > N2 ->
+            Diff is N1 - N2,
+            NewL1 = [Diff*X|EndNewL1],
+            remove_common_vars(L1,NL2,EndNewL1,NewL2,_)
+        ;   (N1 == N2 ->
+                remove_common_vars(L1,NL2,NewL1,NewL2,_)
+            ;   % N1 < N2
+                Diff is N2 - N1,
+                NewL2 = [Diff*X|EndNewL2],
+                remove_common_vars(L1,NL2,NewL1,EndNewL2,_)))
+    ;   (N1 == 0 ->
+            remove_common_vars(L1,L2,NewL1,NewL2,Work)
+        ;   NewL1 = [N1*X|EndNewL1],
+            remove_common_vars(L1,L2,EndNewL1,NewL2,Work))).
 
 remove_null_fact([],[]).
 remove_null_fact([N*X|L],NL) :-
-	(N =:= 0 ->
-		remove_null_fact(L,NL)
-	;	NL = [N*X|EndL],
-		remove_null_fact(L,EndL)).
+    (N =:= 0 ->
+        remove_null_fact(L,NL)
+    ;   NL = [N*X|EndL],
+        remove_null_fact(L,EndL)).
 
 
 %% Coeff1*V1 + C1 = Coeff2*V2 + C2
 %% On regarde si on peut definir V1 (ou V2) en fonction
 %% de V2 (ou V1) par Vi = K*Vj + Cste
 get_affine_def_from_lin_expr([Coeff1*V1],[Coeff2*V2],C1,C2,FromGoal,Goal) :-
-	GCD is gcd(Coeff1,Coeff2),
-	(GCD == Coeff1 ->
-		Cste0 is C2-C1,
-		0 is Cste0 mod GCD,
-		X = V1,
-		Y = V2,
-		K is Coeff2 div GCD
-	;	GCD == Coeff2,
-		Cste0 is C1-C2,
-		0 is Cste0 mod GCD,
-		X = V2,
-		Y = V1,
-		K is Coeff1 div GCD),
-	Cste is Cste0 div GCD,
-	(K == 1 ->
-		(Cste == 0 ->
-			Goal = [X=Y]
-		;	(FromGoal = add(B,C,A) ->
-				%% pour ne pas boucler
-				(Y,Cste) \== (B,C),
-				(Y,Cste) \== (C,B)
-			;	true),
-			Goal = [no_lin_add(Y,Cste,X)])
-	;	(FromGoal = mult(B,C,A) ->
-			%% pour ne pas boucler
-			(K,Y) \== (B,C),
-			(Y,K) \== (B,C)
-		;	true),
-		(Cste == 0 ->
-			Goal = [no_lin_mult(K,Y,X)]
-		;	(FromGoal == add(B,C,A) ->
-				%% pour ne pas boucler
-				(Cste,X) \== (B,A),
-				(Cste,X) \== (C,A)
-			;	true),
-			Goal = [no_lin_mult(K,Y,P),no_lin_add(P,Cste,X)])),
-	!.
+    GCD is gcd(Coeff1,Coeff2),
+    (GCD == Coeff1 ->
+        Cste0 is C2-C1,
+        0 is Cste0 mod GCD,
+        X = V1,
+        Y = V2,
+        K is Coeff2 div GCD
+    ;   GCD == Coeff2,
+        Cste0 is C1-C2,
+        0 is Cste0 mod GCD,
+        X = V2,
+        Y = V1,
+        K is Coeff1 div GCD),
+    Cste is Cste0 div GCD,
+    (K == 1 ->
+        (Cste == 0 ->
+            Goal = [X=Y]
+        ;   (FromGoal = add(B,C,A) ->
+                % pour ne pas boucler
+                (Y,Cste) \== (B,C),
+                (Y,Cste) \== (C,B)
+            ;   true),
+            Goal = [no_lin_add(Y,Cste,X)])
+    ;   (FromGoal = mult(B,C,A) ->
+            % pour ne pas boucler
+            (K,Y) \== (B,C),
+            (Y,K) \== (B,C)
+        ;   true),
+        (Cste == 0 ->
+            Goal = [no_lin_mult(K,Y,X)]
+        ;   (FromGoal == add(B,C,A) ->
+                % pour ne pas boucler
+                (Cste,X) \== (B,A),
+                (Cste,X) \== (C,A)
+            ;   true),
+            Goal = [no_lin_mult(K,Y,P),no_lin_add(P,Cste,X)])),
+    !.
 get_affine_def_from_lin_expr(_,_,_,_,_,[]).
 
 
 %%check_and_call_goals(_) :- !.
 check_and_call_goals([]) :- !.
 check_and_call_goals(Goals) :-
-	call_priority(check_and_call_goals0(Goals),2).
+    call_priority(check_and_call_goals0(Goals),2).
 
 check_and_call_goals0([]).
 check_and_call_goals0([Goal|Goals]) :-
-	check_and_call(Goal),
-	check_and_call_goals0(Goals).
+    check_and_call(Goal),
+    check_and_call_goals0(Goals).
 
 check_and_call(X=Y) :- !,
-	protected_unify(X = Y).
+    protected_unify(X = Y).
 check_and_call(protected_unify(X=Y)) :- !,
-	protected_unify(X = Y).
+    protected_unify(X = Y).
 check_and_call(insert_dep_inst(A)) :- !,
     insert_dep_inst(A).
 check_and_call(add(A,B,C)) :- !,
-	((once (var(A),
-	   suspensions(A,LSusp);
-	   var(B),
-	   suspensions(B,LSusp)),
-	  member(Susp,LSusp),
-	  get_suspension_data(Susp,goal,add_int(X,_,Y,_,Z,_)),
-	  (match_bin_op(all,A,B,C,X,Y,Z,U1,U2);
-	   match_add_with_op_number(add_int,A,B,C,X,Y,Z,U1,U2);
-	   %% On essaye le match de minus(A,B,C)
-	   match_minus(add_int,A,B,C,X,Y,Z,U1,U2)))
-	->
-		protected_unify(U1 = U2)
-	;	add(A,B,C)).
+    ((once (var(A),
+            suspensions(A,LSusp);
+            var(B),
+            suspensions(B,LSusp)),
+      member(Susp,LSusp),
+      get_suspension_data(Susp,goal,add_int(X,_,Y,_,Z,_)),
+      (match_bin_op(all,A,B,C,X,Y,Z,U1,U2);
+       match_add_with_op_number(add_int,A,B,C,X,Y,Z,U1,U2);
+       % On essaye le match de minus(A,B,C)
+       match_minus(add_int,A,B,C,X,Y,Z,U1,U2)))
+    ->
+        protected_unify(U1 = U2)
+    ;   add(A,B,C)).
 	
 check_and_call(no_lin_add(A,B,C)) :- !,
-	((once (var(A),
-	   suspensions(A,LSusp);
-	   var(B),
-	   suspensions(B,LSusp)),
-	  member(Susp,LSusp),
-	  get_suspension_data(Susp,goal,add_int(X,_,Y,_,Z,_)),
-	  (match_bin_op(all,A,B,C,X,Y,Z,U1,U2);
-	   match_add_with_op_number(add_int,A,B,C,X,Y,Z,U1,U2);
-	   %% On essaye le match de minus(A,B,C)
-	   match_minus(add_int,A,B,C,X,Y,Z,U1,U2)))
-	->
-		protected_unify(U1 = U2)
-	;	no_lin_add(A,B,C)).
+    ((once (var(A),
+            suspensions(A,LSusp);
+            var(B),
+            suspensions(B,LSusp)),
+      member(Susp,LSusp),
+      get_suspension_data(Susp,goal,add_int(X,_,Y,_,Z,_)),
+      (match_bin_op(all,A,B,C,X,Y,Z,U1,U2);
+       match_add_with_op_number(add_int,A,B,C,X,Y,Z,U1,U2);
+       % On essaye le match de minus(A,B,C)
+       match_minus(add_int,A,B,C,X,Y,Z,U1,U2)))
+    ->
+        protected_unify(U1 = U2)
+    ;   no_lin_add(A,B,C)).
 
 check_and_call(mult(A,B,C)) :- !,
-	((once (var(A),
-	   suspensions(A,LSusp);
-	   var(B),
-	   suspensions(B,LSusp)),
-	  member(Susp,LSusp),
-	  get_suspension_data(Susp,goal,mult_int(X,_,Y,_,Z,_)),
-	  (X == A ->
-		Y == B
-	  ; X == B,
-	  	Y == A))
-	->
-		protected_unify(C = Z)
-	;	mult(A,B,C)).
+    ((once (var(A),
+            suspensions(A,LSusp);
+            var(B),
+            suspensions(B,LSusp)),
+      member(Susp,LSusp),
+      get_suspension_data(Susp,goal,mult_int(X,_,Y,_,Z,_)),
+      (X == A ->
+          Y == B
+      ;   X == B,
+          Y == A))
+    ->
+        protected_unify(C = Z)
+    ;   mult(A,B,C)).
 
 check_and_call(no_lin_mult(A,B,C)) :- !,
-	((once (var(A),
-	   suspensions(A,LSusp);
-	   var(B),
-	   suspensions(B,LSusp)),
-	  member(Susp,LSusp),
-	  get_suspension_data(Susp,goal,mult_int(X,_,Y,_,Z,_)),
-	  (X == A ->
-		Y == B
-	  ; X == B,
-	  	Y == A))
-	->
-		protected_unify(C = Z)
-	;	no_lin_mult(A,B,C)).
+    ((once (var(A),
+            suspensions(A,LSusp);
+            var(B),
+            suspensions(B,LSusp)),
+      member(Susp,LSusp),
+      get_suspension_data(Susp,goal,mult_int(X,_,Y,_,Z,_)),
+      (X == A ->
+          Y == B
+      ;   X == B,
+          Y == A))
+    ->
+        protected_unify(C = Z)
+    ;   no_lin_mult(A,B,C)).
 
 check_and_call(launch_diff_int(A,B)) :- !,
-	((once (var(A),
-	   suspensions(A,LSusp);
-	   var(B),
-	   suspensions(B,LSusp)),
-	  member(Susp,LSusp),
-	  get_suspension_data(Susp,goal,Goal),
-	  (Goal = diff_int(X,Y);Goal = gt(X,Y)),
-	  (X == A ->
-		Y == B
-	  ; X == B,
-	  	Y == A))
-	->
-		true
-	;	launch_diff_int(A,B)).
+    ((once (var(A),
+            suspensions(A,LSusp);
+            var(B),
+            suspensions(B,LSusp)),
+      member(Susp,LSusp),
+      get_suspension_data(Susp,goal,Goal),
+      (Goal = diff_int(X,Y);Goal = gt(X,Y)),
+      (X == A ->
+          Y == B
+      ;   X == B,
+          Y == A))
+    ->
+        true
+    ;   launch_diff_int(A,B)).
 
 check_and_call(Goal) :-
     (getval(gdbg,1)@eclipse ->
diff --git a/Src/COLIBRI/col_solve.pl b/Src/COLIBRI/col_solve.pl
index 34253eaa2af94c04b36611b31582da958ad6beee..2cf9d66f177eeb115c28d4ef23e34ab6018cc96e 100644
--- a/Src/COLIBRI/col_solve.pl
+++ b/Src/COLIBRI/col_solve.pl
@@ -63,10 +63,6 @@
 :- no_3B.
 :- setval(solve,1).
 :- setval(time_limit,0).
-:- setval(exit_at_end,1).
-
-col_exit(Code) :-
-    (getval(exit_at_end, 1) -> exit(Code) ; true).
 
 no_solve :-
     setval(solve,0).
@@ -106,7 +102,7 @@ interactive_solve :-
     write(output,[colibri]:""),
     block(read(input,Goal),
           Tag,
-          (writeln(error,col_exit(Tag)),
+          (writeln(error,exit(Tag)),
            fail)),
     ((Goal == halt;
       Goal == end_of_file)
@@ -175,7 +171,7 @@ interactive_solve :-
               ;   nl(output),
                   writeln(output,'UNSAT')),
               Tag,
-              writeln(error,col_exit(Tag))),
+              writeln(error,exit(Tag))),
         fail).
 
 get_goals([],_,[]).
@@ -252,7 +248,7 @@ trivial_goal_elim([Goal|Goals],NewGoals) :-
 
 solve(FILE) :-
     solve(_,FILE,0,Code),
-    col_exit(Code).
+    exit(Code).
 
 solve(Test,FILE,TO,Code) :-
     setval(solve,1),
@@ -478,7 +474,7 @@ smt_solve_count_steps(FILE,TO) :-
               setval(use_simplex,US)@eclipse,
               fail),
           Tag,
-          (writeln(output,col_exit(Tag)),
+          (writeln(output,exit(Tag)),
            setval(use_delta,UD)@eclipse,
            setval(use_simplex,US)@eclipse,
            exit_block(Tag))),
@@ -502,7 +498,7 @@ smt_comp_solve(FILE) :-
     % on desactive les warning de dolmen
     setval(no_dolmen_warning,1)@eclipse,
     smt_solve(_,FILE,0,Code),
-    col_exit(Code).
+    exit(Code).
 
 simplex_alway :-
     setval(simplex_delay_deactivation,0)@eclipse.
@@ -527,7 +523,7 @@ smt_solve(FILE) :-
         Test = 1
     ;   true),
     smt_solve(Test,FILE,0,Code),
-    col_exit(Code).
+    exit(Code).
 
 smt_solve_get_stat(FILE) :-
     seed(0),
@@ -545,7 +541,7 @@ smt_solve_get_stat(FILE) :-
     smt_solve(Test,FILE,0,Code),
     getval(nb_steps,Steps)@eclipse,
     writeln(output,"Steps":Steps),
-    col_exit(Code).
+    exit(Code).
 
 smt_solve(Test,FILE,TO,Code) :-
     no_3B,
@@ -578,6 +574,8 @@ smt_solve_bis0(Test,FILE,Code) :-
     min_max_lazy(int,MinInt,MaxInt,_),
     setval(refutation_chk,0)@eclipse,
     setval(logic,"ALL")@eclipse,
+    % par default on n'éssaye pas de réduire les sous intervalles
+    no_reduce_sub_intervals,
     % les deltas sont utiles pour les tableaux
     % positionné par smt_interp0, lu dans solve.pl
     setval(keep_deltas_if_arrays_or_reals,0)@eclipse,
@@ -633,16 +631,19 @@ smt_solve_bis0(Test,FILE,Code) :-
               ->
                   getval(diag_code,(Diag,Code))
               ;   % echec a la propagation
-                  getval(smt_status,Status)@eclipse,
-                  (Status == sat ->
-                      Code = 2,
-                      Diag = unknown,
+                  (getval(unknown_if_unsat,1)@eclipse ->
                       writeln(output,unknown),
-                      writeln(error,"wrong unsat")
-                  ;   Code = 0,
-                      Diag = unsat,
-                      writeln(output,unsat)),
-                  setval(diag_code,(Diag,Code))),
+                      setval(diag_code,(unknown,2))
+                  ;   getval(smt_status,Status)@eclipse,
+                      (Status == sat ->
+                          Code = 2,
+                          Diag = unknown,
+                          writeln(output,unknown),
+                          writeln(error,"wrong unsat")
+                      ;   Code = 0,
+                          Diag = unsat,
+                          writeln(output,unsat)),
+                      setval(diag_code,(Diag,Code)))),
               Tag,
               (update_min_max_lazy_int(MinInt,MaxInt),
                (Tag == timeout_col ->
@@ -698,8 +699,21 @@ get_type_decl_list(Goals,Decl,EndGoals) :-
     ->
         Decl = [D|EDecl],
         get_type_decl_list(NGoals,EDecl,EndGoals)
-    ;   Decl = [],
-        EndGoals = Goals).
+    ;   findall(Path,cgiveInstancePath(new_quantified_var(_,_),Goals,
+                                      Path),Paths),
+        EndGoals = Goals,
+        (Paths == [] ->
+            Decl = []
+        ;   (foreach(P,Paths),
+             foreach(D,Decl),
+             param(Goals) do
+                subscript(Goals,P,NQV),
+                NQV = new_quantified_var(V,T),
+                % call(spy_here)@eclipse,
+                protected_set_var_name(V,"ColQuantV"),
+                (real_type(T,_) ->
+                    D = real_vars(T,V)
+                ;   D = int_vars(T,V))))).
 
 is_decl(int_vars(_,_)) ?- !.
 is_decl(bool_vars(_,_)) ?- !.
@@ -762,7 +776,10 @@ clean_and_save_goal_before_check_sat(Goal,NewGoal) :-
     (NLGoal0 == LEndNewGoal ->
         % pas de check_sat ????
         append(NLDecl,[check_sat|CleanLGoal],NewGoals)
-    ;   append(CleanLGoal,[check_sat|LEndNewGoal],ENewGoals),
+    ;   list_to_conj(CleanLGoal,CleanGoal),
+        CNewGoal =.. [call_priority,CleanGoal,2],
+        % CNewGoal =.. [call_priority,CleanGoal,12],
+        append([CNewGoal],[check_sat|LEndNewGoal],ENewGoals),
         append(NLDecl,ENewGoals,NewGoals)
     ),
     list_to_conj(NewGoals,NewGoal).
@@ -787,8 +804,10 @@ remove_unused_decl_goal([D|LD],NLD,LG,NLG) ?- !,
     ((is_decl(D),
       term_variables(D,[V]),
       member_begin_end(G,LG,NewLG,ELG,ELG),
-      G =.. [FG,A,B],
-      occurs(FG,($=,#=)),
+      once member(G,[A $= B,
+                     A #= B,
+                     array_def(A,_),
+                     array_elt_def(_,A,B)]),
       remove_all_as(A,NA),
       once (NA == V;
             remove_all_as(B,NB),
@@ -796,7 +815,7 @@ remove_unused_decl_goal([D|LD],NLD,LG,NLG) ?- !,
       not occurs(V,NewLG))
     ->
         % D inutile
-        call(spy_here)@eclipse,
+        % call(spy_here)@eclipse,
         remove_unused_decl_goal(LD,NLD,NewLG,NLG)
     ;   NLD = [D|ENLD],
         remove_unused_decl_goal(LD,ENLD,LG,NLG)).
@@ -855,7 +874,7 @@ incNbCode(6) :-
 smt_solve_test(FILE,TO) :-
     seed(0),
     smt_solve_test_bis(FILE,TO,Code),
-    col_exit(Code).
+    exit(Code).
 
 smt_solve_test_bis(FILE,TO,Code) :-
     %set_threshold(1e-3),
@@ -900,7 +919,7 @@ smt_test(TO,Size,CI) :-
     %StrDir = "./colibri_tests/colibri/tests/",
     %StrDir = "./colibri_tests/colibri/tests/sat/", 
     % 0 en 20s (sans real/float->int!)
-    StrDir = "./colibri_tests/colibri/tests/unsat/", %0
+    %StrDir = "./colibri_tests/colibri/tests/unsat/", %0
     %StrDir = "./colibri_tests/colibri/tests/unknown/",
     %StrDir = "./colibri_tests/colibri/tests/timeout/",
 
@@ -979,7 +998,7 @@ smt_test(TO,Size,CI) :-
     %StrDir = "./smtlib_schanda-master/random/fp.leq/",
     %StrDir = "./smtlib_schanda-master/random/fp.lt/",
     %StrDir = "./smtlib_schanda-master/random/fp.from.ubv/",
-    %StrDir = "./smtlib_schanda-master/random/fp.from.sbv/",
+    %StrDir = "./smtlib_schanda-master/randorm/fp.from.sbv/",
     % declare-datatypes ????
 %StrDir = "./smtlib_schanda-master/spark_2014/",
     %StrDir = "./smtlib_schanda-master/wintersteiger/",
@@ -1072,9 +1091,9 @@ smt_test(TO,Size,CI) :-
 %----------------------------------------------------------------    
     %StrDir = "./QF_FP/20170501-Heizmann-UltimateAutomizer/", % 0/2
     %StrDir = "./QF_FP/20190429-UltimateAutomizerSvcomp2019/",% 0/24 (bitwuzla 0)
-    %StrDir = "./QF_FP/griggio/fmcad12/", % 50/214 (min_solve, sans lin_solve ni ls_reduce..)(39)
+    %StrDir = "./QF_FP/griggio/fmcad12/", % 46/214 (min_solve, sans lin_solve ni ls_reduce..)(39)
     %(cvc4/5 89/88)(bitwuzla 74) LES DD DEMARRENT TROP VITE ?
-    %StrDir = "./QF_FP/schanda/spark/", % 6! (min_solve avec X =< (X+Y)/2 =< Y) (cvc5 6)(bitwuzla 3)
+    %StrDir = "./QF_FP/schanda/spark/", % 5! (min_solve avec X =< (X+Y)/2 =< Y) (cvc5 6)(bitwuzla 3)
     %StrDir = "./QF_FP/wintersteiger/", % tout OK
 %-----------------------------------------------------------------------    
     %StrDir = "./QF_UFFP/schanda/",% 0
@@ -1158,6 +1177,43 @@ smt_test(TO,Size,CI) :-
     %StrDir = "QF_ANIA/",% 0/1 (7 I)
     
     %StrDir = "QF_ABV/bmc-arrays/", % 11/20 (19 I)
+
+    StrDir = "./FP/", % 1864 benchs
+    % cvc5 499 TO, bitwuzla 404 TO, colibri 227 TO
+    %StrDir = "./FP/20170501-Heizmann-UltimateAutomizer/", % 1 bench
+    % cvc5 1 TO, bitwuzla 0 TO, colibri 0 TO
+    %StrDir = "./FP/20190429-UltimateAutomizerSvcomp2019/",
+    % cvc5 0 TO, bitwuzla 0 TO, colibri 0 TO
+    %StrDir = "./FP/2019-Preiner/", % 1610 benchs
+    % cvc5 441 TO,bitwuzla 318 TO, colibri 157 TO !!!
+    %StrDir = "./FP/20200911-Pine/", % 245 benchs
+    % cvc5 232 TO,bitwuzla 232 TO, colibri 76 TO !!!
+    
+    %StrDir = "./BVFP/", % 208 benchs; 24s
+    % cvc5 34+? TO + 12 U, bitwuzla 18 TO, colibri 32 TO
+    %StrDir = "./BVFP/20190429-UltimateAutomizerSvcomp2019/", % 200 benchs,
+    % cvc5 26 TO + 12 U, bitwuzla 17 TO, colibri 32 TO
+    %StrDir = "./BVFP/20230321-UltimateAutomizerSvcomp2023/", % 3 benchs,
+    % cvc5 3 TO, bitwuzla 1 TO, colibri 0 TO !!!
+    %StrDir = "./BVFP/20210301-Alive2/", % 5 benchs,
+    % cvc5 5 TO, bitwuzla 5 TO, colibri 3 TO !!!(satus unknown ?)
+    
+    %StrDir = "./FPLRA/", % 41 benchs, 24 s
+    % cvc5 18 TO, bitwuzla 4 TO, colibri 0 TO
+    %StrDir = "./FPLRA/20170501-Heizmann-UltimateAutomizer/", % 14 benchs
+    % cvc5 7 TO, bitwuzla 4 TO, colibri 0 TO
+    %StrDir = "./FPLRA/20190429-UltimateAutomizerSvcomp2019/", % 27 benchs
+    % cvc5 11 TO + 1 U, bitwuzla 0 TO, colibri 0 TO
+    
+    %StrDir = "./BVFPLRA/", % 266 benchs, 24s
+    % cvc5 99 TO, bitwuzla 8 TO, colibri 8 TO
+    %StrDir = "./BVFPLRA/20170501-Heizmann-UltimateAutomizer/", % 70 benchs
+    % cvc5 35 TO, bitwuzla 0 TO, colibri 0 TO
+    %StrDir = "./BVFPLRA/20230321-UltimateAutomizerSvcomp2023/", % 11 benchs
+    % cvc5 11 TO, bitwuzla 0 TO, colibri 0 TO
+    %StrDir = "./BVFPLRA/20190429-UltimateAutomizerSvcomp2019/", % 185 benchs
+    % cvc5 55 TO, bitwuzla 10 TO, colibri 8 TO
+    
     smt_test0(TO,Size,StrDir,CI).
 
 :- lib(timeout).
@@ -1249,12 +1305,11 @@ smt_test0(TO,Size,StrDir0,CI) :-
               concat_string(["timeout --signal=KILL --kill-after=0.1 ",TO,"s ",ECLIPSE," -b ",COL," -g ",SizeM," -e \"seed(0),use_delta,use_simplex,setval(def_real_for_int,1)@colibri,setval(step_limit,0),setval(no_dolmen_warning,1)@eclipse,setval(show_steps,1),",UDS,USS,"smt_solve_get_stat(\'",F,"\')\""],Com)
           ;   concat_string(["timeout --signal=KILL --kill-after=0.1 ",TO,"s ",ECLIPSE," -b ",COL," -g ",SizeM," -e \"seed(0),use_delta,use_simplex,setval(def_real_for_int,1)@colibri,setval(step_limit,0),setval(no_dolmen_warning,1)@eclipse,setval(show_steps,1),",UDS,USS,"setval(scrambler,1)@eclipse,smt_solve_get_stat(\'",F,"\')\""],Com))),
 */
-      ;   concat_string(["timeout --signal=KILL --kill-after=0.1 ",TO,"s ",ECLIPSE," -b ",COL," -g ",SizeM," -e \"seed(0),smt_comp_solve(\'",F,"\')\""],Com)),
-
-%;          concat_string(["timeout --signal=KILL --kill-after=0.1 ",TO,"s cvc5 ",F],Com)),
-%;          concat_string(["timeout --signal=KILL --kill-after=0.1 ",TO,"s ncvc4 --fp-exp ",F],Com)),
-%;          concat_string(["timeout --signal=KILL --kill-after=0.1 ",TO,"s z3 ",F],Com)),
-%;          concat_string(["timeout --signal=KILL --kill-after=0.1 ",TO,"s bitwuzla ",F],Com)),
+%;         concat_string(["timeout --signal=KILL --kill-after=0.1 ",TO,"s ",ECLIPSE," -b ",COL," -g ",SizeM," -e \"seed(0),smt_comp_solve(\'",F,"\')\""],Com)),
+% 9 !!
+;          concat_string(["timeout --signal=KILL --kill-after=0.1 ",TO,"s z3 ",F],Com)), % trop long
+%;          concat_string(["timeout --signal=KILL --kill-after=0.1 ",TO,"s cvc5 ",F],Com)), % 53
+%;          concat_string(["timeout --signal=KILL --kill-after=0.1 ",TO,"s bitwuzla ",F],Com)),% 84
       exec(Com,[],Pid),
       wait(Pid,CodeExt),
       writeln(code:CodeExt),
@@ -1397,18 +1452,65 @@ smt_unit_test_CI(TO) :-
     smt_unit_test(TO,1).
 
 smt_unit_test(TO,CI) :-
+    %StrDir = "UnitTests/sat/FP/",
+    %StrDir = "UnitTests/unsat/FP/", 
+    %StrDir = "./FP/", % 1864 benchs, 24s
+    % cvc5 499 TO, bitwuzla 404 TO, colibri 227 TO
+    %StrDir = "./FP/20170501-Heizmann-UltimateAutomizer/", % 1 bench
+    % cvc5 1 TO, bitwuzla 0 TO, colibri 0 TO
+    %StrDir = "./FP/20190429-UltimateAutomizerSvcomp2019/",
+    % cvc5 0 TO, bitwuzla 0 TO, colibri 0 TO
+    %StrDir = "./FP/2019-Preiner/", % 1610 benchs
+    % cvc5 441 TO,bitwuzla 318 TO, colibri 157 TO !!!
+    %StrDir = "./FP/20200911-Pine/", % 245 benchs
+    % cvc5 232 TO,bitwuzla 232 TO, colibri 76 TO !!!
+    
+    %StrDir = "./BVFP/", % 208 benchs; 24s
+    % cvc5 34+? TO + 12 U, bitwuzla 18 TO, colibri 32 TO
+    %StrDir = "./BVFP/20190429-UltimateAutomizerSvcomp2019/", % 200 benchs,
+    % cvc5 26 TO + 12 U, bitwuzla 17 TO, colibri 32 TO
+    %StrDir = "./BVFP/20230321-UltimateAutomizerSvcomp2023/", % 3 benchs,
+    % cvc5 3 TO, bitwuzla 1 TO, colibri 0 TO !!!
+    %StrDir = "./BVFP/20210301-Alive2/", % 5 benchs,
+    % cvc5 5 TO, bitwuzla 5 TO, colibri 3 TO !!!(satus unknown ?)
+    
+    %StrDir = "./FPLRA/", % 41 benchs, 24 s
+    % cvc5 18 TO, bitwuzla 4 TO, colibri 0 TO
+    %StrDir = "./FPLRA/20170501-Heizmann-UltimateAutomizer/", % 14 benchs
+    % cvc5 7 TO, bitwuzla 4 TO, colibri 0 TO
+    %StrDir = "./FPLRA/20190429-UltimateAutomizerSvcomp2019/", % 27 benchs
+    % cvc5 11 TO + 1 U, bitwuzla 0 TO, colibri 0 TO
+    
+    %StrDir = "./BVFPLRA/", % 266 benchs, 24s
+    % cvc5 99 TO, bitwuzla 8 TO, colibri 8 TO
+    %StrDir = "./BVFPLRA/20170501-Heizmann-UltimateAutomizer/", % 70 benchs
+    % cvc5 35 TO, bitwuzla 0 TO, colibri 0 TO
+    %StrDir = "./BVFPLRA/20230321-UltimateAutomizerSvcomp2023/", % 11 benchs
+    % cvc5 11 TO, bitwuzla 0 TO, colibri 0 TO
+    %StrDir = "./BVFPLRA/20190429-UltimateAutomizerSvcomp2019/", % 185 benchs
+    % cvc5 55 TO, bitwuzla 10 TO, colibri 8 TO
+    
     %StrDir = "./UnitTests/sat/",
     %StrDir = "./UnitTests/unsat/",
+
+    %StrDir = "./FP/20170501-Heizmann-UltimateAutomizer/",
+    %StrDir = "./FP/20190429-UltimateAutomizerSvcomp2019/",
+    %StrDir = "./FP/2019-Preiner/",
+    %StrDir = "./FP/20200911-Pine/",
+    
     %StrDir = "./UnitTests/unsat/QF_ABV/",
     %StrDir = "./UnitTests/sat/QF_ABV/",
     
     %StrDir = "./UnitTests/sat/QF_ABV/",
     %StrDir = "./UnitTests/sat/QF_BV/",
     %StrDir = "./UnitTests/sat/QF_NIA/",
+    %StrDir = "./UnitTests/sat/QF_FP/",
+    %StrDir = "./UnitTests/sat/QF_NIA/",
+    %StrDir = "./UnitTests/unsat/QF_FP/",
     
     %StrDir = "./colibri_tests/colibri/tests/sat/", % 0 (en 15s, 1 en
                                                    % 2s newton)
-    StrDir = "./colibri_tests/colibri/tests/unsat/", % 0
+    %StrDir = "./colibri_tests/colibri/tests/unsat/", % 0
     
 
     %StrDir = "./smtlib_schanda-master/random/", % tout OK ou unsupported
@@ -1420,19 +1522,19 @@ smt_unit_test(TO,CI) :-
     %StrDir = "./smtlib_schanda-master/spark_2014/",
 
 %-----------------------------------------------------------------------    
-    %StrDir = "./QF_AUFBVFP/20210301-Alive2/",% 1/1
+    StrDir = "./QF_AUFBVFP/20210301-Alive2/",% 1/1
 %------------------------------------------------------------------------
-    %StrDir = "./QF_ABVFPLRA/", % 1/74
-    %StrDir = "./QF_ABVFPLRA/20190429-UltimateAutomizerSvcomp2019/",% 0/41
-    %StrDir = "./QF_ABVFPLRA/20170501-Heizmann-UltimateAutomizer/",% 1/33
+    %StrDir = "./QF_ABVFPLRA/", % 1/74 (4 en 5s)
+    %StrDir = "./QF_ABVFPLRA/20190429-UltimateAutomizerSvcomp2019/",% 1/41
+    %StrDir = "./QF_ABVFPLRA/20170501-Heizmann-UltimateAutomizer/",% 0/33
 %------------------------------------------------------------------------
     %StrDir = "./QF_ABVFP/",
-    %StrDir = "./QF_ABVFP/20170428-Liew-KLEE/", % 113/18033 TO (1 I,
-    % 177 u) (69 sans simplex) (cvc4 76)
-    %StrDir = "./QF_ABVFP/20170501-Heizmann-UltimateAutomizer/", % 1/96 TO
+    %StrDir = "./QF_ABVFP/20170428-Liew-KLEE/", % 106 !! 113/18033 TO (1 I,
+    % 177 u) (167 en 5s) (69 sans simplex) (cvc4 76)
+    %StrDir = "./QF_ABVFP/20170501-Heizmann-UltimateAutomizer/", % 0/96 TO
 %------------------------------------------------------------------------
     %StrDir = "./QF_BVFP/",
-    %StrDir = "./QF_BVFP/20170428-Liew-KLEE/", % 46/17156 (89 u)
+    %StrDir = "./QF_BVFP/20170428-Liew-KLEE/", % 0/17156 (89 u)(124 en 5s)
     %StrDir = "./QF_BVFP/20170501-Heizmann-UltimateAutomizer/", % 0/4 TO
     %StrDir = "./QF_BVFP/ramalho/", % 0/32 TO
     %StrDir = "./QF_BVFP/schanda/spark/", % 1/8 TO
@@ -1443,11 +1545,11 @@ smt_unit_test(TO,CI) :-
     %StrDir = "./QF_FPLRA/20170501-Heizmann-UltimateAutomizer/",% 0/4 TO
     %StrDir = "./QF_FPLRA/20190429-UltimateAutomizerSvcomp2019/",% 0/38 TO
     %StrDir = "./QF_FPLRA/schanda/spark/",% 0/2 TO
-    %StrDir = "./QF_FPLRA/2019-Gudemann/",% 2/13 (3/13 en 2s)
+    %StrDir = "./QF_FPLRA/2019-Gudemann/",% 1/13 (3/13 en 2s)
 %------------------------------------------------------------------------
     %StrDir = "./QF_BVFPLRA/",
     %StrDir = "./QF_BVFPLRA/20170501-Heizmann-UltimateAutomizer/",% 0/15 TO
-    %StrDir = "./QF_BVFPLRA/20190429-UltimateAutomizerSvcomp2019/",% 10(9)/152 (11 u) (12/152 en 2s)
+    %StrDir = "./QF_BVFPLRA/20190429-UltimateAutomizerSvcomp2019/",% 0/152 (11 u) (12/152 en 2s)
     %StrDir = "./QF_BVFPLRA/2019-Gudemann/",% 0/1 TO
 %------------------------------------------------------------------------
     %StrDir = "./QF_FP/20170501-Heizmann-UltimateAutomizer/", % 0/2 TO
@@ -1455,7 +1557,7 @@ smt_unit_test(TO,CI) :-
     %StrDir = "./QF_FP/20230321-UltimateAutomizerSvcomp2023/", % 0/1
     %StrDir = "./QF_FP/20210211-Vector/", % 0/91
     %StrDir = "./QF_FP/ramalho/",% 0/38 T0 (5/38 en 2s)
-    %StrDir = "./QF_FP/griggio/fmcad12/", % 45/214 TO en 24s (cvc4 90 en 60s) (65/214 en 2s)
+    %StrDir = "./QF_FP/griggio/fmcad12/", % 46! 45/214 TO en 24s (cvc4 90 en 60s) (65/214 en 2s)
     %StrDir = "./QF_FP/schanda/spark/",% 5/46 TO (7 en 2s)
     %StrDir = "./QF_FP/wintersteiger/", % 0/39994
 %-----------------------------------------------------------------------    
@@ -1730,10 +1832,10 @@ smt_unit_test(StrDir0,TO,CI) :-
           ->
               % on est en mode check avec scrambler
               writeln(output,bug:F),
-              col_exit(4)
+              exit(4)
           ;   true),
           getval(bug,Bugs),
-          (Status == unknown ->
+          (fail,Status == unknown ->
               setval(bug,[smt_unknown:F|Bugs])
           ;   setval(bug,[F|Bugs]))
       ;   pathname(F,PF,NF),
@@ -1771,7 +1873,7 @@ smt_unit_test(StrDir0,TO,CI) :-
       garbage_collect,
       fail
     ; true),
-    call(spy_here)@eclipse,
+    % call(spy_here)@eclipse,
     (getval(make_UT,1)@eclipse ->
         Slog = output
     ;   % on est en check
@@ -1842,20 +1944,25 @@ check_unit_tests(SatUnsat,TO,Mod) :-
 
 check_unit_tests(SatUnsat,TO) :-
     Sat = [
-            "./UnitTests/sat/ALL/",
+           "./UnitTests/sat/FP/",
+           "./UnitTests/sat/BVFP/",
+           "./UnitTests/sat/FPLRA/",
+           "./UnitTests/sat/BVFPLRA/",
+           "./UnitTests/sat/ALL/",
            "./UnitTests/sat/QF_ABVFPLRA/",
            "./UnitTests/sat/QF_AX/",
            "./UnitTests/sat/QF_BVFPLRA/",
 
-           "./UnitTests/sat/QF_LIA/"
+           "./UnitTests/sat/QF_LIA/",
 
            "./UnitTests/sat/QF_UF/",
            "./UnitTests/sat/QF_UFLRA/",
            "./UnitTests/sat/QF_ABV/",
-           "./UnitTests/sat/QF_ALIA/",
+%           "./UnitTests/sat/QF_ALIA/", VIDE (trop gros)
 
            "./UnitTests/sat/QF_BV/",
 
+           % TO sur square_neg_id_fp_sat.smt2
            "./UnitTests/sat/QF_FP/",
            "./UnitTests/sat/QF_LRA/",
            "./UnitTests/sat/QF_UFIDL/",
@@ -1864,27 +1971,26 @@ check_unit_tests(SatUnsat,TO) :-
            "./UnitTests/sat/QF_BVFP/",
            "./UnitTests/sat/QF_FPLRA/",
 
-           "./UnitTests/sat/QF_NIA/",
+            "./UnitTests/sat/QF_NIA/",
 
            "./UnitTests/sat/QF_UFLIA/"
           ],
     
     Unsat = 
           [
+           "./UnitTests/unsat/FP/",
+           "./UnitTests/unsat/BVFPLRA/",
              "./UnitTests/unsat/ALL/",
-
+             "./UnitTests/unsat/FP/",
              "./UnitTests/unsat/QF_ABV/",
-
              "./UnitTests/unsat/QF_ABVFP/",
              "./UnitTests/unsat/QF_ABVFPLRA/",
-              "./UnitTests/unsat/QF_ALIA/",
+             "./UnitTests/unsat/QF_ALIA/",
              "./UnitTests/unsat/QF_AUFBV/",
              "./UnitTests/unsat/AUFBVFPDTNIRA/",
              "./UnitTests/unsat/QF_AX/",
              "./UnitTests/unsat/QF_BV/",
- 
              "./UnitTests/unsat/QF_BVFP/",
-             
              "./UnitTests/unsat/QF_BVFPLRA/",
              "./UnitTests/unsat/QF_FP/",
              "./UnitTests/unsat/QF_FPLRA/",
@@ -1911,8 +2017,21 @@ check_unit_tests(SatUnsat,TO) :-
         COL = "col_solve.pl"),
     %Scr = 1,
     Scr = 0,
+    % Menage des trop gros
+    MaxSize = 10000,
     (foreach(Dir,Dirs),
-     param(TO,ECLIPSE,COL,Scr) do
+     param(MaxSize,TO,ECLIPSE,COL,Scr) do
+        read_directory(Dir, "*.smt2", _, SmtList),
+        (foreach(F,SmtList),
+         param(Dir,MaxSize) do
+            concat_string([Dir,"/",F],PF),
+            os_file_name(PF,OS_PF),
+            get_file_info(OS_PF,size,FSize),
+            (FSize > MaxSize ->
+                % Trop gros on le supprime
+                concat_string(["rm ",OS_PF],RmCom),
+                system(RmCom)
+            ;   true)),
         concat_string([ECLIPSE,
                        " -b ",COL," -g 5000M -e \"setval(make_UT,0)@eclipse,smt_unit_test('",
                        Dir,
@@ -1925,9 +2044,12 @@ check_unit_tests(SatUnsat,TO) :-
         % writeln(Com),
         exec(Com,[],Pid),
         wait(Pid,CodeExt),
-        (CodeExt =:= 4*256 ->
+        (fail,CodeExt =:= 4*256 ->
             halt
-        ;   true)).
+        ;   true),
+        getenv('PWD',Cwd),
+        concat_string(["cd ",Dir,"; git add *.smt2; cd ",Cwd],NCom),
+        system(NCom)).
 
 
 show_stats :- 
diff --git a/Src/COLIBRI/lp_arith.pl b/Src/COLIBRI/lp_arith.pl
index be8499ebd5dbd188a0220d6085add8f1cf1c5170..293df43b3e4aea2d153437da21b98a1bfcf6a21a 100755
--- a/Src/COLIBRI/lp_arith.pl
+++ b/Src/COLIBRI/lp_arith.pl
@@ -2548,7 +2548,10 @@ ocaml_sqrt_simple(Rnd,F,SqrtF) :-
 
 
 % round to nearest even integer (pour fp_rem)
-round_rat_integer(Rat,IRat) :-
+round_rat_integer(Rat0,IRat) :-
+    (number(Rat0) ->
+        make_OCamlRat(Rat0,Rat)
+    ;   Rat = Rat0),
     protect_interrupts_and_gc(p_simplex_ocaml_rat_round_integer_RNE(Rat,IRat)).
 
 get_OCamlRat_strings_from_cst(Int,SNum,SDen) :-
@@ -2627,7 +2630,10 @@ ocaml_round(rtn,dn) :- !.
 ocaml_round(rtp,up) :- !.
 ocaml_round(Rnd,Rnd).
 
-float_of_OCamlRat(Type,Rnd,Rat,Float) :-
+float_of_OCamlRat(Type,Rnd,Rat0,Float) :-
+    (number(Rat0) ->
+        make_OCamlRat(Rat0,Rat)
+    ;   Rat = Rat0),
     ocaml_round(Rnd,NRnd),
     float_of_OCamlRat0(Type,NRnd,Rat,Float0),
     protected_unify(Float0,Float).
diff --git a/Src/COLIBRI/mbv_propa.pl b/Src/COLIBRI/mbv_propa.pl
index 20025a966404de2509b474276541cfb89960f6e2..715e47611bb04b6fbb543d885b065bf4eb69b3ec 100644
--- a/Src/COLIBRI/mbv_propa.pl
+++ b/Src/COLIBRI/mbv_propa.pl
@@ -60,11 +60,12 @@ update_congr_interval_eq(X,Y):-
     fill_bvbounds(Y,DY).
 
 % EN TEST: ca marche !!!
-
+% FAUX
+/*
 launch_bveq(Sx,X,Sy,Y) :-
     !,
     protected_unify(X,Y).
-
+*/
 
 launch_bveq(S,X,S,Y) ?- !,
     protected_unify(X,Y).
@@ -152,12 +153,27 @@ bvand_bis(M,X,0,Z) ?- !,
     protected_unify(Z,0).
 bvand_bis(M,X,X,Z) ?- !,
     protected_unify(Z,X).
+% TEST
+/*
+bvand_bis(M,X,Y,Z) :-
+    (var(X);
+     var(Y)),
+    !,
+    my_suspend(bvand_bis(M,X,Y,Z),0,(X,Y)->suspend:inst).
+*/
 bvand_bis(M,X,Y,Z) :-
     integer(Z),
     Z is \(-1 << M), !,
     % Z tout a 1
     protected_unify(X,Z),
     protected_unify(Y,Z).
+bvand_bis(M,X,Y,Z) :-
+    is_ones_for_other(M,X,Y), !,
+    protected_unify(Z,Y).
+bvand_bis(M,X,Y,Z) :-
+    is_ones_for_other(M,Y,X), !,
+    protected_unify(Z,X).
+
 /*
 bvand_bis(M,X,Y,Z) :-
     % Should I add that test on the use_simplification?
@@ -179,12 +195,6 @@ quand on a A & B = 0 ou A | B = Mask, chercher l'autre, s'il existe, alors
 	les enlever tous les deux et mettre A = ¬ B
 */
 
-bvand_bis(M,X,Y,Z) :-
-    is_ones_for_other(M,X,Y), !,
-    protected_unify(Z,Y).
-bvand_bis(M,X,Y,Z) :-
-    is_ones_for_other(M,Y,X), !,
-    protected_unify(Z,X).
 bvand_bis(M,X,Y,Z) :-
     get_priority(Prio),
     set_priority(1),
@@ -213,7 +223,49 @@ bvand_bis(M,X,Y,Z) :-
             fill_bvbounds(Z,NDZ),
             bvand_inst_free(M,X,Y,Z,Continue1),
             (nonvar(Continue1) ->
-                my_suspend(bvand_bis(M,X,Y,Z), 0, (X,Y,Z) -> suspend:constrained)
+                (fail,((X == Z,
+                   A = Y,
+                   B = X);
+                  (Y == Z,
+                   A = X,
+                   B = Y))
+                ->
+                    % bvand(M,A,B,B)
+                    call(spy_here)@eclipse,
+                    Ones is 2^(M-1),
+                    (not_unify(A,Ones) ->
+                        my_suspend(bvand_bis(M,A,B,B), 0,
+                                   (A,B) -> suspend:constrained)
+/*
+                        (not_unify(A,B) ->
+                            my_suspend(bvand_bis(M,A,B,B), 0,
+                                       (A,B) -> suspend:constrained)
+                        ;   % on essaye de forcer A = B
+                            int_vars(bool,Bool),
+                            (as(A,uint(M)) #\= as(B,uint(M)))
+                            #= as(Bool,bool),
+                            (Bool == 0 ->
+                                true
+                            ;   my_suspend(bvand_bis(M,A,B,B), 0,
+                                           (A,B,Bool) -> suspend:constrained)))
+*/
+                    ;   % on essaye de forcer A = Ones
+                        get_cstr_suspensions(A,LSA),
+                        ((member(SA,LSA),
+                          get_suspension_data(SA,goal,
+                                              eq_int_reif_bis(_,Ones,AA,NotBool)),
+                          A == AA)
+                        ->
+                            Test = (NotBool == 1)
+                        ;   int_vars(bool,Bool),
+                            diff_int_reif(Ones,A,Bool),
+                            Test = (Bool == 0)),
+                        (call(Test) ->
+                            true
+                        ;   my_suspend(bvand_bis(M,A,B,B), 0,
+                                       (A,B,Bool) -> suspend:constrained)))
+                ;   my_suspend(bvand_bis(M,X,Y,Z), 0,
+                               (X,Y,Z) -> suspend:constrained))
             ;   true))),
     set_priority(Prio),
     wake_if_other_scheduled(Prio).
@@ -387,8 +439,19 @@ bvor_bis(M,X,0,Z) ?- !,
 bvor_bis(M,X,Y,0) ?- !,
     protected_unify(X,0),
     protected_unify(Y,0).
+bvor_bis(M,X,Y,Z) :-
+    nonvar(X),
+    nonvar(Y),!,
+    bvor_inst_free(M,X,Y,Z,_).
 
-
+% TEST
+/*
+bvor_bis(M,X,Y,Z) :-
+    (var(X);
+     var(Y)),
+    !,
+    my_suspend(bvor_bis(M,X,Y,Z),0,(X,Y)->suspend:inst).
+*/
 /*
 LABEL1
 
@@ -405,10 +468,6 @@ que c'est exactement l'inverse du OR, ça boucle.
 voir LABEL2
 
 */
-bvor_bis(M,X,Y,Z) :-
-    nonvar(X),
-    nonvar(Y),!,
-    bvor_inst_free(M,X,Y,Z,_).
 /*
 bvor_bis(M,X,Y,Z) :-
     % Should I add that test on the use_simplification?
@@ -458,7 +517,6 @@ bvor_bis(M,X,Y,Z) :-
     set_priority(1),
     save_cstr_suspensions((X,Y)),
     % union des congr si elles existent
-
     get_congr(X,CX,MX),
     get_congr(Y,CY,MY),
     union_congr(CX,CY,MX,MY,CZ,MZ,_),
@@ -487,7 +545,41 @@ bvor_bis(M,X,Y,Z) :-
             fill_bvbounds(Z,NDZ),
             bvor_inst_free(M,X,Y,Z,Continue1),
             (nonvar(Continue1) ->
-                my_suspend(bvor_bis(M,X,Y,Z), 0, (X,Y,Z) -> suspend:constrained)
+                (fail,((X == Z,
+                   A = Y,
+                   B = X);
+                  (Y == Z,
+                   A = X,
+                   B = Y))
+                ->
+                    % bvor(M,A,B,B)
+                    call(spy_here)@eclipse,
+                    (not_unify(A,0) ->
+                        my_suspend(bvor_bis(M,A,B,B), 0,
+                                   (A,B) -> suspend:constrained)
+/*
+                        (not_unify(A,B) ->
+                            my_suspend(bvor_bis(M,A,B,B), 0,
+                                       (A,B) -> suspend:constrained)
+                        ;   % on essaye de forcer A = B
+                            int_vars(bool,Bool),
+                            (as(A,uint(M)) #\= as(B,uint(M)))
+                            #= as(Bool,bool),
+                            (Bool == 0 ->
+                                true
+                            ;   my_suspend(bvor_bis(M,A,B,B), 0,
+                                           (A,B,Bool) -> suspend:constrained)))
+*/
+                    ;   % on essaye de forcer A = 0
+                        int_vars(bool,Bool),
+                        (as(A,uint(M)) #\= as(0,uint(M)))
+                        #= as(Bool,bool),
+                        (Bool == 0 ->
+                            true
+                        ;   my_suspend(bvor_bis(M,A,B,B), 0,
+                                       (A,B,Bool) -> suspend:constrained)))
+                ;   my_suspend(bvor_bis(M,X,Y,Z), 0,
+                               (X,Y,Z) -> suspend:constrained))
             ;   true))),
     set_priority(Prio),
     wake_if_other_scheduled(Prio).
@@ -1011,7 +1103,8 @@ bvsr_bis(M,0,Y,Z) ?- !,
     protected_unify(Z,0).
 bvsr_bis(M,X,Y,Z) :-
     mfd:dvar_range(X,_, Max),
-    Max < 2^ Y,!, % A simple bang point turns UNSAT to SAT!!
+    Max < 2^ Y,
+    !, % A simple bang point turns UNSAT to SAT!!
     protected_unify(Z,0).
 bvsr_bis(M,X,Y,Z) :-
     get_bvbounds(X, bvbounds(X1, X0)),
@@ -1027,7 +1120,7 @@ bvsr_bis(M,X,Y,Z) :-
     get_saved_cstr_suspensions(LSusp),
     filter_bvsr_susps(M,X,Y,Z,LSusp),
     (exists_congr(X,_,_) ->
-        call(spy_here)@eclipse,
+        %call(spy_here)@eclipse,
         DpY is 2^Y,
         congr_div_directe(int,X,DpY,Z)
     ;   true),
@@ -1145,9 +1238,10 @@ bvlsr(M, X, Y, Z) :-
 
 % =========== arithmetic right shift===========
 :- export bvasr/4.
-
+% INUTILE traité dans solve.pl
 bvasr(M,X,Y,Z) :-
-    var(Y), !,
+    var(Y),
+    !,
     my_suspend(bvasr(M,X,Y,Z), 0, [Y] -> suspend:inst).
 
 bvasr(M,X,0,Z) ?- !,
@@ -1161,25 +1255,14 @@ bvasr(M, X, Y, Z):-
     bvasr_bis(M, X, Y, Z).
 
 :- export bvasr_bis/4.
+
 %% Version correcte a optimiser
-/*
-bvasr_bis(M, X, Y, Z) :-
-    mfd:dvar_range(X,_,HX),
-    Mm1 is M - 1,
-    (HX < 2^Mm1 ->
-        % msb(X) = 0
-        bvsr(M, X, Y, Z)
-    ;   bvextract(M, Mm1, Y, X, XX),
-        MXX is M - Y,
-        sign_extend(MXX, Y, XX, Z)).
-*/
-bvasr_bis(M, X, Y, Z) :-
-    Mm1 is M - 1,
-    bvextract(M, Mm1, Y, X, XX),
-    insert_dep_inst(dep(XX,0,[Y,X])),
-    insert_dep_inst(dep(Z,0,[Y,XX])),
-    MXX is M - Y,
-    sign_extend(MXX, Y, XX, Z).
+bvasr_bis(Size, X, Shift, R) :- !,
+    Sm1 is Size - 1,
+    ite(extract(Size,Sm1,Sm1,X) #= as(0,uint(1)),
+        bvlshr(Size,X,Shift),
+        bvnot(Size,bvlshr(Size,bvnot(Size,X),Shift)))
+    #= R.
 
 % ================= Extract ==================
 :- export bvextract/5.
@@ -1188,15 +1271,7 @@ bvextract(SX,I,J,0,Y) ?-
     protected_unify(Y, 0).
 
 bvextract(SX,I,0,X,Y) ?-
-    integer(Y),
-    !,
-    Power is 2 ^ (I+1),
-    gardefou(Y < Power),
-    set_lazy_domain(bv,SX,X),
-    launch_congr(X, Y, Power).
-
-bvextract(SX,I,0,X,Y) ?-
-    SX is I + 1,
+    SX is I - 1,
     !,
     set_lazy_domain(bv,SX,X),
     protected_unify(X,Y).
@@ -1310,18 +1385,25 @@ bvconcat(SX,X,SY,Y,Z) :-
     %bvconcat_v1(SX,X,SY,Y,Z).
     bvconcat_v2(SX,X,SY,Y,Z).
 */
+
 % plus efficace !!!
+bvconcat(SX,0,SY,Y,Z) ?- !,
+    SZ is SX + SY,
+    launch_bveq(SY,Y,SZ,Z).
 bvconcat(SX,X,SY,Y,Z) :-
     SizeXY is SX + SY,
     set_lazy_domain(bv,SX,X),
     set_lazy_domain(bv,SY,Y),
     set_lazy_domain(bv,SizeXY,Z),
     N is 2^SY,
+    div_mod(Z,N,X,Y).
+/*
     insert_dep_inst(dep(NX,0,[X])),
     insert_dep_inst(dep(Z,0,[NX,Y])),
     mult(N,X,NX),
     add(NX,Y,Z).
-
+*/
+% FAUX
 bvconcat_v1(0, _, SY, Y, Z) ?-
     !, protected_unify(Z, Y).
 bvconcat_v1( SY, Y,0, _, Z) ?-
@@ -1832,27 +1914,45 @@ zero_extend(Sx,Extend,X,Y) :-
 % pour obtenir Y
 sign_extend(Sx, I, X, Y) :-
     var(I), !,
-    my_suspend(sign_extend(Sx, I, X, Y),0,[I] -> inst).
-sign_extend(_, 0, X, Y) ?-
-    !, protected_unify(X,Y).
-sign_extend(Sx, I, 0, Y) ?-
-    !, protected_unify(Y, 0).
-sign_extend(Sx, I, X, 0) ?-
-    !, protected_unify(X, 0).
+    my_suspend(sign_extend(Sx, I, X, Y),0,I->suspend:inst).
+
+sign_extend(_, 0, X, Y) ?- !,
+    protected_unify(X,Y).
+sign_extend(Sx, I, X, 0) ?- !,
+    protected_unify(X, 0).
+sign_extend(Sx, I, 0, Y) ?- !,
+    protected_unify(Y, 0).
 sign_extend(Sx, I, X, Y) :-
     integer(X),
     !,
-    (X < (2 ^ (Sx - 1)) ->
+    PF is Sx - 1,
+    bvextract(Sx,PF,PF,X,PFX),
+    (PFX == 0 ->
         % poid fort à 0
         protected_unify(X,Y)
     ;   % poid fort à 1
-        YY is X \/ (( \ (- 1 << I)) << Sx),
-        protected_unify(YY,Y)).
+        BegY is 2^I - 1,
+        bvconcat(I,BegY,Sx,X,Y)).
 sign_extend(Sx, I, X, Y) :-
-    integer(Y), !,
-    XX is Y /\ ( \ (- 1 << Sx)),
-    protected_unify(XX,X).
+    integer(Y),
+    !,
+    SxM1 is Sx-1,
+    Sy is Sx+I,
+    bvextract(Sy,SxM1,0,Y,X),
+    % Necessaire pour pouvoir échouer !
+    sign_extend(Sx,I,X,Y).
+
+sign_extend(Sx, I, X, Y) :- !,
+    PF is Sx - 1,
+    bvextract(Sx,PF,PF,X,PFX),
+    Sy is Sx + I,
+    MaxBegY is 2^I -1,
+    chk_nan(as(PFX,uint(1)) #= 1,
+            concat(I,as(MaxBegY,uint(I)),Sx,as(X,uint(Sx))),
+            zero_extend(Sx,I,as(X,uint(Sx))))
+    #= as(Y,uint(Sy)).
 
+% A supprimer !!
 sign_extend(SX, I, X, Y) :-
     SX == 1,
     !,
@@ -1865,61 +1965,83 @@ sign_extend(SX, I, X, Y) :-
     bvextract(SY, 2, 2, Y, X). % TODO : faster with 2, 2 instead of I, I? meh
 
 sign_extend(Sx, I, X, Y) :-
+    get_priority(P),
+    set_priority(1),
+    save_cstr_suspensions((X,Y)),
     Sx > 1,
     Sy is Sx + I,
     set_lazy_domain(bv, Sx, X),
     set_lazy_domain(bv, Sy, Y),
-    mfd:get_intervals(X,InterX),
-    (not (member(Vx,InterX),
-          Vx = _.._)
-    ->
-        % only_values_in_intervals(InterX)
-        (foreach(Vx,InterX),
-         foreach(Vy,InterY),
-         param(Sx,I) do
-            sign_extend(Sx,I,Vx,Vy)),
-        mfd:set_intervals(Y,InterY)
-    ;   true),
-    mfd:get_intervals(Y,NInterY),
-    (not (member(Vy,NInterY),
-          Vy = _.._)
-    ->
-        % only_values_in_intervals(NInterY)
-        (foreach(Vy,NInterY),
-         foreach(Vx,NInterX),
-         param(Sx,I) do
-            sign_extend(Sx,I,Vx,Vy)),
-        mfd:set_intervals(X,NInterX),
-        mfd:get_intervals(X,NNInterX),
-        (InterX \== NNInterX ->
-            % only_values_in_intervals(NNInterX)
-            (foreach(Vx,NNInterX),
-             foreach(Vy,NInterY),
+    get_saved_cstr_suspensions(LSusp),
+    (foreach((Susp,G),LSusp),
+     param(Fact) do
+        ((G = sign_extend(Sx, II, XX, YY),
+          II == I,
+          (XX == X;
+           YY == Y))
+        ->
+            Fact = 1,
+            protected_unify(X,XX),
+            protected_unify(Y,YY)
+        ;   true)),
+    (var(Fact) ->
+        my_suspend(sign_extend(Sx, I, X, Y),0,(X,Y)->suspend:inst)
+/*
+        mfd:get_intervals(X,InterX),
+        (not (member(Vx,InterX),
+              Vx = _.._)
+        ->
+            % only_values_in_intervals(InterX)
+            (foreach(Vx,InterX),
+             foreach(Vy,InterY),
              param(Sx,I) do
                 sign_extend(Sx,I,Vx,Vy)),
-            mfd:set_intervals(Y,NInterY)
-        ;   true)
+            mfd:set_intervals(Y,InterY)
+        ;   true),
+        mfd:get_intervals(Y,NInterY),
+        (not (member(Vy,NInterY),
+              Vy = _.._)
+        ->
+            % only_values_in_intervals(NInterY)
+            (foreach(Vy,NInterY),
+             foreach(Vx,NInterX),
+             param(Sx,I) do
+                sign_extend(Sx,I,Vx,Vy)),
+            mfd:set_intervals(X,NInterX),
+            mfd:get_intervals(X,NNInterX),
+            (InterX \== NNInterX ->
+                % only_values_in_intervals(NNInterX)
+                (foreach(Vx,NNInterX),
+                 foreach(Vy,NInterY),
+                 param(Sx,I) do
+                    sign_extend(Sx,I,Vx,Vy)),
+                mfd:set_intervals(Y,NInterY)
+            ;   true)
+        ;   true),
+        Sxm1 is Sx - 1,
+        Sym1 is Sy - 1,
+        mfd:dvar_range(X,LX,HX),
+        DpSxm1 is 2^Sxm1,
+        mfd:dvar_range(Y,LY,HY),
+        DpSym1 is 2^Sym1,
+        % signe à 0 ?
+        ((HX < DpSxm1;
+          HY < DpSym1)
+        ->
+            launch_bveq(Sx,X,Sy,Y)
+        ;   % Mask contient I bits a 1
+            % Mask vaut donc 2^(I+1) - 1
+            Mask is \ (-1 << I),
+            mfd:set_intervals(Ext, [0,Mask]),
+            % X et Y de meme signe
+            insert_dep_inst(dep(Sign,0,[X,Y])),
+            bvextract(Sx, Sxm1, Sxm1, X, Sign),
+            bvextract(Sy, Sym1, Sym1, Y, Sign),
+            bvconcat(I, Ext, Sx, X, Y))
+*/
     ;   true),
-    Sxm1 is Sx - 1,
-    Sym1 is Sy - 1,
-    mfd:dvar_range(X,LX,HX),
-    DpSxm1 is 2^Sxm1,
-    mfd:dvar_range(Y,LY,HY),
-    DpSym1 is 2^Sym1,
-    % signe à 0 ?
-    ((HX < DpSxm1;
-      HY < DpSym1)
-    ->
-        launch_bveq(Sx,X,Sy,Y)
-    ;   % Mask contient I bits a 1
-        % Mask vaut donc 2^(I+1) - 1
-        Mask is \ (-1 << I),
-        mfd:set_intervals(Ext, [0,Mask]),
-        % X et Y de meme signe
-        insert_dep_inst(dep(Sign,0,[X,Y])),
-        bvextract(Sx, Sxm1, Sxm1, X, Sign),
-        bvextract(Sy, Sym1, Sym1, Y, Sign),
-        bvconcat(I, Ext, Sx, X, Y)).
+    set_priority(P),
+    wake_if_other_scheduled(P).
 
 % =================== Add ====================248474
 :- export bvadd/4.
diff --git a/Src/COLIBRI/mreal.pl b/Src/COLIBRI/mreal.pl
index b88a9085acdafc9b05450eea0d82ef611b30f2cb..089133cd001d8d751ebaed4c6551de22be15f562 100755
--- a/Src/COLIBRI/mreal.pl
+++ b/Src/COLIBRI/mreal.pl
@@ -448,20 +448,27 @@ one_is_contained(_Type,LI1,S1,LI1,S2,LI,S) ?- !,
     S1 = S2,
     S = S1.
 one_is_contained(Type,LI1,S1,[Min2..Max2],_,LI1,S1) :-
-    interval_range(LI1,Min1,Max1),
+    LI1 = [Min1..Max1],
     compare(O1,Min1,Min2),
     occurs(O1,(>,=)),
+    % Min1 >= Min2
     compare(O2,Max1,Max2),
-    occurs(O2,(<,=)),!,
+    occurs(O2,(<,=)),
+    !,
+    % Max1 =< Max2
+    % LI1 est dans Min2..Max2!,
     (var(S1) ->
         real_interval_size(Type,LI1,0,S1)
     ;   true).
 one_is_contained(Type,[Min1..Max1],_,LI2,S2,LI2,S2) :-
-    interval_range(LI2,Min2,Max2),
+    LI2 = [Min2..Max2],
     compare(O1,Min2,Min1),
     occurs(O1,(>,=)),
+    % Min2 >= Min1
     compare(O2,Max2,Max1),
     occurs(O2,(<,=)),
+    !,
+    % Max2 =< Max1
     (var(S2) ->
         real_interval_size(Type,LI2,0,S2)
     ;   true).
diff --git a/Src/COLIBRI/ndelta.pl b/Src/COLIBRI/ndelta.pl
index 9cb008b4a0d1820557053b61525eee4dac3935ec..61e6c1cf6432dec73fa86a3963b16338cc5d6743 100755
--- a/Src/COLIBRI/ndelta.pl
+++ b/Src/COLIBRI/ndelta.pl
@@ -425,12 +425,13 @@ pre_unify_delta0(T1,T2) :-
               float(T1),abs(T1) =:= 1.0Inf,T=T1;
               float(T2),abs(T2) =:= 1.0Inf,T=T2)
             ->
-                (call(getval(gdbg,1))@eclipse ->
-                    writeln(output,nan_inf(T))
-                ;   true),
-                call(spy_nan_inf)@eclipse,
-                not getval(no_float_error,1)@eclipse
-            ;   true))).
+                (getval(no_float_error,1)@eclipse ->
+                    call(spy_nan_inf)@eclipse,
+                    call(getval(gdbg,1))@eclipse,
+                    writeln(output,nan_inf(T)),
+                    fail
+                ;   true)
+             ;   true))).
 
 pre_unify_delta_var(V1,T2) :-
     (not not_unify(V1,T2)),
diff --git a/Src/COLIBRI/rbox.pl b/Src/COLIBRI/rbox.pl
index d9fd661713d2c816f667e9eb58ad317f3a255164..75d6413bb7c7334d767e9b84237571487d859192 100755
--- a/Src/COLIBRI/rbox.pl
+++ b/Src/COLIBRI/rbox.pl
@@ -54,6 +54,13 @@
    protected_denominator/2
    from colibri.
 
+:- export notify_replace_attribute/4.
+notify_replace_attribute(Var,OA,NA,Mod) :-
+    replace_attribute(Var,NA,Mod),
+    (OA \== NA ->
+        my_notify_constrained(Var),
+        wake
+    ;   true).
 %----------------------------------------------------------------
 % attribute declaration
 %----------------------------------------------------------------
@@ -134,16 +141,20 @@ unify_rbox_rbox(Y, rf(InfosX,NaNX), rf(InfosY,NaNY)) ?-
     ->
         InfosX = InfosY
     ;   ((InfosX == InfosY;
+          Diff = 1,
           InfosX = BoxX-RatX,
           InfosY = BoxY-RatY)
         ->
             RatX = RatY,
             (BoxY == rbox ->
-                replace_attribute(Y,rf(BoxX-RatX,NaNX),rbox)
+                notify_replace_attribute(Y,rf(InfosY,NaNY),rf(BoxX-RatX,NaNX),rbox)
             ;   (BoxY == float_int ->
                     BoxX \== not_float_int
                 ;   % not_float_int
-                    BoxX \== float_int))
+                    BoxX \== float_int),
+                (nonvar(Diff) ->
+                    my_notify_constrained(Y)
+                ;   true))
         ;   (InfosX == float ->
                 atomic(InfosY),
                 occurs(InfosY,(float_int,not_float_int))
@@ -329,7 +340,7 @@ launch_box_prio(Var{rbox:rf(RF,NaN)},Rat) ?- !,
                     Den \== 1
                 ;   NBox = rbox)),
             (var(Var) ->
-                replace_attribute(Var,rf(NBox-Rat,0),rbox),
+                notify_replace_attribute(Var,rf(RF,NaN),rf(NBox-Rat,0),rbox),
                 (get_real_cst(Rat,NVar) ->
                     protected_unify(Var,NVar)
                 ;   add_real_cst(Rat,Var))
@@ -354,7 +365,7 @@ launch_box_prio(Var{rbox:rf(RF,NaN)},Rat) ?- !,
             ;   (RF == not_float_int ->
                     Box = nibox
                 ;   Box = rbox)),
-            replace_attribute(Var,rf(Box-_,0),rbox))).
+            notify_replace_attribute(Var,rf(RF,NaN),rf(Box-_,0),rbox))).
 %% Pas d'attribut
 launch_box_prio(Var,Rat) :-
     (nonvar(Rat) ->
@@ -440,7 +451,7 @@ launch_float_int_prio(Var{rbox:rf(RF,NaN)}) ?- !,
         ->
             NRF = float_int
         ;   NRF = ibox-Rat),
-        replace_attribute(Var,rf(NRF,NaN),rbox),
+        notify_replace_attribute(Var,rf(RF,NaN),rf(NRF,NaN),rbox),
         (mreal:dvar_domain(Var,Dom) ->
             mreal:dom_type(Dom,Type),
             mreal:dom_interval(Dom,Inter),
@@ -505,7 +516,7 @@ launch_not_float_int_prio(Var{rbox:rf(RF,NaN)}) ?- !,
         ->
             NRF = nibox-Rat
         ;   NRF = not_float_int),
-        replace_attribute(Var,rf(NRF,NaN),rbox),
+        notify_replace_attribute(Var,rf(RF,NaN),rf(NRF,NaN),rbox),
         (get_type(Var,Type) ->
             set_not_integral_dom(Type,Var),
             (RF == not_float_int ->
diff --git a/Src/COLIBRI/real_util.pl b/Src/COLIBRI/real_util.pl
index a2b99e3e631a2091a709dd5e99f9001c3ee6690e..8be633d65d901a3f655e0770511a7bdac17ba535 100755
--- a/Src/COLIBRI/real_util.pl
+++ b/Src/COLIBRI/real_util.pl
@@ -520,255 +520,255 @@ get_number_of_simple_floats_between(Inf,Sup,Nb) :-
 
 %PMO a verif
 get_nth_float_from(float_simple,F,N,NF) ?- !,
-	get_nth_simple_float_from(F,N,NF).
+    get_nth_simple_float_from(F,N,NF).
 get_nth_float_from(_,F,N,NF) :-
-	get_nth_double_float_from(F,N,NF).
+    get_nth_double_float_from(F,N,NF).
 
 get_nth_float_from(F,N,NF):-
-	(getval(float_eval,float_simple)@eclipse->
-		get_nth_simple_float_from(F,N,NF)
-	;	get_nth_double_float_from(F,N,NF)).
+    (getval(float_eval,float_simple)@eclipse->
+        get_nth_simple_float_from(F,N,NF)
+    ;   get_nth_double_float_from(F,N,NF)).
 
 get_nth_simple_float_from(F,0,F) :- !.
 get_nth_simple_float_from(F,1,NF) :- !,
-	get_next_simple_float(F,NF).
+    get_next_simple_float(F,NF).
 get_nth_simple_float_from(F,-1,NF) :- !,
-	get_previous_simple_float(F,NF).
+    get_previous_simple_float(F,NF).
 get_nth_simple_float_from(F,N,NF) :-
-	(N > 0 ->
-		DInf is get_number_of_simple_floats_between(F,1.0Inf),
-		(DInf =< N + 1 ->
-			NF = 1.0Inf
-		;	get_nth_simple_from1(F,N,NF))
-	;	%% N < 0, on reculle
-		OpF is norm_zero_op(real,F),
-		OpN is -N,
-		DInf is get_number_of_simple_floats_between(OpF,1.0Inf),
-		(DInf =< OpN + 1 ->
-			NF = -1.0Inf
-		;	get_nth_simple_from1(OpF,OpN,OpNF),
-			NF is norm_zero_op(real,OpNF))).
+    (N > 0 ->
+        DInf is get_number_of_simple_floats_between(F,1.0Inf),
+        (DInf =< N + 1 ->
+            NF = 1.0Inf
+        ;   get_nth_simple_from1(F,N,NF))
+    ;   % N < 0, on reculle
+        OpF is norm_zero_op(real,F),
+        OpN is -N,
+        DInf is get_number_of_simple_floats_between(OpF,1.0Inf),
+        (DInf =< OpN + 1 ->
+            NF = -1.0Inf
+        ;   get_nth_simple_from1(OpF,OpN,OpNF),
+            NF is norm_zero_op(real,OpNF))).
 
 %% PMO a verif
 %% Entre chaque puissance de 2 "normalisee"
 %% on a 2^23 flottants?
 get_nth_simple_from1(F,N,NF) :-
-	(F =:= -1.0Inf ->
-		get_next_simple_float(F,SF),
-		NN is N - 1,
-		get_nth_simple_from2(SF,NN,NF0)
-	;	get_nth_simple_from2(F,N,NF0)),
+    (F =:= -1.0Inf ->
+        get_next_simple_float(F,SF),
+        NN is N - 1,
+        get_nth_simple_from2(SF,NN,NF0)
+    ;   get_nth_simple_from2(F,N,NF0)),
     (NF0 == 0.0 ->
         NF = -0.0
     ;   NF = NF0).
 get_nth_simple_from2(F,N,NF) :-
-	%% N > 0
-	% Representant double du plus petit normalise 1.17549351e-38
-	MinNorm = 1.1754943508222875e-38,%% 2^(-126)
-	OpMinNorm = -1.1754943508222875e-38,
-	DeuxP23 = 8388608,
-	(F =< OpMinNorm ->
-		DOpMinNorm is get_number_of_simple_floats_between(F,OpMinNorm) - 1,
-		(N < DOpMinNorm ->
-			%% On avance dans les normalises negatifs
-			NbUlp is N div DeuxP23,
-			(NbUlp > 0 ->
-				F1 is F*2.0^(-NbUlp),
-				N1 is N mod DeuxP23
-			;	% moins de 1 ulp
-				F1 = F,
-				N1 = N),
-			%% On a moins de 1 ulp a partir de F1
-			%% On avance jusqu'a la prochaine puissance de 2
-			AF is abs(F1),
-			FL2AF is floor_log2(AF),
-			F02 is - (2^FL2AF),
-			norm_zero(real,F02,F2),
-			D12 is get_number_of_simple_floats_between(F1,F2)-1,
-			(N1 =< D12 ->
-				%% on s'arrete avant F2
-				Step is 2.0^(FL2AF-23),
-				NF is F1 + N1*Step
-			;	%% on franchit une puisance de 2 (F2) en allant vers 0 donc
-				%% on divise par 2 l'ulp (on passe à 2^(FL2AF-24) pour ulp) 
-				N2 is N1 - D12,
-				Step is 2.0^(FL2AF-24),
-				NF is F2 + N2*Step),
-			Stop = 1
-		;	%% N >= DOpMinNorm, on passe par les denormalises
-			D0 is get_number_of_simple_floats_between(F,MinNorm)-1,
-			(N < D0 ->
-				%% On reste dans les denormalises
-				F1 = OpMinNorm,
-				N1 is N - DOpMinNorm,
-				NF is F1 + N1* get_simple_float_epsilon,
-				Stop = 1
-			;	%% On avance en MinNorm
-				F0 = MinNorm,
-				N0 is N - D0))
-	;	F0 = F,
-		N0 = N),
-	(nonvar(Stop) ->
-		true
-	;	(F0 < MinNorm ->
-			%% On passe par les denormalises
-			DMinNorm is get_number_of_simple_floats_between(F0,MinNorm)-1,
-			(N0 > DMinNorm ->
-				%% On avance en MinNorm
-				F01 = MinNorm,
-				N01 is N - DMinNorm
-			;	%% On reste dans les denormalises
-				NF is F0 + N0*get_simple_float_epsilon,
-				%% On a fini
-				Stop = 1)
-		;	F01 = F0,
-			N01 = N0),
-		(nonvar(Stop) ->
-			true
-		;	%% On est dans les normalises positifs
-			NbUlp is N01 div DeuxP23,
-			(NbUlp > 0 ->
-				F1 is F01*2.0^NbUlp,
-				N1 is N01 mod DeuxP23
-			;	F1 = F01,
-				N1 = N01),
-			%% On a moins d'une ulp mais on peut en franchir une
-			%% On recule jusqu'a La precedente puissance de 2
-			L2F1 is floor_log2(F1),
-			F2 is 2.0^(L2F1+1),
-			D12 is get_number_of_simple_floats_between(F1,F2)-1,
-			(N1 =< D12 ->
-				%% on s'arrete avant F2
-				Step is 2.0^(L2F1-23),
-				NF is F1 + N1*Step
-			;	%% On avance en F2 et on consomme le reste de N 
-				Step is 2.0^(L2F1-22),
-				N2 is N1 - D12,
-				NF is F2 + N2*Step))).
+    % N > 0
+    % Representant double du plus petit normalise 1.17549351e-38
+    MinNorm = 1.1754943508222875e-38,%% 2^(-126)
+    OpMinNorm = -1.1754943508222875e-38,
+    DeuxP23 = 8388608,
+    (F =< OpMinNorm ->
+        DOpMinNorm is get_number_of_simple_floats_between(F,OpMinNorm) - 1,
+        (N < DOpMinNorm ->
+            % On avance dans les normalises negatifs
+            NbUlp is N div DeuxP23,
+            (NbUlp > 0 ->
+                F1 is F*2.0^(-NbUlp),
+                N1 is N mod DeuxP23
+            ;   % moins de 1 ulp
+                F1 = F,
+                N1 = N),
+            % On a moins de 1 ulp a partir de F1
+            % On avance jusqu'a la prochaine puissance de 2
+            AF is abs(F1),
+            FL2AF is floor_log2(AF),
+            F02 is - (2^FL2AF),
+            norm_zero(real,F02,F2),
+            D12 is get_number_of_simple_floats_between(F1,F2)-1,
+            (N1 =< D12 ->
+                % on s'arrete avant F2
+                Step is 2.0^(FL2AF-23),
+                NF is F1 + N1*Step
+            ;   % on franchit une puisance de 2 (F2) en allant vers 0 donc
+                % on divise par 2 l'ulp (on passe à 2^(FL2AF-24) pour ulp) 
+                N2 is N1 - D12,
+                Step is 2.0^(FL2AF-24),
+                NF is F2 + N2*Step),
+            Stop = 1
+        ;   % N >= DOpMinNorm, on passe par les denormalises
+            D0 is get_number_of_simple_floats_between(F,MinNorm)-1,
+            (N < D0 ->
+                % On reste dans les denormalises
+                F1 = OpMinNorm,
+                N1 is N - DOpMinNorm,
+                NF is F1 + N1* get_simple_float_epsilon,
+                Stop = 1
+            ;   % On avance en MinNorm
+                F0 = MinNorm,
+                N0 is N - D0))
+    ;   F0 = F,
+        N0 = N),
+    (nonvar(Stop) ->
+        true
+    ;   (F0 < MinNorm ->
+            % On passe par les denormalises
+            DMinNorm is get_number_of_simple_floats_between(F0,MinNorm)-1,
+            (N0 > DMinNorm ->
+                % On avance en MinNorm
+                F01 = MinNorm,
+                N01 is N - DMinNorm
+            ;   % On reste dans les denormalises
+                NF is F0 + N0*get_simple_float_epsilon,
+                % On a fini
+                Stop = 1)
+        ;   F01 = F0,
+            N01 = N0),
+        (nonvar(Stop) ->
+            true
+        ;   % On est dans les normalises positifs
+            NbUlp is N01 div DeuxP23,
+            (NbUlp > 0 ->
+                F1 is F01*2.0^NbUlp,
+                N1 is N01 mod DeuxP23
+            ;   F1 = F01,
+                N1 = N01),
+            % On a moins d'une ulp mais on peut en franchir une
+            % On recule jusqu'a La precedente puissance de 2
+            L2F1 is floor_log2(F1),
+            F2 is 2.0^(L2F1+1),
+            D12 is get_number_of_simple_floats_between(F1,F2)-1,
+            (N1 =< D12 ->
+                % on s'arrete avant F2
+                Step is 2.0^(L2F1-23),
+                NF is F1 + N1*Step
+            ;   % On avance en F2 et on consomme le reste de N 
+                Step is 2.0^(L2F1-22),
+                N2 is N1 - D12,
+                NF is F2 + N2*Step))).
 
 
 get_nth_double_float_from(F,0,F) :- !.
 get_nth_double_float_from(F,1,NF) :- !,
-	get_next_double_float(F,NF).
+    get_next_double_float(F,NF).
 get_nth_double_float_from(F,-1,NF) :- !,
-	get_previous_double_float(F,NF).
+    get_previous_double_float(F,NF).
 get_nth_double_float_from(F,N,NF) :-
-	(N > 0 ->
-		DInf is get_number_of_double_floats_between(F,1.0Inf),
-		(DInf =< N + 1 ->
-			NF = 1.0Inf
-		;	get_nth_double_from1(F,N,NF))
-	;	%% N < 0, on reculle
-		OpF is norm_zero_op(real,F),
-		OpN is -N,
-		DInf is get_number_of_double_floats_between(OpF,1.0Inf),
-		(DInf =< OpN + 1 ->
-			NF = -1.0Inf
-		;	get_nth_double_from1(OpF,OpN,OpNF),
-			NF is norm_zero_op(real,OpNF))).
+    (N > 0 ->
+        DInf is get_number_of_double_floats_between(F,1.0Inf),
+        (DInf =< N + 1 ->
+            NF = 1.0Inf
+        ;   get_nth_double_from1(F,N,NF))
+    ;   % N < 0, on reculle
+        OpF is norm_zero_op(real,F),
+        OpN is -N,
+        DInf is get_number_of_double_floats_between(OpF,1.0Inf),
+        (DInf =< OpN + 1 ->
+            NF = -1.0Inf
+        ;   get_nth_double_from1(OpF,OpN,OpNF),
+            NF is norm_zero_op(real,OpNF))).
 
 %% Entre chaque puissance de 2 "normalisee"
 %% on a 2^52 flottants
 get_nth_double_from1(F,N,NF) :-
-	(F =:= -1.0Inf ->
-		get_next_double_float(F,SF),
-		NN is N - 1,
-		get_nth_double_from2(SF,NN,NF0)
-	;	get_nth_double_from2(F,N,NF0)),
+    (F =:= -1.0Inf ->
+        get_next_double_float(F,SF),
+        NN is N - 1,
+        get_nth_double_from2(SF,NN,NF0)
+    ;   get_nth_double_from2(F,N,NF0)),
     (NF0 == 0.0 ->
         NF = -0.0
     ;   NF = NF0).
 get_nth_double_from2(F,N,NF) :-
-	%% N > 0
-	MinNorm = 4.4501477170144028e-308, % 2^-1021
-	OpMinNorm = -4.4501477170144028e-308,
-	DeuxP52 = 4503599627370496,
-	(F =< OpMinNorm ->
-		DOpMinNorm is get_number_of_double_floats_between(F,OpMinNorm) - 1,
-		(N < DOpMinNorm ->
-			%% On avance dans les normalises negatifs
-			NbUlp is N div DeuxP52,
-			(NbUlp > 0 ->
-				F1 is F*2.0^(-NbUlp),
-				N1 is N mod DeuxP52
-			;	F1 = F,
-				N1 = N),
-			%% On a moins d'une ulp mais on peut en franchir une
-			%% On avance jusqu'a la prochaine puissance de 2
-			AF is abs(F1),
-			FL2AF is floor_log2(AF),
-			F02 is - (2^FL2AF),
-			norm_zero(real,F02,F2),
-			D12 is get_number_of_double_floats_between(F1,F2)-1,
-			(N1 =< D12 ->
-				%% on s'arrete avant F2
-				Step is 2.0^(FL2AF-52),
-				NF is F1 + N1*Step
-			;	%% on franchit une puisance de 2 (F2) en allant vers 0 donc
-				%% on divise par 2 l'ulp (on passe à 2^(FL2AF-53) pour ulp) 
-				N2 is N1 - D12,
-				Step is 2.0^(FL2AF-53),
-				NF is F2 + N2*Step),
-			Stop = 1
-		;	%% N >= DOpMinNorm, on passe par les denormalises
-			D0 is get_number_of_double_floats_between(F,MinNorm)-1,
-			(N < D0 ->
-				%% On reste dans les denormalises
-				F1 = OpMinNorm,
-				N1 is N - DOpMinNorm,
-				NF is F1 + N1* get_double_float_epsilon,
-				Stop = 1
-			;	%% On avance en MinNorm
-				F0 = MinNorm,
-				N0 is N - D0))
-	;	F0 = F,
-		N0 = N),
-	(nonvar(Stop) ->
-		true
-	;	(F0 < MinNorm ->
-			%% On passe par les denormalises
-			DMinNorm is get_number_of_double_floats_between(F0,MinNorm)-1,
-			(N0 > DMinNorm ->
-				%% On avance en MinNorm
-				F01 = MinNorm,
-				N01 is N - DMinNorm
-			;	%% On reste dans les denormalises
-				NF is F0 + N0*get_double_float_epsilon,
-				%% On a fini
-				Stop = 1)
-		;	F01 = F0,
-			N01 = N0),
-		(nonvar(Stop) ->
-			true
-		;	%% On est dans les normalises positifs
-			NbUlp is N01 div DeuxP52,
-			(NbUlp > 0 ->
-				%% F1 is F01*2.0^NbUlp
-				%% IL FAUT CONDITIONNER CE CALCUL CAR
-				%% NbUlp PEUT ETRE >>> 1024 QUAND F01 < 1.0
-				(F01 < 1.0 ->
-					%% On est dans une puissance de 2 negative
-					L2F is floor_log2(F01), 
-					%% -1021 =< L2F < 0
-%%					F1 is (F01*2.0^(NbUlp+L2F))*2.0^(-L2F)
-					F1 is (F01*2.0^(1-L2F))*2.0^(NbUlp+L2F-1)
-				;	F1 is F01*2.0^NbUlp),
-				N1 is N01 mod DeuxP52
-			;	F1 = F01,
-				N1 = N01),
-			%% On a moins d'une ulp mais on peut en franchir une
-			%% On recule jusqu'a La precedente puissance de 2
-			L2F1 is floor_log2(F1),
-			F2 is 2.0^(L2F1+1),
-			D12 is get_number_of_double_floats_between(F1,F2)-1,
-			(N1 =< D12 ->
-				%% on s'arrete avant F2
-				Step is 2.0^(L2F1-52),
-				NF is F1 + N1*Step
-			;	%% On avance en F2 et on consomme le reste de N 
-				Step is 2.0^(L2F1-51),
-				N2 is N1 - D12,
-				NF is F2 + N2*Step))).
+    % N > 0
+    MinNorm = 4.4501477170144028e-308, % 2^-1021
+    OpMinNorm = -4.4501477170144028e-308,
+    DeuxP52 = 4503599627370496,
+    (F =< OpMinNorm ->
+        DOpMinNorm is get_number_of_double_floats_between(F,OpMinNorm) - 1,
+        (N < DOpMinNorm ->
+            % On avance dans les normalises negatifs
+            NbUlp is N div DeuxP52,
+            (NbUlp > 0 ->
+                F1 is F*2.0^(-NbUlp),
+                N1 is N mod DeuxP52
+            ;   F1 = F,
+                N1 = N),
+            % On a moins d'une ulp mais on peut en franchir une
+            % On avance jusqu'a la prochaine puissance de 2
+            AF is abs(F1),
+            FL2AF is floor_log2(AF),
+            F02 is - (2^FL2AF),
+            norm_zero(real,F02,F2),
+            D12 is get_number_of_double_floats_between(F1,F2)-1,
+            (N1 =< D12 ->
+                % on s'arrete avant F2
+                Step is 2.0^(FL2AF-52),
+                NF is F1 + N1*Step
+            ;   % on franchit une puisance de 2 (F2) en allant vers 0 donc
+                % on divise par 2 l'ulp (on passe à 2^(FL2AF-53) pour ulp) 
+                N2 is N1 - D12,
+                Step is 2.0^(FL2AF-53),
+                NF is F2 + N2*Step),
+            Stop = 1
+        ;   % N >= DOpMinNorm, on passe par les denormalises
+            D0 is get_number_of_double_floats_between(F,MinNorm)-1,
+            (N < D0 ->
+                % On reste dans les denormalises
+                F1 = OpMinNorm,
+                N1 is N - DOpMinNorm,
+                NF is F1 + N1* get_double_float_epsilon,
+                Stop = 1
+            ;   % On avance en MinNorm
+                F0 = MinNorm,
+                N0 is N - D0))
+    ;   F0 = F,
+        N0 = N),
+    (nonvar(Stop) ->
+        true
+    ;   (F0 < MinNorm ->
+            % On passe par les denormalises
+            DMinNorm is get_number_of_double_floats_between(F0,MinNorm)-1,
+            (N0 > DMinNorm ->
+                % On avance en MinNorm
+                F01 = MinNorm,
+                N01 is N - DMinNorm
+            ;   % On reste dans les denormalises
+                NF is F0 + N0*get_double_float_epsilon,
+                % On a fini
+                Stop = 1)
+        ;   F01 = F0,
+            N01 = N0),
+        (nonvar(Stop) ->
+            true
+        ;   % On est dans les normalises positifs
+            NbUlp is N01 div DeuxP52,
+            (NbUlp > 0 ->
+                % F1 is F01*2.0^NbUlp
+                % IL FAUT CONDITIONNER CE CALCUL CAR
+                % NbUlp PEUT ETRE >>> 1024 QUAND F01 < 1.0
+                (F01 < 1.0 ->
+                    % On est dans une puissance de 2 negative
+                    L2F is floor_log2(F01), 
+                    % -1021 =< L2F < 0
+                    % F1 is (F01*2.0^(NbUlp+L2F))*2.0^(-L2F)
+                    F1 is (F01*2.0^(1-L2F))*2.0^(NbUlp+L2F-1)
+                ;   F1 is F01*2.0^NbUlp),
+                N1 is N01 mod DeuxP52
+            ;   F1 = F01,
+                N1 = N01),
+            % On a moins d'une ulp mais on peut en franchir une
+            % On recule jusqu'a La precedente puissance de 2
+            L2F1 is floor_log2(F1),
+            F2 is 2.0^(L2F1+1),
+            D12 is get_number_of_double_floats_between(F1,F2)-1,
+            (N1 =< D12 ->
+                % on s'arrete avant F2
+                Step is 2.0^(L2F1-52),
+                NF is F1 + N1*Step
+            ;   % On avance en F2 et on consomme le reste de N 
+                Step is 2.0^(L2F1-51),
+                N2 is N1 - D12,
+                NF is F2 + N2*Step))).
 
 %% Fin ZONE A COMMENTER POUR VERSION SANS FLOTTANTS
 %%:- setval(libdbg,1).%PMO
@@ -1040,8 +1040,11 @@ int_to_simple_float_max(Int,DMax) :-
 
     
 % en real/double
-is_pow2(C,PC) :-
-    abs(C) < 1.0Inf,
+is_pow2(C0,PC) :-
+    float(C0,C),
+    abs(C,AC),
+    AC < 1.0Inf,
+    AC \== 0.0,
     get_double_float_parts(C,S,M,E),
     (E == -1023 ->
         % Denormalise
diff --git a/Src/COLIBRI/realarith.pl b/Src/COLIBRI/realarith.pl
index 879253379ebe74d5868bca3f5c6dc25a71eb7b6d..3dae31c41abe98e0933c23863ee25fde19574a38 100644
--- a/Src/COLIBRI/realarith.pl
+++ b/Src/COLIBRI/realarith.pl
@@ -743,11 +743,14 @@ check_round_floor_ceiling(Type,Round,A,B,EF,EC,FA,CA,_,Stop).
 round_rna_val(Type,A,B) :-
     (is_float_int_number(A) ->
         B = A
-    ;   abs(A,AbsA),
+    ;   (is_real_box_rat(A,RA0) ->
+            true
+        ;   RA0 = A),
+        abs(RA0,AbsA),
         make_OCamlRat(AbsA,RA),
         simplex_ocaml_rat_round_integer_RNA(RA,IRB),
         float_of_OCamlRat(Type,rna,IRB,AbsB),
-        (A > 0.0 ->
+        (RA0 > 0.0 ->
             B = AbsB
         ;   B is -AbsB)).
 
@@ -2151,9 +2154,9 @@ check_before_susp_cast_float_to_double_bis(A,B) :-
             double_is_simple_float(B),
             protected_unify(A = B)
         ;   cast_float_to_double_ineqs(A,B),
-            
             my_suspend(cast_float_to_double_bis(A,B),3,(A,B)->suspend:constrained))).
 
+%cast_float_to_double_ineqs(A,B) :- !.
 cast_float_to_double_ineqs(A,B) :-
     var(A),
     var(B),
@@ -2179,16 +2182,18 @@ cast_float_to_double_ineqs1([S|LSuspV],Seen,NSeen,A,B) :-
         get_suspension_data(S,goal,G),
         (G = cast_float_to_double_bis(AA,BB) ->
             get_rel_between_real_args(A,AA,RA),
-            % A =< AA ==> double(A) =< double(AA)
+            % Tous les float sont représentables en double
+            % A Rel AA ==> double(A) Rel double(AA)
             (RA \== ? ->
                 launch_real_ineq(RA,float_double,B,BB)
             ;   true),
             get_rel_between_real_args(B,BB,RB),
-            % double(A) =< double(AA) ==> A =< AA
+            % double(A) Rel double(AA) ==> A Rel AA
             (RB \== ? ->
                 launch_real_ineq(RB,float_simple,A,AA)
             ;   true)
-        ;   (G = cast_double_to_float_bis(BB,AA) ->
+        ;   (fail,G = cast_double_to_float_bis(BB,AA) ->
+                % A REVOIR !!!
                 get_rel_between_real_args(B,BB,RB),
                 % double(A) > BB ==> A >= float(BB)
                 % double(A) >= BB ==> A >= float(BB)
@@ -2507,6 +2512,7 @@ check_before_susp_cast_double_to_float_bis(A,B) :-
         ;   cast_double_to_float_ineqs(A,B),
             my_suspend(cast_double_to_float_bis(A,B),3,(A,B)->suspend:constrained))).
 
+%cast_double_to_float_ineqs(A,B) :- !.
 cast_double_to_float_ineqs(A,B) :-
     var(A),
     var(B),
@@ -2776,12 +2782,16 @@ mult_rat_interval(LA,HA,LB,HB,LR,HR) :-
                     max(H1,H2,HR))))).
 
 negative_rat(Rat) :-
-    simplex_ocaml_rat_num(Rat,SNum),
-    number_string(Num,SNum),
+    (number(Rat) ->
+        Num = Rat
+    ;   simplex_ocaml_rat_num(Rat,SNum),
+        number_string(Num,SNum)),
     get_sign(Num,neg).
 positive_rat(Rat) :-
-    simplex_ocaml_rat_num(Rat,SNum),
-    number_string(Num,SNum),
+    (number(Rat) ->
+        Num = Rat
+    ;   simplex_ocaml_rat_num(Rat,SNum),
+        number_string(Num,SNum)),
     get_sign(Num,pos).
 
 
@@ -3375,10 +3385,15 @@ clear_Goals_add_real(Type,A,B,C) :-
            BB == B
        ;   AA == B,
            BB == A),
+       % A+B = C et A+B = CC -> C=CC
        Kill == 1;
-       G = minus_real1(Type,AA,BB,CC),
+       Type == real,
+       % ATTENTION AUX ZEROS
+       % A+B = C et A-OpB = CC -> C=CC
+       G = minus_real1(Type,AA,OpB,CC),
        AA == A,
-       is_op_real(Type,BB,B)))
+       is_op_real(Type,A,OpBB),
+       OpBB == OpB))
     ->
         (nonvar(Kill) ->
             kill_suspension(S)
@@ -3615,9 +3630,8 @@ add_real_2_args_equal(Type,X,Y,Z,Continue) :-
         true
     ;   Continue = 1,
         mreal:dvar_domain(B,DomB),
-        (not is_fzero(B) ->
-            true
-        ;   % B <> 0 et A doit absorber B
+        (not_zero(B) ->
+            % B <> 0 et A doit absorber B
             % On peut enlever de A le plus grand intervalle autour de zero
             % qui n'absorbe pas les plus petites valeurs de B
             % Meme si B est une constante on doit continuer:
@@ -3626,7 +3640,8 @@ add_real_2_args_equal(Type,X,Y,Z,Continue) :-
             greatest_interval_not_absorbing(add,Type,B,IAbsB),
             mreal:get_intervals(A,IA),
             mreal:finterval_difference(Type,IA,[IAbsB],NIA),
-            mreal:set_typed_intervals(A,Type,NIA))).
+            mreal:set_typed_intervals(A,Type,NIA)
+        ;   true)).
 % Simplifications communes avec un "op_real"
 add_real_2_args_equal(Type,A,B,C,_) :- 
     get_saved_cstr_suspensions(LSusp),
@@ -3776,7 +3791,7 @@ add_real_zeroes(_,Z1,Z2,C) ?- !,
         protected_unify(C = -0.0)
     ;   protected_unify(C = 0.0)).
 
-add_real_inst(Type,A,B,C,_) ?-
+add_real_inst(Type,A,B,C,Continue) ?-
     (B == A ->
         !,
         (C == A ->
@@ -3791,6 +3806,7 @@ add_real_inst(Type,A,B,-0.0,_) ?-
     !,
     protected_unify(A,-0.0),
     protected_unify(B,-0.0).
+
 add_real_inst(real,0.0,B,C,_) ?- !,
     protected_unify(B,C).
 add_real_inst(real,A,0.0,C,_) ?- !,
@@ -3827,6 +3843,8 @@ add_real_inst(Type,A,B,C,Continue) :-
         ;   % A = +0, B contient -0 et C contient +/-0
             % mais C <> -0.0
             mreal:dvar_remove_element(C,-0.0),
+            protected_unify(B,C))).
+/*
             (C == 0.0 ->
                 set_typed_intervals(B,Type,[-0.0 .. 0.0])
             ;   (float(C) ->
@@ -3859,6 +3877,7 @@ add_real_inst(Type,A,B,C,Continue) :-
                             ;   Var = B),
                             isZero(as(Var,Type)) #= as(Bool,bool),
                             Continue = 1)))))).
+*/
 add_real_inst(Type,A,B,C,Continue) :-
     nonvar(B),
     B =:= 0.0,
@@ -4149,16 +4168,24 @@ check_add_rat(A,B,C) :-
             fail)
     ;   launch_box_rat(C,RatC)).
 safe_add_rat(A0,B0,RatC) :-
-    (var(A0) ->
-        A = A0
-    ;   A is A0),
-    (var(B0) ->
-        B = B0
-    ;   B is B0),
-    check_rbox_rat(A,RatA),
-    check_rbox_rat(B,RatB),
-    make_OCamlRat(RatA,RA),
-    make_OCamlRat(RatB,RB),
+    (((var(A0);
+       number(A0)),
+      A = A0;
+      compound(A0),
+      A is A0)
+    ->
+        check_rbox_rat(A,RatA),
+        make_OCamlRat(RatA,RA)
+    ;   RA = A0),
+    (((var(B0);
+       number(B0)),
+      B = B0;
+      compound(B0),
+      B is B0)
+    ->
+        check_rbox_rat(B,RatB),
+        make_OCamlRat(RatB,RB)
+    ;   RB = B0),
     add_rat(RA,RB,RC),
     simplex_ocaml_rat_num(RC,SCNum),
     simplex_ocaml_rat_den(RC,SCDen),
@@ -4174,16 +4201,24 @@ check_minus_rat(A,B,C) :-
             fail)
     ;   launch_box_rat(C,RatC)).
 safe_minus_rat(A0,B0,RatC) :-
-    (var(A0) ->
-        A = A0
-    ;   A is A0),
-    (var(B0) ->
-        B = B0
-    ;   B is B0),
-    check_rbox_rat(A,RatA),
-    check_rbox_rat(B,RatB),
-    make_OCamlRat(RatA,RA),
-    make_OCamlRat(RatB,RB),
+    (((var(A0);
+       number(A0)),
+      A = A0;
+      compound(A0),
+      A is A0)
+    ->
+        check_rbox_rat(A,RatA),
+        make_OCamlRat(RatA,RA)
+    ;   RA = A0),
+    (((var(B0);
+       number(B0)),
+      B = B0;
+      compound(B0),
+      B is B0)
+    ->
+        check_rbox_rat(B,RatB),
+        make_OCamlRat(RatB,RB)
+    ;   RB = B0),
     sub_rat(RA,RB,RC),
     simplex_ocaml_rat_num(RC,SCNum),
     simplex_ocaml_rat_den(RC,SCDen),
@@ -4204,16 +4239,24 @@ check_mult_rat(A,B,C) :-
             fail)
     ;   launch_box_rat(C,RatC)).
 safe_mult_rat(A0,B0,RatC) :-
-    (var(A0) ->
-        A = A0
-    ;   A is A0),
-    (var(B0) ->
-        B = B0
-    ;   B is B0),
-    check_rbox_rat(A,RatA),
-    check_rbox_rat(B,RatB),
-    make_OCamlRat(RatA,RA),
-    make_OCamlRat(RatB,RB),
+    (((var(A0);
+       number(A0)),
+      A = A0;
+      compound(A0),
+      A is A0)
+    ->
+        check_rbox_rat(A,RatA),
+        make_OCamlRat(RatA,RA)
+    ;   RA = A0),
+    (((var(B0);
+       number(B0)),
+      B = B0;
+      compound(B0),
+      B is B0)
+    ->
+        check_rbox_rat(B,RatB),
+        make_OCamlRat(RatB,RB)
+    ;   RB = B0),
     mult_rat(RA,RB,RC),
     simplex_ocaml_rat_num(RC,SCNum),
     simplex_ocaml_rat_den(RC,SCDen),
@@ -4229,16 +4272,24 @@ check_div_rat(A,B,C) :-
             fail)
     ;   launch_box_rat(C,RatC)).
 safe_div_rat(A0,B0,RatC) :-
-    (var(A0) ->
-        A = A0
-    ;   A is A0),
-    (var(B0) ->
-        B = B0
-    ;   B is B0),
-    check_rbox_rat(A,RatA),
-    check_rbox_rat(B,RatB),
-    make_OCamlRat(RatA,RA),
-    make_OCamlRat(RatB,RB),
+    (((var(A0);
+       number(A0)),
+      A = A0;
+      compound(A0),
+      A is A0)
+    ->
+        check_rbox_rat(A,RatA),
+        make_OCamlRat(RatA,RA)
+    ;   RA = A0),
+    (((var(B0);
+       number(B0)),
+      B = B0;
+      compound(B0),
+      B is B0)
+    ->
+        check_rbox_rat(B,RatB),
+        make_OCamlRat(RatB,RB)
+    ;   RB = B0),
     div_rat(RA,RB,RC),
     simplex_ocaml_rat_num(RC,SCNum),
     simplex_ocaml_rat_den(RC,SCDen),
@@ -5547,8 +5598,6 @@ add_real_ineqs(Type,A,B,C) :-
         ->
             check_exists_lin_expr_giving_diff_args(real,C,0.0,_Stop)
         ;   true),
-        % pour unsat/issue35.smt2 ????
-        check_add_op_real(Type,A,B,C),
         average_add_real_ineqs(Type,A,B,C),
         bin_op_real_ineq(Type,add_real1,A,B,C)).
 
@@ -5586,7 +5635,6 @@ add_real_ineqs0(Type,A,B,C) :-
     ->
         check_exists_lin_expr_giving_diff_args(real,C,0.0,_Stop)
     ;   true),
-    %check_add_op_real(Type,A,B,C),
     average_add_real_ineqs(Type,A,B,C),
     bin_op_real_ineq(Type,add_real1,A,B,C).
 
@@ -8258,17 +8306,110 @@ op_real(Type,A,B) :-
 op_real1(Type,A,B) :-
     get_priority(Prio),
     set_priority(1),
+    save_cstr_suspensions((A,B)),
     same_float_int_number_status(Type,A,B),
+    ((var(A),
+      var(B))
+    ->
+        check_op_mult_div_real(Type,A,B)
+    ;   true),
     op_real_bis(Type,A,B),
     set_priority(Prio),
     wake_if_other_scheduled(Prio).
 
+check_op_mult_div_real(real,A,OpA) ?- !,
+    % -(X*Y) = -X*Y = X*-Y, idem pour /
+    % -(round(X)) = round(-X)
+    % -(truncate(X)) = truncate(-X)
+    get_saved_cstr_suspensions(LS),
+    (foreach((S,G),LS),
+     fromto([],IGs,OGs,LNGs),
+     param(A,OpA) do
+        get_suspension_data(S,state,State),
+        functor(G,FG,ArG),
+        ((State == 1;
+          not occurs(FG,(op_real1,mult_real1,div_real1,add_real1,
+                     minus_real1,round_bis,truncate_bis,floor_bis,ceiling_bis));
+          arg(ArG,G,Z),
+          Z \== A)
+        ->
+            OGs = IGs
+        ;   (G = op_real1(real,X,Z) ->
+                NGs = protected_unify(X,OpA)
+            ;   ((G = mult_real1(real,X,Y,Z),
+                  fail,Z == A)
+                ->
+                    NGs = (   set_lazy_domain(real,OpX),
+                              op_real_bis(real,X,OpX),
+                              mult_real(real,OpX,Y,OpA),
+                              % -(X*Y) = X*-Y
+                              set_lazy_domain(real,OpY),
+                              op_real_bis(real,Y,OpY),
+                              mult_real(real,X,OpY,OpA)),
+                    OGs = [NGs|IGs]
+                ;   (fail,G = div_real1(real,X,Y,Z) ->
+                        NGs = (   % -(X/Y) = -X/Y
+                                  set_lazy_domain(real,OpX),
+                                  op_real_bis(real,X,OpX),
+                                  div_real(real,OpX,Y,OpA),
+                                  % -(X/Y) = X/-Y
+                                  set_lazy_domain(real,OpY),
+                                  op_real_bis(real,Y,OpY),
+                                  div_real(real,X,OpY,OpA)),
+                        OGs = [NGs|IGs]
+                    ;   (fail,G = add_real1(real,X,Y,Z) ->
+                            NGs = (   % -(X+Y) = -X+-Y
+                                      set_lazy_domain(real,OpX),
+                                      op_real_bis(real,X,OpX),
+                                      set_lazy_domain(real,OpY),
+                                      op_real_bis(real,Y,OpY),
+                                      add_real(real,OpX,OpY,OpA)),
+                            OGs = [NGs|IGs]
+                        ;   (fail,G = minus_real1(real,X,Y,Z) ->
+                                NGs = (   % -(X-Y) = -X+Y
+                                          set_lazy_domain(real,OpX),
+                                          op_real_bis(real,X,OpX),
+                                          add_real(real,OpX,Y,OpA)),
+                                OGs = [NGs|IGs]
+                            ;   (G = round_bis(real,X,Z) ->
+                                    % -round(X) = round(-X)
+                                    NGs = (set_lazy_domain(real,OpX),
+                                           op_real_bis(real,X,OpX),
+                                           round(real,OpX,OpA)),
+                                    OGs = [NGs|IGs]
+                                ;   (G = truncate_bis(real,X,Z) ->
+                                        % -truncate(X) = truncate(-X)
+                                        NGs = (set_lazy_domain(real,OpX),
+                                               op_real_bis(real,X,OpX),
+                                               truncate(real,OpX,OpA)),
+                                        OGs = [NGs|IGs]
+                                    ;   (G = floor_bis(real,X,Z) ->
+                                            NGs = (set_lazy_domain(real,OpX),
+                                                   op_real_bis(real,X,OpX),
+                                                   floor(real,OpX,OpA)),
+                                            OGs = [NGs|IGs]
+                                        ;   (G = ceiling_bis(real,X,Z) ->
+                                                NGs = (set_lazy_domain(real,OpX),
+                                                       op_real_bis(real,X,OpX),
+                                                       ceiling(real,OpX,OpA)),
+                                                OGs = [NGs|IGs]
+                                            ;   OGs = IGs))))))))))),
+    (LNGs \== [] ->
+        % -(X op Y) = OpA
+        % ou -round/truncate(X) = OpA
+        % on essaye de saturer
+        call(spy_here)@eclipse,
+        (foreach(NGs,LNGs) do
+            call_priority(NGs,2))
+    ;   true).
+check_op_mult_div_real(_,_,_).
+
 op_real_bis(Type,A,B) :-
     (A == B ->
         % fail en flottants
         Type == real,
         protected_unify(A,0.0)
-    ;   save_cstr_suspensions((A,B)),
+    ;   %save_cstr_suspensions((A,B)),
         (is_float_int_number(A) ->
             launch_float_int_number(B)
         ;   (is_float_int_number(B) ->
@@ -8618,10 +8759,6 @@ check_launch_op_int(Type,A,B,_,Continue) :-
       term_variables((A,B),[_,_]),
       is_float_int_number(A),
       is_float_int_number(B),
-/*
-      not_inf_bounds(A),
-      not_inf_bounds(B))
-*/
       is_inside_mantissa(Type,A),
       is_inside_mantissa(Type,B))
 
@@ -8641,20 +8778,14 @@ minus_real(A,B,C) :-
     minus_real_type(Type,A,B,C).
 
 minus_real_type(real,A,B,C) ?- !,
-    minus_real(real,A,B,C).
+%    minus_real(real,A,B,C).
+    op_real(real,B,OB),
+    add_real(real,A,OB,C).
 minus_real_type(Type,A,B,C) :-
     (getval(no_float_error,1)@eclipse ->
         minus_real(Type,A,B,C)
     ;   fp_sub(rne,as(A,Type),as(B,Type)) $= as(C,Type)).
 
-/*
-minus_real(Type,A,B,C) :- 
-    Type \== real,
-    !,
-    op_real(Type,B,OpB),
-    fp_eq(Type,OpB,OpBB),
-    add_real(Type,A,OpBB,C).
-*/
 minus_real(Type,A,B,C) :-
     ((Type == real,
       var(A),
@@ -8858,11 +8989,17 @@ clear_Goals_minus_real(Type,A,B,C) :-
     get_saved_cstr_suspensions(LSusp),
     ((member((S,G),LSusp),
       (G = minus_real1(Type,AA,BB,CC),
-       AA == A, BB == B;
-       G = add_real1(Type,AA,BB,CC),
-       AA == A, is_op_real(Type,BB,B)))
+       AA == A, BB == B,
+       Kill = 1;
+       Type == real,
+       G = add_real1(Type,AA,OpB,CC),
+       AA == A,
+       is_op_real(Type,A,OpBB),
+       OpBB = OpB))
     ->
-        kill_suspension(S),
+        (nonvar(Kill) ->
+            kill_suspension(S)
+        ;   true),
         protected_unify(C,CC)
     ;   true).
 clear_Goals_minus_real0(real,A,B,C) ?- !,
@@ -8939,7 +9076,8 @@ check_launch_minus_int(Type,A,B,C,_,Continue) :-
 minus_real_2_args_equal(Type,A,A,C,_) ?- !,
     forbid_infinities(Type,[A]),
     protected_unify(C = 0.0).
-minus_real_2_args_equal(Type,A,B,B,Continue) ?- !,
+minus_real_2_args_equal(Type,A,B,B,Continue) ?- 
+fail,    !,
     % En nearest, la projection inverse sur A
     % est B +|- ulp(B)/2 + B qui donne bien 2B
     % sauf si abs(B) = 1.0Inf (ou abs(B)) alors on doit echouer
@@ -8949,71 +9087,74 @@ minus_real_2_args_equal(Type,A,B,C,Continue) :-
     exists_feq(Type,A,C),
     !,
     (Type == real ->
-		(not_inf_bounds(A) ->
-			protected_unify(B = 0.0)
-		;	true)
-	;	%% Type == float
-		%% -B est absorbe par A 
-		%% On peut enlever de B tout ce qui n'est pas absorbable
-		%% par A
-		%% Les Min/Max de A et la projection inverse sur B
-		%% suffisent pour sur-approximer B
-		mreal:dvar_range(A,MinA,MaxA),
-		inv2_minus_float_same_interval(Type,MinA,MaxA,LB,HB),
-		mreal:set_typed_intervals(B,Type,[LB..HB]),
-		mreal:dvar_range(B,MinB,MaxB),
-		((B == 0.0;
-		  has_absorbed_range(Type,A,L,H),
-		  L =< -MaxB,
-		  H >= -MinB)
-		->
-			%% -B est absorbe par A
-			true
-		;	Continue = 1,
-			mreal:dvar_domain(B,DomB),
-			(mreal:in_domain(DomB,0.0) ->
-				true
-			;	%% B <> 0
-				%% On peut enlever de A l'intervalle autour de zero
-				%% qui n'absorbe pas la plus petite valeur absolue de B
-				%% Meme si B est une constante on doit continuer:
-				%% - on a travaille en valeurs absolues et les ulps
-				%%   g/d sont inversees selon le signe
-				%% - l'arrondi nearest to even n'est pas continu si B est une
-				%%   puissance de deux, il y a des valeurs de NIA 
-				%%   qui n'absorbent pas B
-				greatest_interval_not_absorbing(minus,Type,B,IAbsOpB),
-				mreal:get_intervals(A,IA),
-				mreal:finterval_difference(Type,IA,[IAbsOpB],NIA),
-				mreal:set_typed_intervals(A,Type,NIA)))).
+        (not_inf_bounds(A) ->
+            protected_unify(B = 0.0)
+        ;   true)
+    ;   % Type == float*
+        % -B est absorbe par A 
+        % On peut enlever de B tout ce qui n'est pas absorbable
+        % par A
+        % Les Min/Max de A et la projection inverse sur B
+        % suffisent pour sur-approximer B
+        mreal:dvar_range(A,MinA,MaxA),
+        inv2_minus_float_same_interval(Type,MinA,MaxA,LB,HB),
+        mreal:set_typed_intervals(B,Type,[LB..HB]),
+        mreal:dvar_range(B,MinB,MaxB),
+        ((B == 0.0;
+          has_absorbed_range(Type,A,L,H),
+          L =< -MaxB,
+          H >= -MinB)
+        ->
+            % -B est absorbe par A
+            true
+        ;   Continue = 1,
+            mreal:dvar_domain(B,DomB),
+            (not_zero(B) ->
+                % B <> 0
+                % On peut enlever de A l'intervalle autour de zero
+                % qui n'absorbe pas la plus petite valeur absolue de B
+                % Meme si B est une constante on doit continuer:
+                % - on a travaille en valeurs absolues et les ulps
+                %   g/d sont inversees selon le signe
+                % - l'arrondi nearest to even n'est pas continu si B est une
+                %   puissance de deux, il y a des valeurs de NIA 
+                %   qui n'absorbent pas B
+                greatest_interval_not_absorbing(minus,Type,B,IAbsOpB),
+                mreal:get_intervals(A,IA),
+                mreal:finterval_difference(Type,IA,[IAbsOpB],NIA),
+                mreal:set_typed_intervals(A,Type,NIA)
+            ;   true))).
 %% Simplifications communes avec un "op_real"
 minus_real_2_args_equal(Type,A,B,C,_) :- 
-	get_saved_cstr_suspensions(LSusp),
-	member((Susp,op_real1(Type,X,Y)),LSusp),
-	( A == X, 
-	  (B == Y,
+fail,    get_saved_cstr_suspensions(LSusp),
+    member((Susp,op_real1(Type,X,Y)),LSusp),
+    ( A == X, 
+      (B == Y,
        Goal = mult_real_bis(Type,2.0,A,C);	%% A - -A = C
-	   C == Y,
-       Goal = (forbid_infinities(Type,[A,B]),mult_real_bis(Type,2.0,A,B))) 	%% A - B = -A
-	   %% En nearest, la projection inverse sur B
-	   %% est A +|- ulp(A)/2 + A qui donne bien 2A
-	; A == Y, 
-	  (B == X,
-       Goal = mult_real_bis(Type,2.0,A,C);	%% -B - B = C, ie A - -A = C
-	   C == X,
-       Goal = (forbid_infinities(Type,[A,B]),mult_real_bis(Type,2.0,A,B))) 	%% -C - B = C, ie A - B = -A
-	; B == X,
-	  (A == Y,
+       C == Y,
+       Goal = (forbid_infinities(Type,[A,B]),mult_real_bis(Type,2.0,A,B))) 	
+      % A - B = -A
+      % En nearest, la projection inverse sur B
+      % est A +|- ulp(A)/2 + A qui donne bien 2A
+    ; A == Y, 
+      (B == X,
+       Goal = mult_real_bis(Type,2.0,A,C);
+       % -B - B = C, ie A - -A = C
+       C == X,
+       Goal = (forbid_infinities(Type,[A,B]),mult_real_bis(Type,2.0,A,B)))
+      % -C - B = C, ie A - B = -A
+    ; B == X,
+      (A == Y,
        Goal = mult_real_bis(Type,2.0,A,C);	%% -B - B = C, ie A - -A = C
-	   C == Y,
+       C == Y,
        Goal = add_real_bis(Type,A,C,C))		%% A + -B = -B
-	; B == Y,
-	  (A == X,
+    ; B == Y,
+      (A == X,
        Goal = mult_real_bis(Type,2.0,A,C);	%% A - -A = C
-	   C == X,
+       C == X,
        Goal = add_real_bis(Type,A,C,C))),	%% A - -C = C
-	!,
-	call_priority(Goal,2).
+    !,
+    call_priority(Goal,2).
 minus_real_2_args_equal(_,_,_,_,1).
 
 
@@ -9401,6 +9542,8 @@ minus_real_inst(Type,0.0,B,C,Continue) ?- !,
         op_real(Type,B,C)
     ;   % C <> -0.0
         mreal:dvar_remove_element(C,-0.0),
+        op_real(Type,B,C)).
+/*
         (not_unify(B,0.0) ->
             op_real(Type,B,C)
         ;   (is_fzero(B) ->
@@ -9418,7 +9561,7 @@ minus_real_inst(Type,0.0,B,C,Continue) ?- !,
                         ;   Var = B),
                         isZero(as(Var,Type)) #= as(Bool,bool),
                         Continue = 1))))).
-
+*/
 minus_real_inst(Type,-0.0,B,C,_) ?- !,
     % Type <> real
     op_real(Type,B,C).
@@ -10355,32 +10498,50 @@ mult_real_bis(Type,A,B,C) :-
     propagate_float_int_bin_op(Type,A,B,C),
     clean_inf_args_from_res(Type,C,[A,B]),
     clear_Goals_mult_real(Type,A,B,C),
-    check_zero_mult_real(Type,A,B,C),
-    mult_real_sign(Type,A,B,C),
-    mult_real_inst(Type,A,B,C,Continue),
-    (var(Continue) ->
-        true
-    ;   mult_real_2_args_equal(Type,A,B,C,Continue1),
-        % PMO si les 3 args sont des float_int entre -2^53 et 2^53 on peut
-        % deleguer le calcul aux entiers
-        check_launch_mult_int(Type,A,B,C,Continue1,Continue2),
-        (var(Continue2) ->
+    ((Type == real,
+      member((Susp,mult_real1(real,AA,BB,CC)),LSusp),
+      CC == C,
+      (A == BB ->
+          exists_diff_Rel(B,AA),
+          Z = A
+      ;   (A == AA ->
+              exists_diff_Rel(B,BB),
+              Z =  A
+          ;   B == BB,
+              exists_diff_Rel(A,AA),
+              Z = B)))
+    ->
+        % cas manquant
+        call(spy_here)@eclipse,
+        kill_suspension(Susp),
+        protected_unify(C,0.0),
+        protected_unify(Z,0.0)
+    ;   check_zero_mult_real(Type,A,B,C),
+        mult_real_sign(Type,A,B,C),
+        mult_real_inst(Type,A,B,C,Continue),
+        (var(Continue) ->
             true
-        ;   check_mult_real_rel(Type,A,B,C),
-            mult_real_rec(Type,A,B,C),
-            mult_real_ineqs(Type,A,B,C),
-            mult_real_inst(Type,A,B,C,Continue3),
-            (var(Continue3) ->
+        ;   mult_real_2_args_equal(Type,A,B,C,Continue1),
+            % PMO si les 3 args sont des float_int entre -2^53 et 2^53 on peut
+            % deleguer le calcul aux entiers
+            check_launch_mult_int(Type,A,B,C,Continue1,Continue2),
+            (var(Continue2) ->
                 true
-            ;   check_2box(Type,[A,B,C]),
-                set_prio_inst([A,B,C],4,5,Prio0),
-                ((exists_congr(A,_,_),
-                  exists_congr(B,_,_))
-                ->
-                    Prio is Prio0 - 1
-                ;   Prio = Prio0),
-                NewGoal = mult_real1(Type,A,B,C),
-                my_suspend(NewGoal,Prio,(A,B,C) -> suspend:constrained)))).
+            ;   check_mult_real_rel(Type,A,B,C),
+                mult_real_rec(Type,A,B,C),
+                mult_real_ineqs(Type,A,B,C),
+                mult_real_inst(Type,A,B,C,Continue3),
+                (var(Continue3) ->
+                    true
+                ;   check_2box(Type,[A,B,C]),
+                    set_prio_inst([A,B,C],4,5,Prio0),
+                    ((exists_congr(A,_,_),
+                      exists_congr(B,_,_))
+                    ->
+                        Prio is Prio0 - 1
+                    ;   Prio = Prio0),
+                    NewGoal = mult_real1(Type,A,B,C),
+                    my_suspend(NewGoal,Prio,(A,B,C) -> suspend:constrained))))).
 
 
 check_mult_real_rel(Type,A,B,C) :-
@@ -13431,242 +13592,158 @@ div_real_float_intervals1(Type,ValInter1,ValInter2,L,EndL) :-
 
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% 							A/B = C
+%%  real_int: A div B = Q, R = A - B*Q
+%%  définition SMT-LIB de div/mod
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%			
-idiv_mod_real(A,B,Q,R) :-
-    % version integrale de mod_real
+
+idiv_mod_real(A,B,Q,R) :- !,
+    % version integrale de div/mod_real
     % pour la simulation des entiers non bornes par des reels
     get_priority(P),
     set_priority(1),
-    save_cstr_suspensions((A,B)),
-    get_saved_cstr_suspensions(LSusp),
-    ((member((Susp,check_divides_real(AA,BB,QQ,_,RR)),LSusp),
-      (B == BB ->
-          (A == AA;
-           Q == QQ,
-           R == RR)
-      ;    A == AA,
-           Q == QQ,
-           R == RR,
-           (not_zero(Q) ->
-               true
-           ;   exists_diff_Rel(B,BB),
-               ZQ = 1)))
-    ->
-        (nonvar(ZQ) ->
-            protected_unify(Q,0.0)
-        ;   % Fact
-            protected_unify(A,AA),
-            protected_unify(B,BB),
-            protected_unify(Q,QQ),
-            protected_unify(R,RR))
-    ;   set_lazy_domain(real,A),
-        set_lazy_domain(real,B),
-        set_lazy_domain(real,Q),
-        set_lazy_domain(real,BQ),
-        set_lazy_domain(real,R),
-        launch_float_int_number(A),
-        launch_float_int_number(B),
-        launch_float_int_number(Q),
-        launch_float_int_number(BQ),
-        launch_float_int_number(R),
-        ensure_not_NaN([A,B,Q,BQ,R]),
-        diff_real(real,B,0.0),
-        % R positif
-        mreal:dvar_remove_smaller(R,0.0),
-        % abs(R) est borné strictement par B en valeur absolue
-        as(R,real) $< abs(as(B,real)),
-
-        % cas à gérer explicitement pour éviter que le labelling
-        % parte sur Q sans les considérer
-        chk_nan(as(A,real) $= as(0.0,real),
-                (as(Q,real) $= as(0.0,real)) and 
-                (as(R,real) $= as(0.0,real)),
-                chk_nan(abs(as(B,real)) $= as(1.0,real),
-                        (abs(as(A,real)) $= abs(as(Q,real))) and
-                        (as(R,real) $= as(0.0,real)),
-                        chk_nan(as(R,real) $= as(0.0,real),
-                                as(BQ,real) $= as(A,real),
-                                as(A,real) $\= as(0.0,real)))),
-        % R = A-BQ, mais pas de lien direct sur A et B ?
-        mult_real(real,B,Q,BQ),
-        minus_real(real,A,BQ,R),
-        % on garde une trace de idiv_mod_real
-        % qui teste la divisibilite
-        % et propage d'autres réductions
-        check_divides_real(A,B,Q,BQ,R)),
+    set_lazy_domain(real,A),
+    set_lazy_domain(real,B),
+    set_lazy_domain(real,Q),
+    set_lazy_domain(real,BQ),
+    set_lazy_domain(real,R),
+    launch_float_int_number(A),
+    launch_float_int_number(B),
+    launch_float_int_number(Q),
+    launch_float_int_number(BQ),
+    launch_float_int_number(R),
+    ensure_not_NaN([A,B,Q,BQ,R]),
+    % 0.0 <= R <= abs(B)-1.0
+    launch_geq_real(real,R,0.0),
+    abs_val_real(real,B,AbsB),
+    launch_gt_real(real,AbsB,R),
+    % A = BQ + R
+    mult_real(real,B,Q,BQ),
+    add_real(real,BQ,R,A),
+    % cas à gérer explicitement pour forcer
+    % les signes de A et B 
+    chk_nan(as(A,real) $= as(0.0,real),
+            (as(Q,real) $= as(0.0,real)) and 
+            (as(R,real) $= as(0.0,real)),
+            chk_nan(as(A,real) $> as(0.0,real),
+                    chk_nan(as(B,real) $> as(0.0,real),
+                            as(Q,real) $>= as(0.0,real),
+                            as(Q,real) $=< as(0.0,real)),
+                    chk_nan(as(B,real) $> as(0.0,real),
+                            as(Q,real) $=< as(0.0,real),
+                            as(Q,real) $>= as(0.0,real)))),
+    check_idiv_mod_real(A,B,Q,BQ,R),
     set_priority(P),
-    wake_if_other_scheduled(P).  
-    
+    wake_if_other_scheduled(P).
 
-check_divides_real(A,A,Q,BQ,R) ?- !,
+check_idiv_mod_real(A,A,Q,BQ,R) ?- !,
     protected_unify(Q,1.0),
     protected_unify(BQ,A),
     protected_unify(R,0.0).
-check_divides_real(A,B,Q,BQ,A) ?- !,
+check_idiv_mod_real(A,B,Q,BQ,A) ?- !,
     protected_unify(Q,0.0),
     protected_unify(BQ,0.0).
-check_divides_real(A,B,Q,A,R) ?- !,
+check_idiv_mod_real(A,B,Q,A,R) ?- !,
     protected_unify(R,0.0).
-check_divides_real(0.0,B,Q,BQ,R) ?- !,
+check_idiv_mod_real(0.0,B,Q,BQ,R) ?- !,
     protected_unify(Q,0.0),
     protected_unify(BQ,0.0),
     protected_unify(R,0.0).
-check_divides_real(A,1.0,Q,BQ,R) ?- !,
+check_idiv_mod_real(A,1.0,Q,BQ,R) ?- !,
     protected_unify(Q,A),
     protected_unify(BQ,A),
     protected_unify(R,0.0).
-check_divides_real(A,-1.0,Q,BQ,R) ?- !,
+check_idiv_mod_real(A,-1.0,Q,BQ,R) ?- !,
     op_real(real,A,Q),
     protected_unify(BQ,A),
     protected_unify(R,0.0).
-check_divides_real(A,B,Q,BQ,0.0) ?- !,
+check_idiv_mod_real(A,B,Q,BQ,0.0) ?- !,
     protected_unify(A,BQ).
-check_divides_real(A,B,Q,0.0,R) ?- !,
+check_idiv_mod_real(A,B,Q,0.0,R) ?- !,
     protected_unify(Q,0.0),
     protected_unify(A,R).
-check_divides_real(X,Y,Q,YQ,R) :-
-    check_rbox_rat(X,RX),
-    check_rbox_rat(Y,RY),
-    !,
-    (RY > 0 ->
-        RQ is floor(RX/RY)
-    ;   RQ is ceiling(RX/RY)),
-    launch_box_rat(Q,RQ),
-    % RR is RX - (RY*RQ),
-    safe_mult_rat(RY,RQ,RYQ),
-    launch_box_rat(YQ,RYQ),
-    safe_minus_rat(RX,RYQ,RR),
-    launch_box_rat(R,RR).
-
-check_divides_real(X,Y,Q,YQ,R) :-
+check_idiv_mod_real(X,Y,Q,YQ,R) :-
+    (number(X);check_rbox_rat(X,RX)),
+    (number(Y);check_rbox_rat(Y,RY)),
+    !.
+check_idiv_mod_real(X,Y,Q,YQ,R) :-
     get_priority(P),
     set_priority(1),
-    (exists_abs_op(real,X,AOXs) ->
-        (exists_abs_op(real,Y,AOYs) ->
-            Vars = (AOXs,AOYs)
-        ;   Vars = (Y,AOXs))
-    ;   (exists_abs_op(real,Y,AOYs) ->
-            Vars = (X,AOYs)
-        ;   Vars = (X,Y))),
-    save_cstr_suspensions(Vars),
+    save_cstr_suspensions((X,Y,Q,R)),
     get_saved_cstr_suspensions(LSusp),
-    
-    (not_zero(Q) ->
-        mreal:dvar_remove_element(X,0.0)
-    ;   true),
-    (not_zero(R) ->
+
+    ((not_zero(Q);
+      not_zero(R))
+    ->
         mreal:dvar_remove_element(X,0.0)
     ;   true),
- 
-    congr_mult_inverse(real,YQ,Y,Q),
-    congr_mult_inverse(real,YQ,Q,Y),
-    
-    (same_abs(real,X,Y,LSusp,_,_) ->
-        abs_val_real(real,Q,1.0),
-        protected_unify(R,0.0)
-    ;   true),
     % factorisation
-    ((member((Susp,check_divides_real(XX,YY,QQ,YYQQ,RR)),LSusp),
+    ((member((Susp,check_idiv_mod_real(XX,YY,QQ,YYQQ,RR)),LSusp),
       (YY == Y ->
-          once (XX == X; % Fact
-                QQ == Q,
-                RR == R),
-                % X = YQ + R et XX = YQ + R -> Fact
+          XX == X,
           Fact = 1
       ;   XX == X,
-          QQ == Q,
-          RR == R,
-          % X = YQ + R et X = YYQ + R -> YQ = YYQ 
-          (exists_diff_Rel(YY,Y) ->
-              % Y <> YY donc Q = 0 et R = X
-              % et abs(X) < abs(Y) et abs(X) < abs(YY)
-              DiffY = 1
-          ;   true),
-          (not_zero(Q) ->
-              % YQ = YYQ
-              NZQ =  1
-          ;   true),
-          (nonvar(DiffY);
-           nonvar(NZQ))))
+          is_abs_real(real,Y,OY),
+          OY == YY,
+          % abs(YY) = Y
+          % R = X - Y*Q et RR = X - abs(Y)*QQ
+          % donc R = RR
+          Goal = protected_unify(R,RR)))
     ->
-        kill_suspension(Susp),
         (nonvar(Fact) ->
-            % on continue
-            protected_unify(X,XX),
-            protected_unify(Y,YY),
+            Stop = 1,
             protected_unify(Q,QQ),
             protected_unify(YQ,YYQQ),
             protected_unify(R,RR)
-        ;   (nonvar(DiffY) ->
-                Stop = 1,
-                protected_unify(Q,0.0),
-                protected_unify(YQ,0.0),
-                protected_unify(YYQQ,0.0),
-                protected_unify(X,R),
-                abs_val_real(real,X,AX),
-                abs_val_real(real,Y,AY),
-                abs_val_real(real,YY,AYY),
-                gt_real(real,AY,AX),
-                gt_real(real,AYY,AX)
-            ;   nonvar(NZQ),
-                % X = XX, Q = QQ, R = RR, Q <> 0
-                % X = YQ + R et X = YYQ + R
-                % donc YQ == YYQ et Y == YY
-                Stop = 1,
-                protected_unify(Y,YY),
-                protected_unify(YQ,YYQ)))
+        ;   call_priority(Goal,2))
     ;   true),
     % X et/ou Y variable
-    (divides_real_vars(Y,X,[]) ->
+    ((var(Stop),
+      divides_real_vars(Y,X,[]))
+    ->
         % R = 0 et X = YQ
         protected_unify(R,0.0),
         protected_unify(X,YQ),
         Stop = 1
     ;   true),
     (var(Stop) ->
-        % congruence
-        ((member((_,check_divides_real(XX,YY,QQ,_,RR)),LSusp),
-          once (YY == Y,
-                OO = XX,
-                O = X;
-                XX == X,
-                OO = YY,
-                O = Y),
-          
-          (exists_diff_Rel(QQ,Q);
-           exists_diff_Rel(RR,R)))
-        ->
-            launch_diff_real(real,OO,O)
-        ;   true),
-        % matching d'autres div_mod avec des op entre arguments
-        % utile pour issue60 adacore et ses variantes
-        ((not_zero(X),
-          member_begin_end((_,check_divides_real(CX,CY,CQ,CYQ,CR)),
-                           LSusp,NLS,ELS,ELS),
-          % voire solve.pl
-          % Rel* = eq|op|abs, on beaucoup de cas ici
-          same_abs(real,X,CX,NLS,RelX,NNLS),
-          RelX == eq,
-          same_abs(real,Y,CY,NNLS,RelY,_),
-          RelY == op)
-        ->
-            % AUTRES CAS DE Rel* INUTILES
-            % X = CX et Y = -CY
-            % et on observe (prouvé par cvc5) Q = -CQ
-            % X-CX = 0 = YQ + Y*CQ + R-CR
-            % donc R = CR (ca tue l'issue60)
-            op_real(real,Q,CQ),
-            protected_unify(R,CR)
-        ;   true),
+        % contre apposée congruence
+        % X div Y = Q et X div YY = QQ et QQ <> Q => Y <> YY
+        % X mod Y = R et X mod YY = RR et RR <> R => Y <> YY
+        % X div Y = Q et XX div Y = QQ et QQ <> Q => X <> XX
+        % X mod Y = R et XX mod Y = RR et RR <> R => X <> XX
+
+        (foreach((_,G),LSusp),
+         param(X,Y,Q,R) do
+            ((G = check_idiv_mod_real(NX,NY,NQ,_,NR),
+              (X == NX ->
+                  (exists_diff_Rel(Q,NQ);
+                   exists_diff_Rel(R,NR)),
+                  D1 = Y,
+                  D2 = NY
+              ;   Y == NY,
+                  (exists_diff_Rel(Q,NQ);
+                   exists_diff_Rel(R,NR)),
+                  D1 = X,
+                  D2 = NX))
+            ->
+                launch_diff_real(real,D1,D2)
+            ;   true)),
+
         (var(Stop) ->
-            my_suspend(check_divides_real(X,Y,Q,YQ,R),4,(X,Y,Q,YQ,R)->
+            my_suspend(check_idiv_mod_real(X,Y,Q,YQ,R),4,(X,Y,Q,YQ,R)->
                           suspend:constrained)
         ;   true)
     ;   true),
     set_priority(P),
     wake_if_other_scheduled(P).
 
+is_abs_real(real,AbsA,A) :-
+    get_saved_cstr_suspensions(LS),
+    member((_,abs_val_real1(real,CA,CAbsA)),LS),
+    AbsA == CAbsA,
+    protected_unify(A,CA),
+    !.
+
 divides_real_vars(X,X,_) ?- !.
 divides_real_vars(Y,X,Seen) :-
     ((exists_congr(Y,CY,MY),
@@ -13706,7 +13783,6 @@ divides_real_vars(Y,X,Seen) :-
         (var(A),divides_real_vars(Y,A,[S|Seen]);
          var(B),divides_real_vars(Y,B,[S|Seen]))).
 
-
 div_real(A,B,C) :-
     getval(float_eval,Type)@eclipse,
     div_real_type(Type,A,B,C).
@@ -16439,6 +16515,52 @@ check_is_e(Type,A) :-
     exp_val(Type,1.0,E),
     A == E.
 
+power_real(Type,A,N,B) :-
+    var(N),
+    !,
+    save_cstr_suspensions((A,N,B)),
+    ((Type == real,
+      is_float_int_number(A),
+      is_float_int_number(B),
+      get_sign(N,pos))
+    ->
+        (get_sign(B,SB) ->
+            (SB == neg ->
+                % A neg et N impair
+                launch_congr(N,1,2),
+                set_intervals(real,A,[-1.0Inf..0.0])
+            ;   % B pos
+                (get_sign(A,neg) ->
+                    % N pair
+                    launch_congr(N,0,2)
+                ;   true))
+        ;   ((get_sign(A,pos);
+              get_congr(N,0,2))
+            ->
+                % B pos
+                set_intervals(real,B,[0.0..1.0Inf])
+            ;   true))
+    ;   true),
+    get_saved_cstr_suspensions(LSusp),
+    ((member((S,power_real(Type,AA,NN,BB)),LSusp),
+      (A == AA ->
+          (N == NN ->
+              U1 = B,
+              U2 = BB
+          ;   Type == real,
+              B == BB,
+              U1 = N,
+              U2 = NN)
+      ;   Type == real,
+          not_zero(N),
+          N == NN,
+          B == BB,
+          U1 = A,
+          U2 = B))
+    ->
+        protected_unify(U1,U2)
+    ;   my_suspend(power_real(Type,A,N,B),0,N->suspend:inst)).
+       
 power_real(Type,A,0,B) ?- !,
     protected_unify(B,1.0).
 power_real(Type,A,1,B) ?- !,
@@ -16471,30 +16593,51 @@ power_real(Type,A,N,B) :-
 power_real(Type,A,N,B) :-
     integer(N),
     N >= 0,
-    %N =< 2^53,
-    mreal:set_typed_intervals(A,Type,[-1.0Inf..1.0Inf]),
-    mreal:set_typed_intervals(B,Type,[-1.0Inf..1.0Inf]),
-    ensure_not_NaN((A,B)),
-    (Type == real ->
-        true
-    ;   launch_float_number(A),
-        launch_float_number(B)),
-    (N == 0 ->
-        protected_unify(B = 1.0)
-    ;   (N == 1 ->
-            protected_unify(A = B)
-        ;   (is_float_int_number(A) ->
-                launch_float_int_number(B)
-            ;   true),
-            power_real_interval(Type,A,N,B),
-            (mod(N,2,0) ->
-                mreal:set_typed_intervals(B,Type,[0.0..1.0Inf])
-            ;   true),
-            power_real1(Type,A,N,B))).
+    %N =< 2^64,
+    (check_max_exponent(A,N) ->
+        mreal:set_typed_intervals(A,Type,[-1.0Inf..1.0Inf]),
+        mreal:set_typed_intervals(B,Type,[-1.0Inf..1.0Inf]),
+        ensure_not_NaN((A,B)),
+        ((Type == real,
+          is_float_int_number(A),
+          is_float_int_number(B),
+          get_sign(B,neg))
+        ->
+            % A neg et N impair
+            launch_congr(N,1,2),
+            set_intervals(real,A,[-1.0Inf..0.0])
+        ;   true),
+        (Type == real ->
+            true
+        ;   launch_float_number(A),
+            launch_float_number(B)),
+        (N == 0 ->
+            protected_unify(B = 1.0)
+        ;   (N == 1 ->
+                protected_unify(A = B)
+            ;   (is_float_int_number(A) ->
+                    launch_float_int_number(B)
+                ;   true),
+                power_real_interval(Type,A,N,B),
+                (mod(N,2,0) ->
+                    mreal:set_typed_intervals(B,Type,[0.0..1.0Inf])
+                ;   true),
+                power_real1(Type,A,N,B)))
+    ;   setval(unknown_if_unsat,1)@eclipse,
+        fail).
 
 power_real1(Type,A,N,B) :-
     get_priority(Prio),
     set_priority(1),
+    ((Type == real,
+      is_float_int_number(A),
+      is_float_int_number(B),
+      get_sign(B,neg))
+    ->
+        % A neg et N impair
+        launch_congr(N,1,2),
+        set_intervals(real,A,[-1.0Inf..0.0])
+    ;   true),
     (is_float_int_number(A) ->
         launch_float_int_number(B)
     ;   true),
@@ -16813,55 +16956,55 @@ check_other_odd_power_ineqs_from_res(Type,Pow,Val,ValPow) :-
 
 
 power_real_inst(Type,Val1,N,Val,Continue) :-
-	(float(Val1) ->
-		power_real_value(Type,Val1,N,L,H),
-		%% lance une rbox en mode real si L <> H
-		%% sinon L=H et instanciation de Val
-		set_interval_box(Val,L,H),
+    (float(Val1) ->
+        power_real_value(Type,Val1,N,L,H),
+        % lance une rbox en mode real si L <> H
+        % sinon L=H et instanciation de Val
+        set_interval_box(Val,L,H),
         (var(Val) ->
             check_rbox_cstrs(3,power_real(Type,Val1,N,Val))
         ;   true)
-	;	(float(Val) ->
-			% on verifie l atteignabilite
-			abs(Val,AVal),
-			check_reachable_from_pow0(Type,AVal,N,Unreachable,ALow,AHigh,_),
-			(nonvar(Unreachable) ->
-				Type == real,
-				(Val < 0.0 ->
-					Low is -AHigh,
-					High is -ALow,
-					mreal:set_typed_intervals(Val1,Type,[Low..High]),
-					launch_box(Val1),
+    ;   (float(Val) ->
+            % on verifie l atteignabilite
+            abs(Val,AVal),
+            check_reachable_from_pow0(Type,AVal,N,Unreachable,ALow,AHigh,_),
+            (nonvar(Unreachable) ->
+                Type == real,
+                (Val < 0.0 ->
+                    Low is -AHigh,
+                    High is -ALow,
+                    mreal:set_typed_intervals(Val1,Type,[Low..High]),
+                    launch_box(Val1),
                     (var(Val1) ->
                         check_rbox_cstrs(3,inv_power_real(Type,Val,N,
                                                           Val1))
                     ;   true)
-				;	Low = ALow,
-					High = AHigh,
-					(mod(N,2,1) ->
-						mreal:set_typed_intervals(Val1,Type,[Low..High]),
-						launch_box(Val1),
+                ;   Low = ALow,
+                    High = AHigh,
+                    (mod(N,2,1) ->
+                        mreal:set_typed_intervals(Val1,Type,[Low..High]),
+                        launch_box(Val1),
                         (var(Val1) ->
                             check_rbox_cstrs(3,inv_power_real(Type,Val,N,
                                                               Val1))
                         ;   true)
-					;	OpLow is norm_zero_op(Type,High),
-						OpHigh is norm_zero_op(Type,Low),
-						mreal:set_typed_intervals(Val1,Type,[OpLow..OpHigh,Low..High]),
-						mreal:dvar_range(Val1,L,H),
-						((L >= 0.0;
-						  H =< 0.0)
-						->
-							launch_box(Val1),
+                    ;   OpLow is norm_zero_op(Type,High),
+                        OpHigh is norm_zero_op(Type,Low),
+                        mreal:set_typed_intervals(Val1,Type,[OpLow..OpHigh,Low..High]),
+                        mreal:dvar_range(Val1,L,H),
+                        ((L >= 0.0;
+                          H =< 0.0)
+                        ->
+                            launch_box(Val1),
                             (var(Val1) ->
                                 check_rbox_cstrs(3,inv_power_real(Type,Val,N,
                                                                   Val1))
                             ;   true)
-						;	Continue = 1)))
-			;	inv_power_real_interval(Type,Val,N,LInter1,[]),
-				list_to_intervals(Type,LInter1,NLInter1),
-				mreal:set_typed_intervals(Val1,Type,NLInter1))
-		;	Continue = 1)).
+                        ;   Continue = 1)))
+            ;   inv_power_real_interval(Type,Val,N,LInter1,[]),
+                list_to_intervals(Type,LInter1,NLInter1),
+                mreal:set_typed_intervals(Val1,Type,NLInter1))
+        ;   Continue = 1)).
 
 power_real_rec(Type,Val1,N,Val) :-
     mreal:dvar_domain(Val1,Dom1),
@@ -16889,7 +17032,6 @@ power_real_rec(Type,Val1,N,Val,Dom1,Dom) :-
         true
     ;   power_real_rec(Type,Val1,N,Val,NewDom1,NewDom)).
 
-
 %% Typage et calcul de la projection directe
 %% Utilise aussi pour l'evaluation
 power_real_interval(A,2,B) ?- !,
@@ -16910,11 +17052,11 @@ power_real_interval_type(Type,A,N,B) :-
         ;   set_lazy_domain(Type,B))).
 
 power_real_interval(_,A,0,B) ?- !,
-    protected_unify(B = 1.0).
+    protected_unify(B;1.0).
 power_real_interval(Type,A,1,B) ?- !,
     % set_lazy_domain(Type,A),
     mreal:set_typed_intervals(A,Type,[-1.0Inf..1.0Inf]),
-    protected_unify(B = A).
+    protected_unify(B,A).
 power_real_interval(Type,A,N,B) :-
     N > 1,
     ((Type == real,
@@ -16994,12 +17136,33 @@ power_real_value(0.0,N,0.0,0.0) :- !.
 power_real_value(Val,N,L,H) :-
     pow_real_min_max(Val,N,L,H).
 
+pow_real_min_max(0.0,N,L,H) ?- !,
+    (N == 0 ->
+        L = 1.0,
+        H = 1.0
+    ;   L = 0.0,
+        H = 0.0).
+pow_real_min_max(1.0,N,L,H) ?- !,
+    L = 1.0,
+    H = 1.0.
+pow_real_min_max(-1.0,N,L,H) ?- !,
+    (N mod 2 =:= 0 ->
+        L = 1.0,
+        H = 1.0
+    ;   L = -1.0,
+        H = -1.0).
 pow_real_min_max(Val,N,L,H) :-
     rational(Val,RatVal),
     power_rat(RatVal,N,Rat),
     float_of_rat(real,rtn,Rat,L),
     float_of_rat(real,rtp,Rat,H).
 
+check_max_exponent(Var,N) :-
+    mreal:dvar_range(Var,L,H),
+    Abs is max(abs(L),abs(H)),
+    log2(Abs,LAbs),
+    ceiling(N * LAbs) < 10000.
+
 power_rat(RatVal,N,Rat) :-
     numerator(RatVal,Num),
     RNum is Num^integer(N),
@@ -17008,21 +17171,27 @@ power_rat(RatVal,N,Rat) :-
     Rat is rational(RNum)/rational(RDen).
 
 power_real_min(real,Val,N,L) :- !,
+    pow_real_min_max(Val,N,L,_).
+/*
     rational(Val,RatVal),
     power_rat(RatVal,N,Rat),
     float_of_rat(real,rtn,Rat,L).
+*/
 power_real_min(Type,Val,N,L) :-
     power_real_value(Type,Val,N,L,_).
 
 power_real_max(real,Val,N,H) :- !,
+    pow_real_min_max(Val,N,_,H).
+/*
     rational(Val,RatVal),
     power_rat(RatVal,N,Rat),
     float_of_rat(real,rtp,Rat,H).
+*/
 power_real_max(Type,Val,N,H) :-
     power_real_value(Type,Val,N,_,H).
 
 
-
+% ????
 inv_power_real_interval_list(Type,[],N,[]).
 inv_power_real_interval_list(Type,[I|L],N,NL) :-
     inv_power_real_interval(Type,I,N,NL,ENL),
@@ -17270,18 +17439,16 @@ choose_start_narrow_pow(Type,ValpInvN0,Delta,Val,N,OEnd,Start,End) :-
     ;   Start = Start0,
         End = OEnd).
 
-
-
-min_inv_power_real(Type,0.0,N,Min) :- !,
-    max_inv_power_real(Type,0.0,N,Max),
-    Min is -Max.
 min_inv_power_real(real,Val,N,Min) :- !,
-    check_reachable_from_pow0(Type,Val,N,Unreachable,Min0,_,HMin),
+    check_reachable_from_pow0(real,Val,N,Unreachable,Min0,_,HMin),
     (nonvar(Unreachable) ->
         Min = Min0
     ;   % en real HMin est le seul a atteindre Val (Err == 0)
         Min = HMin).
 % double ou simple
+min_inv_power_real(Type,0.0,N,Min) ?- !,
+    max_inv_power_real(Type,0.0,N,Max),
+    Min is -Max.
 min_inv_power_real(Type,Val,N,Min) :-
     check_reachable_from_pow0(Type,Val,N,Unreachable,Min0,Max0,HMin),
     (nonvar(Unreachable) ->
@@ -17398,6 +17565,7 @@ square_real(Type,A,B) :-
         check_no_float_error(Type,(A,B)),
         same_float_int_number_status(Type,A,B),
         square_real_interval(Type,A,B),
+            
         ((member(Susp,LS),
           (Goal = add_real1(real,X,Y,AA),
            FG = add_real;
@@ -19091,13 +19259,14 @@ abs_val_real_bis(Type,Val,Abs) :-
         (var(Continue1) ->
             true
         ;   ((Type == real,
-              is_float_int_number(A))
+              is_float_int_number(Val))
             ->
                 congr_abs_directe(Val,Abs,Stop),
                 (var(Stop) ->
                     congr_abs_inverse(Val,Abs,Stop)
                 ;   true)
             ;   true),
+            check_dist_abs_mult_div(Type,Val,Abs,Stop),
             (var(Stop) ->
                 % Propagation de Val vers Abs
                 abs_val_real_interval(Type,Val,Abs),
@@ -19111,6 +19280,27 @@ abs_val_real_bis(Type,Val,Abs) :-
                 check_before_susp_abs_val_real(Type,Val,Abs)
             ;   true))).
 
+check_dist_abs_mult_div(Type,Val,Abs,1) ?- !.
+check_dist_abs_mult_div(real,Val,Abs,Stop) ?- !,
+    get_saved_cstr_suspensions(LS),
+    ((member((S,G),LS),
+      (G = mult_real1(real,A,B,VVal); % abs(A*B) = abs(A)*abs(B)
+       G = div_real1(real,A,B,VVal); % abs(A/B) = abs(A)/abs(B)
+       G = truncate_bis(real,A,VVal)), % vers 0, abs(truncate(A)) = truncate(abs(A))
+      VVal == Val)
+    ->
+        % Pas de Stop, on sature
+        functor(G,FG,Ar),
+        (Ar == 4 ->
+            % mult|div
+            NG0 =.. [FG,real,AbsA,AbsB,Abs],
+            NG = (abs_val_real_bis(real,B,AbsB),NG0)
+        ;   NG =.. [FG,real,AbsA,Abs]),
+        call(spy_here)@eclipse,
+        call_priority((abs_val_real1(Type,A,AbsA),NG),2)
+    ;   true).
+check_dist_abs_mult_div(Type,Val,Abs,_).
+
 abs_val_real_inst(Type,Val,Abs,Continue) :-
     (number(Val) ->
         Abs0 is abs(Val),
@@ -19688,14 +19878,22 @@ fp_eq1(Type,A,B) :-
                 kill_suspension(S),
                 protected_unify(Bool1,1)
             ;   true),
-            mreal:get_intervals(A,IA),
-            mreal:get_intervals(B,IB),
-            intervals_intersection(Type,IA,IB,Inter),
-            % Inter peut etre vide si zeros
-            NInter = [-0.0 .. 0.0|Inter],
-            set_typed_intervals(A,Type,NInter),
-            set_typed_intervals(B,Type,NInter),
+            ((is_op_real(Type,A,BB),
+              B == BB)
+            ->
+                % NEW
+                Zero = 1,
+                % en real on obtient 0.0
+                NInter = [-0.0 .. 0.0]
+            ;   mreal:get_intervals(A,IA),
+                mreal:get_intervals(B,IB),
+                intervals_intersection(Type,IA,IB,Inter),
+                % Inter peut etre vide si zeros
+                NInter = [-0.0 .. 0.0|Inter]),
+            set_intervals(Type,A,NInter),
+            set_intervals(Type,B,NInter),
             ((A == B;
+              nonvar(Zero),
               number(A);
               number(B))
             ->
@@ -19922,12 +20120,12 @@ check_geq_real(_,_,_,1,_) ?- !.
 check_geq_real(Type,A,B,_,Suspend) :-
     (A == B ->
         true
-    ;   geq_real_number_box(Type,A,B,Continue),
-        (var(Continue) ->
+    ;   mreal:mindomain(A,MinA),
+        mreal:maxdomain(B,MaxB),
+        (MinA >= MaxB ->
             true
-        ;   mreal:mindomain(A,MinA),
-            mreal:maxdomain(B,MaxB),
-            (MinA >= MaxB ->
+        ;   geq_real_number_box(Type,A,B,Continue),
+            (var(Continue) ->
                 true
             ;   Suspend = 1))).
 
@@ -20281,17 +20479,17 @@ gt_real_int_ineq(A,B).
 check_gt_real(_,_,_,1,_) ?- !.
 check_gt_real(Type,A,B,_,Suspend) :-
     A \== B,
-    % En "real", on ne doit pas reduire trop le domaine
-    % d'un intervalle par rapport a une valeur
-    % sinon, l'ordre des contraintes influe sur le resultat
-    % On doit donc faire comme pour geq_real, mais en conservant
-    % le gt_real quand on s'est freine.
-    gt_real_number_box(Type,A,B,Continue),
-    (var(Continue) ->
+    mreal:mindomain(A,MinA),
+    mreal:maxdomain(B,MaxB),
+    (MinA > MaxB ->
         true
-    ;   mreal:mindomain(A,MinA),
-        mreal:maxdomain(B,MaxB),
-        (MinA > MaxB ->
+    ;   % En "real", on ne doit pas reduire trop le domaine
+        % d'un intervalle par rapport a une valeur
+        % sinon, l'ordre des contraintes influe sur le resultat
+        % On doit donc faire comme pour geq_real, mais en conservant
+        % le gt_real quand on s'est freine.
+        gt_real_number_box(Type,A,B,Continue),
+        (var(Continue) ->
             true
         ;   Suspend = 1)).
 
diff --git a/Src/COLIBRI/smt_import.pl b/Src/COLIBRI/smt_import.pl
index 1df6acae2f76055a806f4d436c2988af3a1e5e5c..51496686c66e1dd460c1d86e610dac4981a715e4 100644
--- a/Src/COLIBRI/smt_import.pl
+++ b/Src/COLIBRI/smt_import.pl
@@ -9,9 +9,41 @@
 
 % pour indiquer une abstaction de forall/exists
 :- setval(quantifier,0).
+:- (current_array(quant_abs,_) ->
+       true
+   ;   local reference(quant_abs)).
+:- export quant_abs/1.
+quant_abs(Expr) :-
+    setval(quantifier,1),
+    (var(Expr) ->
+        Var = Expr,
+        protected_set_var_name(Var,"ColQuant"),
+        int_vars(bool,Var)
+    ;   (number(Expr) ->
+            (occurs(Expr,(0,1)) ->
+                Var = Expr
+            ;   exit_block(syntax))
+        ;   Var = 1,
+            call(as(Var,bool) #= as(Expr,bool)))),
+    getval(quant_abs,TL),
+    (TL == 0 ->
+        NTL = []
+    ;   NTL = TL),
+    NewTL = [Var|NTL],
+    setval(quant_abs,NewTL).
+:- export get_quant_abs/1.
+get_quant_abs(NTL) :-
+    getval(quant_abs,TL),
+    (TL == 0 ->
+        NTL = []
+    ;   NTL = TL).
+:- export check_quant_abs/0.
+check_quant_abs :-
+    get_quant_abs(TL),
+    not occurs(0,TL).
+            
 % pour activer le scrambler en mode test
 :- setval(scrambler,0)@eclipse.
-
 :- set_stream_property(error,flush,end_of_line).
 
 :- include([new_parser_builtins]).
@@ -39,6 +71,8 @@ parse_smtlib_file(File,Res) :-
     % defaut pour la simulation des entiers non bornes
     getval(def_real_for_int,RI),
     setval(real_for_int,RI)@eclipse,
+    setval(quantifier,0),
+    setval(unknown_if_unsat,0)@eclipse,
     get_flag(hostarch,ARCH),
     ((ARCH == "i386_nt";
       ARCH == "x86_64_nt")
@@ -106,6 +140,12 @@ dolmen_to_colibri_term(error(String),_) ?- !,
     concat_string(["(error \"",NString,"\")"],Error),
     writeln(error,Error),
     exit_block(syntax).
+dolmen_to_colibri_term(get_info(String),Term) ?- !,
+    (getval(no_dolmen_warning,1)@eclipse ->
+        true
+    ;   concat_string(["(unsupported (get-info \"",String,"\"))"],Error),
+        writeln(error,Error)),
+    Term = 'set-info'("Info","").
 dolmen_to_colibri_term(warn(String),Term) ?- !,
     (getval(no_dolmen_warning,1)@eclipse ->
         true
@@ -693,8 +733,19 @@ check_sat0 :-
     ;   writeln(output,Diag)).
 
 check_sat_vars :-
-%    not not check_sat_vars0.
-    check_sat_vars0.
+    (getval(quantifier,1) ->
+        % pas fiable ?
+        (check_quant_abs ->
+            % sat fiable pour l'instant
+            setval(unknown_quantifier_abstraction,0)@eclipse,
+            check_sat_vars0
+        ;   setval(diag_code,(unknown,2))@eclipse)
+    ;  (getval(smt_status,unsat)@eclipse ->
+           writeln(error,wrong_sat),
+           setval(diag_code,(unknown,2))@eclipse
+       ;   setval(unknown_quantifier_abstraction,0)@eclipse,
+           check_sat_vars0)).
+
 check_sat_vars0 :-
     init_real_cst,
     init_seen_expr,
@@ -709,25 +760,27 @@ check_sat_vars0 :-
             CV = V
         ;   CV = as(V,Type))),
     (foreach(Goal,Goals) do
-        (fail,check_only_real_box_rat(Goal) ->
-            % BUG rationnels !!
-            true
-        ;   block((call(Goal) ->
-                      true
-                  ;   spy_here,
-                      call(Goal)),
-                  Tag,
-                  (exit_block(Tag),
-                   spy_here,
-                   call(Goal))))),
+        block((call(Goal) ->
+                  true
+              ;   spy_here,
+                  call(Goal)),
+              Tag,
+              (exit_block(Tag),
+               spy_here,
+               call(Goal)))),
     setval(diag_code,(sat,1))@eclipse,
 
     delayed_goals(NGoals),
-    term_variables(NGoals,GoalsVars),
-    (foreach(GV,GoalsVars),
-     foreach((GV,0,[]),NGoalsVars) do
-        trans_no_rat(GV)),
-    once solve_cstrs_list([NGoalsVars]),
+    (NGoals == [] ->
+        true
+    ;   %writeln(output,NGoals),
+        %halt,
+        term_variables(NGoals,GoalsVars),
+        (foreach(GV,GoalsVars),
+         foreach((GV,0,[]),NGoalsVars) do
+            trans_no_rat(GV)),
+        seed(0),
+        once solve_cstrs_list([NGoalsVars])),
 
     % pas de residue,sinon wrong_sat
     suspensions(LSusp),
@@ -1637,7 +1690,7 @@ defined_smt_func(F/Ar,IArgs,Type,IExpr) :-
             ->
                 NIArg = IArg
             ;   NIArg = as(IArg,IArgType)),
-            call(spy_here)@eclipse,
+            % call(spy_here)@eclipse,
             (nonvar(IArgType) ->
                 findall(Sort,cgiveInstanceAndPath(sort(_),IArgType,
                                                   sort(Sort),_),LSs),
@@ -1667,6 +1720,8 @@ restore_seen_expr(SeenExpr) :-
     setval(seen_expr,SeenExpr).
 
 add_seen_expr(let(_,_),_,_) ?- !.
+add_seen_expr(exists(_,_),_,_) ?- !.
+add_seen_expr(forall(_,_),_,_) ?- !.
 add_seen_expr(Expr,IExpr,Type) :-
     getval(in_let,0),
     compound(Expr),
@@ -1683,6 +1738,8 @@ add_seen_expr(Expr,IExpr,Type).
 
 check_seen_expr(let(_,_),_,_) ?- !,
     fail.
+check_seen_expr(new_quantified_var(_,_),_,_) ?- !,
+    fail.
 check_seen_expr(forall(_,_),_,_) ?- !,
     fail.
 check_seen_expr(exists(_,_),_,_) ?- !,
@@ -1904,12 +1961,15 @@ smt_interp(Expr,IExpr,Type) :-
         add_seen_expr(Expr,IExpr,Type)).
 
 :- setval(logic,"ALL")@eclipse.
+:- setval(in_assert,0).
 % INTERPRETATION
 smt_interp0(exit,true,bool) :- !.
 smt_interp0('set-logic'(SLogic),true,bool) :- !,
     setval(logic,SLogic)@eclipse.
 
-smt_interp0('get-info'(Key),get_info(Key),bool) :- !.
+smt_interp0('get-info'(Key),true,bool) :- 
+    call(spy_here)@eclipse,
+    !.
 smt_interp0('set-info'(K,S),true,bool) :- !,
     (K == ':status' ->
         setval(smt_status,S)@eclipse
@@ -1948,6 +2008,7 @@ smt_interp0(set_default_int_bounds(L,H),set_default_int_bounds(Low,High),bool)
     ;   unsupported_error("set_default_int_bounds needs min/max integer values")).
     
 smt_interp0(assert(A0),NewDecl,bool) :- !,
+    setval(in_assert,true),
     getval(decl,OD),
     setval(decl,End-End),
     reset_let_vars,
@@ -2005,7 +2066,8 @@ smt_interp0(assert(A0),NewDecl,bool) :- !,
             ;   NDecl = Decl))),
     reset_let_vars,
     remove_true_decl(NDecl,NewDecl),
-    setval(decl,OD).
+    setval(decl,OD),
+    setval(in_assert,0).
 smt_interp0(array_def(Var,Def),array_def(IVar,IDef),bool) :- !,
     smt_interp(Var,IVar,Type),
     smt_interp(Def,IDef,Type).
@@ -2203,7 +2265,10 @@ smt_interp0(let(Pairs,Expr),IExprLet,Type) :- !,
             ;   OK = IK),
             smt_interp0(EV,IEV,TypeV),
             check_eval(TypeV,IEV,Res),
-            (ground(Res) ->
+            ((ground(Res),
+              remove_upper_as(Res,Res0,_),
+              Res0 \= new_quantified_var(_,_))
+            ->
                 NV = Res,
                 OT = IT
             ;   OT = [(NV,TypeV,IEV)|IT])),
@@ -2218,14 +2283,27 @@ smt_interp0(let(Pairs,Expr),IExprLet,Type) :- !,
         (foreach((V,ONV,OTypeV),Known) do
             add_let_var(V,NV,TypeV))),
     setval(in_let,OIL).
-smt_interp0(forall(L,E),Res,bool) :- !,
+
+% forall Vars P = not(exists Vars not(P))
+smt_interp0(forall(Vars,P),Res,bool) :- !,
     %unsupported_error(forall).
     % Abstraction, plus de sat fiable
-    new_quantifier_abstraction(Res).
-smt_interp0(exists(L,E),Res,bool) :- !,
+    % new_quantifier_abstraction(Res).
+    call(spy_here)@eclipse,
+    smt_interp(exists(Vars,not(P)),NotRes,bool),
+    Res = neg(NotRes).
+smt_interp0(exists(Vars,P),Res,bool) :- !,
     %unsupported_error(exists).
     % Abstraction, plus de sat fiable
-    new_quantifier_abstraction(Res).
+    %new_quantifier_abstraction(Res).
+    call(spy_here)@eclipse,
+    (foreach((V,Type),Vars),
+     foreach((V,new_quantified_var(QV,Type)),Pairs) do
+        true),
+    smt_interp(let(Pairs,P),Res0,bool),
+    % pas fiable si R0 false
+    Res = as(quant_abs(Res0),bool).
+
 smt_interp0(as(Id,Sort),Res,Type) :- !,
     get_type_from_sort(Sort,Type,_),
     smt_interp(Id,IId,Type),
@@ -2242,7 +2320,6 @@ smt_interp0(A,IA,Type) :-
             (integer(A) ->
                 rational(A,RA),
                 term_string(RA,SRA),
-%                IA = realString(SRA)
                 IA = as(realString(SRA),real_int)
             ;   float(A), %??
                 IA = as(A,real))
@@ -2254,7 +2331,6 @@ smt_interp0(A,IA,Type) :-
                 Type = real_int,
                 rational(A,RA),
                 term_string(RA,SRA),
-%                IA = realString(SRA)
                 IA = as(realString(SRA),real_int)
             ;   Type = int,
                 IA = A)
@@ -2297,11 +2373,16 @@ smt_interp0(Atom,IAtom,Type) :-
     ;   IAtom = Val).
 smt_interp0(not(A),NegIA,bool) :- !,
     ((nonvar(A),
-      A = let(Pairs,Expr))
+      remove_upper_as(A,AA,_),
+      (AA = let(Pairs,Expr),
+       NA = let(Pairs,not(Expr));
+       AA = forall(Pairs,Expr),
+       NA = exists(Pairs,not(Expr))))
     ->
-        smt_interp(let(Pairs,not(Expr)),NegIA,bool)
+        smt_interp(NA,NegIA,bool)
     ;   ((nonvar(A),
-          A = not(B))
+          remove_upper_as(A,AA,_),
+          AA = not(B))
         ->
             smt_interp(B,NegIA,bool)
         ;   ((nonvar(A),
@@ -3168,12 +3249,32 @@ smt_interp0(T,IT,Type) :-
             % instanciation/liaison parametres
             defined_smt_func(F/Ar,IArgs,Type,IT))),
     !.
+smt_interp0(new_quantified_var(V,Type),IT,IType) ?- !,
+    IT = as(new_quantified_var(V,IType),IType),
+    get_type_from_sort(Type,IType,_).
+
 smt_interp0(T,IT,Type) :-
     compound(T),
     functor(T,F,Ar),
     concat_string(["Unknown function:",F,/,Ar],Err),
     unsupported_error(Err).
 
+/*
+new_quantified_var(Type,Res) :-
+    % On cree une variable
+    get_decl_type_from_sort(Type,NVar,Decl,IType),
+    set_var_name(NVar,"ColQuantV"),
+    protected_get_var_name(NVar,VS),
+    atom_string(Id,VS),
+    add_binding(Id,IType,NVar),
+    (getval(decl,ODecl-End) ->
+        true
+    ;   setval(decl,End-End),
+        ODecl = End),
+    End = (Decl,NEnd),
+    setval(decl,ODecl-NEnd),
+    Res = as(Id,Type).
+
 new_quantifier_abstraction(Res) :-
     setval(quantifier,1),
     % On cree une variable
@@ -3189,7 +3290,7 @@ new_quantifier_abstraction(Res) :-
     End = (Decl,NEnd),
     setval(decl,ODecl-NEnd),
     Res = as(NVar,bool).
-
+*/
 is_quantifier_abstraction(Var) :-
     var(Var),
     protected_get_var_name(Var,VS),
@@ -3198,6 +3299,8 @@ is_quantifier_abstraction(Var) :-
 % on garde les realString
 check_eval(Type,realString(Str),RE) ?- !,
     RE = as(realString(Str),Type).
+check_eval(Type,new_quantified_var(V,T),RE) ?- !,
+    RE = as(new_quantified_var(V,T),Type).
 % on traverse les as
 check_eval(_Type,as(E,Type),RE) ?- !,
     check_eval(Type,E,RE).
@@ -3717,7 +3820,7 @@ remove_true_decl((Beg,End),Decl) ?- !,
       Decl0 = as(1,bool))
     ->
         remove_true_decl(Beg,Decl)
-    ;   remove_true_decl(End,Decl1),
+    ;   remove_true_decl(Beg,Decl1),
         make_conj(Decl0,Decl1,Decl)).
 remove_true_decl(D,D).
 
diff --git a/Src/COLIBRI/solve.pl b/Src/COLIBRI/solve.pl
index 5904f11c12b2b6b9e09ebc0363a85b73b7370608..759b7a66a6ce6f39ee6855a8aa6a5a232818da61 100644
--- a/Src/COLIBRI/solve.pl
+++ b/Src/COLIBRI/solve.pl
@@ -158,6 +158,8 @@ trans_col(or_seq_reif(X,_,Y,Z),(X or Y) #= Z).
 % TODO : ajouter declaration type pour BV
 unfold_int_expr_block(E,D,C,T,R) :-
     get_priority(P),
+    use_norm_expr,
+%    no_norm_expr,
     call_priority(
                      block(once unfold_int_expr(E,D,C,T,R),
                            Tag,
@@ -170,6 +172,7 @@ unfold_int_expr_block(E,D,C,T,R) :-
     set_priority(P),
     wake.
 
+
 '#:'(L,I) :-
     (I == bool ->
         mfd:(L :: [0,1])
@@ -178,39 +181,8 @@ unfold_int_expr_block(E,D,C,T,R) :-
 '#='(L,R) :-
     unfold_int_expr_block(L #= R,0,C,bool,1),
     call(C).
-/*
-'#='(L,R) :-
-    (var(L) ->
-        get_variable_type(L,Type),
-        ((Type = array(_,_),
-          occurs(L,R))
-        ->
-            unfold_int_expr_block(L #= R,0,C,bool,1)
-        ;   unfold_int_expr_block(R,0,C,Type,L))
-    ;   (L = as(V,Type) ->
-            ((var(V),
-              Type = array(_,_),
-              occurs(V,R))
-            ->
-                unfold_int_expr_block(L #= R,0,C,bool,1)
-            ;   unfold_int_expr_block(R,0,C,Type,V))
-        ;   (var(R) ->
-                 get_variable_type(R,Type),
-                 ((Type = array(_,_),
-                   occurs(R,L))
-                 ->
-                     unfold_int_expr_block(L #= R,0,C,bool,1)
-                 ;   unfold_int_expr_block(L,0,C,Type,R))
-            ;   (R = as(V,Type) ->
-                    ((var(V),
-                      Type = array(_,_),
-                      occurs(V,R))
-                    ->
-                        unfold_int_expr_block(L #= R,0,C,bool,1)
-                    ;   unfold_int_expr_block(L,0,C,Type,V))
-                ;   unfold_int_expr_block(L #= R,0,C,bool,1))))),
-    call(C).
-*/% version specifique pour les definitions de tableaux
+
+% version specifique pour les definitions de tableaux
 array_def(Var,Def) :-
     (((var(Var),V = Var;
        Var = as(V,Type),var(V)),
@@ -428,7 +400,7 @@ set_int_type(sort(S),X) ?- !,
 set_int_type(rnd,X) ?- !,
     rnd_vars(X).
 set_int_type(Type,X) :-
-    call(spy_here)@eclipse,
+    % call(spy_here)@eclipse,
     write(error,"Type error for variable "),
     writeln(error,X:Type),
     exit_block(syntax).
@@ -449,7 +421,7 @@ add_typed_var(V,Type) :-
         (hash_get(Hash,VA,(_,Type0)) ->
             (Type == Type0 ->
                 true
-            ;   call(spy_here)@eclipse,
+            ;   % call(spy_here)@eclipse,
                 write(error,"Type error for variable "),
                 writeln(error,V:Type0),
                 exit_block(syntax))
@@ -474,13 +446,15 @@ get_variable_from_name(Name,Var) :-
 protected_get_var_name(V,Name) :-
     (var(V) ->
         get_var_name(V,Name)
-    ;   call(spy_here)@eclipse,
+    ;   % call(spy_here)@eclipse,
         fail,writeln(error,"Error: variable needed as first argument of get_var_name/2"),
         exit_block(syntax)).
 protected_set_var_name(V,Name) :-
     (var(V) ->
-        set_var_name(V,Name)
-    ;   call(spy_here)@eclipse,
+        (protected_get_var_name(V,Name0) ->
+            true
+        ;   set_var_name(V,Name))
+    ;   % call(spy_here)@eclipse,
         writeln(error,"Error: variable needed as first argument of set_var_name/2"),
         exit_block(syntax)).
 
@@ -498,7 +472,7 @@ check_int_var_type(V,Type) :-
     hash_get(Hash,VA,(_,Type0)),
     (compatible_types(Type,Type0) ->
         true
-    ;   call(spy_here)@eclipse,
+    ;   % call(spy_here)@eclipse,
         write(error,"Type error for variable "),
         writeln(error,V:Type0),
         exit_block(syntax)).
@@ -519,14 +493,14 @@ compatible_types(T1,T2) :-
 get_int_var_type(V,Type) :-
     getval(typed_vars,Hash),
     (Hash == 0 ->
-        call(spy_here)@eclipse,
+        % call(spy_here)@eclipse,
         writeln(error,"Type unknown for variable":X),
         exit_block(syntax)
     ;   get_variable_atom(V,VA),
         (hash_get(Hash,VA,(_,Type0)) ->
             (compatible_types(Type,Type0) ->
                 true
-            ;   call(spy_here)@eclipse,
+            ;   % call(spy_here)@eclipse,
                 write(error,"Type error for variable "),
                 writeln(error,VA:Type0),
                 exit_block(syntax))
@@ -536,7 +510,7 @@ get_int_var_type(V,Type) :-
               get_type(V,_))
             ->
                 true
-            ;   call(spy_here)@eclipse,
+            ;   % call(spy_here)@eclipse,
                 writeln(error,"Type unknown for variable":X),
                 exit_block(syntax)))).
 
@@ -756,18 +730,6 @@ power1(uint(N),D,A,P,B,UO) :-
     insert_dep_inst(dep(A,D,[UO])),
     insert_dep_inst(dep(B,D,[UO])).
 
-power_real0(Type,A,P,B) :-
-    set_lazy_domain(Type,A),
-    set_lazy_domain(int,P),
-    mfd:dvar_remove_smaller(P,0),
-    set_lazy_domain(Type,B),
-    (is_float_int_number(A) ->
-        launch_float_int_number(B)
-    ;   true),
-    (var(P) ->
-        my_suspend(power_real0(Type,A,P,B),0,P->suspend:inst)
-    ;   power_real(Type,A,P,B)).
-
 make_conj(true,C,NC) ?- !,
     NC = C.
 make_conj(C,true,NC) ?- !,
@@ -800,19 +762,30 @@ unfold_int_expr(X,_D,Cstr,Type,R) :-
       nonvar(Type),
       int_vars(Type,X))
     ->
-        blocked_unify(X = R)
-    ;   call(spy_here)@eclipse,
+        blocked_call(X = R)
+    ;   % call(spy_here)@eclipse,
         writeln(error,"Type unknown for variable":X),
         exit_block(syntax)),
     Cstr = true.
     %insert_dep_inst(inst_cstr(D,X)).
+unfold_int_expr(quant_abs(Let),D,Cstr,Type,R) ?- !,
+    Type = bool,
+    !,
+    unfold_int_expr(Let,D,Cstr0,Type,R),
+    % au début pour le nom ColQuantX
+    make_conj(quant_abs(R),Cstr0,Cstr).
+unfold_int_expr(new_quantified_var(R0,Type0),D,Cstr,Type,R) ?- !,
+%    call(spy_here)@eclipse,
+    Type = Type0,
+    unfold_int_expr(R0,D,Cstr,Type,R).
 unfold_int_expr(X,_,Cstr,Type,R) :-
     integer(X),!,
     (nonvar(Type) ->
         Cstr = true,
-        to_int(Type,X,R0),
-        blocked_unify(R,R0)
-    ;   % A typer plus tard
+%        to_int(Type,X,R0),
+%        blocked_unify(R,R0)
+        blocked_call(to_int(Type,X,R))
+     ;   % A typer plus tard
         Cstr = to_int(Type,X,R)).
 unfold_int_expr(as(EA,Type0),D,Cstr,Type,R) ?- !,
     Type = Type0,
@@ -884,8 +857,9 @@ unfold_int_expr(select(EA,EI), D, Cstr, Type, R) ?-
         let_int_vars(TI,I)),
     !,
     % les resultats de select sont eligibles
-    eval_select(TA,A,I,R0,Start,CES),
-    blocked_unify(R0,R),
+%    eval_select(TA,A,I,R0,Start,CES),
+%    blocked_unify(R0,R),
+    blocked_call(eval_select(TA,A,I,R,Start,CES)),
     make_conj(CI,CA,CIA),
     let_int_vars(Type,R),
 %    insert_dep_inst(dep(R,D,[I,Start])),
@@ -926,8 +900,8 @@ unfold_int_expr(bvand(Size,EA,EB), D, Cstr, Type, R) ?-
          ;   ((number(A),
                number(B))
              ->
-                 bvand(Size,A,B,R0),
-                 blocked_unify(R,R0),
+                 blocked_call(bvand(Size,A,B,R)),
+%                 blocked_unify(R,R0),
                  Cstr = CAB
              ;   set_int_type(Type,A),
                  set_int_type(Type,B),
@@ -950,8 +924,8 @@ unfold_int_expr(bvor(Size,EA,EB), D, Cstr, Type, R) ?-
     ((number(A),
       number(B))
     ->
-        bvor(Size,A,B,R0),
-        blocked_unify(R,R0),
+        blocked_call(bvor(Size,A,B,R)),
+%        blocked_unify(R,R0),
         Cstr = CAB
     ;   set_int_type(Type,A),
         set_int_type(Type,B),
@@ -976,8 +950,8 @@ unfold_int_expr(xorb(Size,EA,EB), D, Cstr, Type, R) ?-
     ((number(A),
       number(B))
     ->
-        bvxor(Size,A,B,R0),
-        blocked_unify(R,R0),
+        blocked_call(bvxor(Size,A,B,R)),
+%        blocked_unify(R,R0),
         Cstr = CAB
     ;   set_int_type(Type,A),
         set_int_type(Type,B),
@@ -993,8 +967,13 @@ unfold_int_expr(bvnot(Size,EA), D, Cstr, Type, R) ?-
     Type = uint(Size),
     !,
     unfold_int_expr(EA,D,CA,Type,A),
+    % on sature au ou
+    Max is 2^Size - 1,
+    unfold_int_expr(bvsub(Size,as(Max,uint(Size)),EA),D,CB,Type,CR),
+    blocked_unify(R,CR),
     insert_dep_inst(dep(R,D,[A])),
-    make_conj(CA, bvnot(Size,A,R),Cstr).
+    make_conj(CA,CB,CAB),
+    make_conj(CAB,bvnot(Size,A,R),Cstr).
 
 unfold_int_expr(bvnand(Size,EA,EB), D, Cstr, Type, R) ?- !,
     unfold_int_expr(bvnot(Size,bvand(Size,EA,EB)), D, Cstr, Type, R).
@@ -1018,8 +997,8 @@ unfold_int_expr(bvcomp(Size,EA,EB), D, Cstr, RType, R) ?-
     ((number(A),
       number(B))
     ->
-        eq_int_reif(Type,A,B,R0),
-        blocked_unify(R,R0),
+        blocked_call(eq_int_reif(Type,A,B,R)),
+%        blocked_unify(R,R0),
         Cstr = CAB
     ;   set_int_type(Type,R),
         get_reif_var_depth_from_labchoice(DD),
@@ -1040,12 +1019,16 @@ unfold_int_expr(bvneg(Size,EA), D, Cstr, Type, R) ?- !,
     integer(Size),
     Size > 0,
     Type = uint(Size),
-    % ça risque pas de fail parce qu'on est en unsigned?
-    (Size == 1 ->
-        get_reif_var_depth_from_labchoice(DD),
-        insert_dep_inst(dep(inst_cstr(DD,R)))
-    ;   true),
-    unfold_int_expr(-EA, D, Cstr, Type, R).
+    % ça risque pas de fail parce qu'on est en unsigned
+    get_norm_expr(Norm),
+    (normalize_expr(Norm,Type,bvneg(Size,EA),D,Cstr,R,Goal) ->
+        call(Goal)
+    ;   (Size == 1 ->
+            get_reif_var_depth_from_labchoice(DD),
+            insert_dep_inst(dep(inst_cstr(DD,R)))
+        ;   true),
+        unfold_int_expr(-EA, D, Cstr, Type, R),
+        set_norm_expr(Norm)).
 
 /*
  Size = 8, int_vars(uint(Size),[A,B]),
@@ -1057,7 +1040,11 @@ unfold_int_expr(bvadd(Size,EA,EB), D, Cstr, Type, R) ?-
     Size > 0,
     !,
     Type = uint(Size),
-    unfold_int_expr(EA + EB, D, Cstr, Type, R).
+    get_norm_expr(Norm),
+    (normalize_expr(Norm,Type,bvadd(Size,EA,EB),D,Cstr,R,Goal) ->
+        call(Goal)
+    ;   unfold_int_expr(EA + EB, D, Cstr, Type, R),
+        set_norm_expr(Norm)).
 
 /*
  Size = 8, int_vars(uint(Size),[A,B]),
@@ -1077,7 +1064,11 @@ unfold_int_expr(bvsub(Size,EA,EB), D, Cstr, Type, R) ?-
     Size > 0,
     !,
     Type = uint(Size),
-    unfold_int_expr(EA - EB, D, Cstr, Type, R).
+    get_norm_expr(Norm),
+    (normalize_expr(Norm,Type,bvsub(Size,EA,EB),D,Cstr,R,Goal) ->
+        call(Goal)
+    ;   unfold_int_expr(EA - EB, D, Cstr, Type, R),
+        set_norm_expr(Norm)).
 
 
 /*
@@ -1090,7 +1081,11 @@ unfold_int_expr(bvmul(Size,EA,EB), D, Cstr, Type, R) ?-
     Size > 0,
     !,
     Type = uint(Size),
-    unfold_int_expr(EA * EB, D, Cstr, Type, R).
+    get_norm_expr(Norm),
+    (normalize_expr(Norm,Type,bvmul(Size,EA,EB),D,Cstr,R,Goal) ->
+        call(Goal)
+    ;   unfold_int_expr(EA * EB, D, Cstr, Type, R),
+        set_norm_expr(Norm)).
 
 /*
 Size = 6, int_vars(uint(Size),[A,B,Q]),
@@ -1297,6 +1292,12 @@ unfold_int_expr(bvashr(Size,EA,EB), D, Cstr, Type, R) ?-
     integer(Size),
     Size > 0,
     Type = uint(Size),
+    Sm1 is Size - 1,
+    unfold_int_expr(ite(extract(Size,Sm1,Sm1,EA) #= as(0,uint(1)),
+                        bvlshr(Size,EA,EB),
+                        bvnot(Size,bvlshr(Size,bvnot(Size,EA),EB))),
+                    D,Cstr,Type,R).
+/*
     unfold_int_expr(EA,ND,CA,Type,A),
     unfold_int_expr(EB,ND,CB,Type,B),
     !,
@@ -1310,6 +1311,7 @@ unfold_int_expr(bvashr(Size,EA,EB), D, Cstr, Type, R) ?-
     ;   set_int_type(Type,R),
         insert_dep_inst(dep(R,D,[A,B])),
         make_conj(CAB,bvasr(Size,A,B,R),Cstr)).
+*/
 
 /*
 % preuve bvudiv
@@ -1340,8 +1342,8 @@ unfold_int_expr(bvlshr(Size,EA,EB), D, Cstr, Type, R) ?-
     ((number(A),
       number(B))
     ->
-        bvlsr(Size,A,B,R0),
-        blocked_unify(R,R0),
+        blocked_call(bvlsr(Size,A,B,R)),
+%        blocked_unify(R,R0),
         Cstr = CAB
     ;   set_int_type(Type,R),
         insert_dep_inst(dep(R,D,[A,B])),
@@ -1379,8 +1381,8 @@ unfold_int_expr(bvshl(Size,EA,EB), D, Cstr, Type, R) ?-
     ((number(A),
       number(B))
     ->
-        bvsl(Size,A,B,R0),
-        blocked_unify(R,R0),
+        blocked_call(bvsl(Size,A,B,R)),
+%        blocked_unify(R,R0),
         Cstr = CAB
     ;   insert_dep_inst(dep(R,D,[A,B])),
         make_conj(CAB,bvsl(Size,A,B,R),Cstr)).
@@ -1425,8 +1427,12 @@ solve_cstrs.
 */
 unfold_int_expr(extract(SizeA,I,J,EA), D, Cstr, Type, R) ?-
     Type = uint(N),
-    integer(SizeA), integer(I), integer(J),
-    SizeA > I, I >= J, J >= 0,
+    integer(SizeA),
+    integer(I),
+    integer(J),
+    SizeA > I,
+    I >= J,
+    J >= 0,
     N is I - J + 1,
     ND is D + 1,
     Type0 = uint(SizeA),
@@ -1451,8 +1457,8 @@ unfold_int_expr(rotate_left(Size,I,EA), D, Cstr, Type, R) ?-
     unfold_int_expr(EA,ND,CA,uint(Size),A),
     !,
     (integer(A) ->
-        bvrotatel(Size,I,A,R0),
-        blocked_unify(R,R0),
+        blocked_call(bvrotatel(Size,I,A,R)),
+%        blocked_unify(R,R0),
         Cstr = CA
     ;   set_int_type(Type,R),
         insert_dep_inst(dep(R,D,[A])),
@@ -1467,8 +1473,8 @@ unfold_int_expr(rotate_right(Size,I,EA), D, Cstr, Type, R) ?-
     unfold_int_expr(EA,ND,CA,uint(Size),A),
     !,
     (integer(A) ->
-        bvrotater(Size,I,A,R0),
-        blocked_unify(R,R0),
+        blocked_call(bvrotater(Size,I,A,R)),
+%        blocked_unify(R,R0),
         Cstr = CA
     ;   set_int_type(Type,R),
         insert_dep_inst(dep(R,D,[A])),
@@ -1484,8 +1490,8 @@ unfold_int_expr(repeat(Size,I,EA), D, Cstr, Type, R) ?-
     !,
     SizeR is Size * I,
     (integer(A) ->
-        repeat(Size,I,A,R0),
-        blocked_unify(R,R0),
+        blocked_call(repeat(Size,I,A,R)),
+%        blocked_unify(R,R0),
         Cstr = CA
     ;   set_int_type(Type,R),
         insert_dep_inst(dep(R,D,[A])),
@@ -1511,8 +1517,8 @@ unfold_int_expr(zero_extend(Size,I,EA), D, Cstr, Type, R) ?-
     !,
     SizeR is Size + I,
     (integer(A) ->
-        zero_extend(Size,I,A,R0),
-        blocked_unify(R,R0),
+        blocked_call(zero_extend(Size,I,A,R)),
+%        blocked_unify(R,R0),
         Cstr = CA
     ;   (I == 0 ->
             R = A,
@@ -1553,8 +1559,8 @@ unfold_int_expr(sign_extend(Size,I,EA), D, Cstr, Type, R) ?-
     unfold_int_expr(EA,ND,CA,uint(Size),A),
     !,
     (integer(A) ->
-        sign_extend(Size,I,A,R0),
-        blocked_unify(R,R0),
+        blocked_call(sign_extend(Size,I,A,R)),
+%        blocked_unify(R,R0),
         Cstr = CA
     ;   (I == 0 ->
             R = A,
@@ -1621,7 +1627,6 @@ unfold_int_expr(bvslt(N, EA, EB), D, Cstr, Type, R) ?-
              bvult(as(A,uint(N)),as(B,uint(N))))),
        D, Cstr, Type, R).
 */
-
 /*
 Size = 5,PSize is Size - 1,
 int_vars(uint(Size),(S,T)),
@@ -1666,23 +1671,28 @@ unfold_int_expr(bvsgt(N, EA, EB), D, Cstr, Type, R) ?-
     unfold_int_expr(bvslt(N, EB, EA), D, Cstr, Type, R).
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 unfold_int_expr(- EA,D,Cstr,Type,R) ?-
-    ND is D + 1,
-    unfold_int_expr(EA,ND,CA,Type,A),
-    !,
-    (number(A) ->
-        opp(Type,D,A,R0,UO),
-        blocked_unify(R,R0),
-        Cstr = CA
-    ;   insert_dep_inst(dep(R,D,[A])),
-        make_conj(CA,opp(Type,D,A,R,UO),Cstr)).
+    get_norm_expr(Norm),
+    (normalize_expr(Norm,Type,-EA,D,Cstr,R,Goal) ->
+        !,
+        call(Goal)
+    ;   ND is D + 1,
+        unfold_int_expr(EA,ND,CA,Type,A),
+        !,
+        set_norm_expr(Norm),
+        (number(A) ->
+            blocked_call(opp(Type,D,A,R,UO)),
+%            blocked_unify(R,R0),
+            Cstr = CA
+        ;   insert_dep_inst(dep(R,D,[A])),
+            make_conj(CA,opp(Type,D,A,R,UO),Cstr))).
 unfold_int_expr(int(EA),D,Cstr,Type,R) ?-
     ND is D + 1,
     unfold_real_expr(EA,ND,CA,RType,A),
     !,
     (number(A) ->
-        cast_real_int(RType,A,R0),
-        to_int(Type,R0,R1),
-        blocked_unify(R,R1),
+        blocked_call((cast_real_int(RType,A,R0),
+                      to_int(Type,R0,R))),
+%        blocked_unify(R,R1),
         Cstr = CA
     ;   insert_dep_inst(dep(R,D,[A])),
         make_conj(CA,(cast_real_int(RType,A,R0),to_int(Type,R0,R)),Cstr)).
@@ -1694,8 +1704,8 @@ unfold_int_expr(intN_from_int(N,EA),D,Cstr,Type,R) ?-
     !,
     Type = int(N),
     (number(A) ->
-        to_intNs(N,A,R0),
-        blocked_unify(R,R0),
+        blocked_call(to_intNs(N,A,R)),
+%        blocked_unify(R,R0),
         Cstr = CA
     ;   insert_dep_inst(dep(R,D,[A])),
         make_conj(CA,to_intNs(N,A,R),Cstr)).
@@ -1709,8 +1719,8 @@ unfold_int_expr(intN_from_uint(N,EA),D,Cstr,Type,R) ?-
     !,
     Type = int(N),
     (number(A) ->
-        uintN_to_intN(N,A,R0,UO),
-        blocked_unify(R,R0),
+        blocked_call(uintN_to_intN(N,A,R,UO)),
+%        blocked_unify(R,R0),
         Cstr = CA
     ;   %get_reif_var_depth_from_labchoice(DD),
         %insert_dep_inst(inst_cstr(DD,UO)),
@@ -1726,8 +1736,8 @@ unfold_int_expr(uintN_from_int(N,EA),D,Cstr,Type,R) ?-
     !,
     Type = uint(N),
     (number(A) ->
-        to_intNu(N,A,R0),
-        blocked_unify(R,R0),
+        blocked_call(to_intNu(N,A,R)),
+%        blocked_unify(R,R0),
         Cstr = CA
     ;   insert_dep_inst(dep(R,D,[A])),
         make_conj(CA,to_intNu(N,A,R),Cstr)).
@@ -1753,8 +1763,8 @@ unfold_int_expr(uintN_from_intN(N,EA),D,Cstr,Type,R) ?-
     !,
     Type = uint(N),
     (number(A) ->
-        intN_to_uintN(N,A,R0,UO),
-        blocked_unify(R,R0),
+        blocked_call(intN_to_uintN(N,A,R,UO)),
+%        blocked_unify(R,R0),
         Cstr = CA
     ;   %get_reif_var_depth_from_labchoice(DD),
         %insert_dep_inst(inst_cstr(DD,UO)),
@@ -1783,8 +1793,8 @@ unfold_int_expr(int_from_real(EA),D,Cstr,Type,R) ?-
     !,
     Type = int,
     (number(A) ->
-        cast_real_int(real,A,R0),
-        blocked_unify(R,R0),
+        blocked_call(cast_real_int(real,A,R)),
+%        blocked_unify(R,R0),
         Cstr = CA
     ;   insert_dep_inst(dep(R,D,[A])),
         make_conj(CA,cast_real_int(real,A,R),Cstr)).
@@ -1794,8 +1804,8 @@ unfold_int_expr(int_from_float(EA),D,Cstr,Type,R) ?-
     !,
     Type = int,
     (number(A) ->
-        cast_real_int(float_simple,A,R0),
-        blocked_unify(R,R0),
+        blocked_call(cast_real_int(float_simple,A,R)),
+%        blocked_unify(R,R0),
         Cstr = CA
     ;   insert_dep_inst(dep(R,D,[A])),
         make_conj(CA,cast_real_int(float_simple,A,R),Cstr)).
@@ -1817,23 +1827,52 @@ unfold_int_expr(abs(EA),D,Cstr,Type,R) ?-
     nonvar(Type),
     !,
     (number(A) ->
-        abs_val(Type,D,A,R0,UO),
-        blocked_unify(R,R0),
+        blocked_call(abs_val(Type,D,A,R,UO)),
+%        blocked_unify(R,R0),
         Cstr = CA
     ;   set_int_type(Type,R),
         insert_dep_inst(dep(R,D,[A])),
         make_conj(CA,abs_val(Type,D,A,R,UO),Cstr)).
 unfold_int_expr(EA + EB,D,Cstr,Type,R) ?-
-    ((nonvar(EB),
-      EB = - OpEB)
-    ->
+    get_norm_expr(Norm),
+    (normalize_expr(Norm,Type,EA+EB,D,Cstr,R,Goal) ->
         !,
-        unfold_int_expr(EA - OpEB,D,Cstr,Type,R)
-    ;   ((nonvar(EA),
-          EA = - OpEA)
+        call(Goal)
+    ;   ((nonvar(EB),
+          EB = - OpEB)
+        ->
+            !,
+            unfold_int_expr(EA - OpEB,D,Cstr,Type,R)
+        ;   ((nonvar(EA),
+              EA = - OpEA)
+            ->
+                !,
+                unfold_int_expr(EB - OpEA,D,Cstr,Type,R)
+            ;   ND is D + 1,
+                unfold_int_expr(EA,ND,CA,Type,A),
+                unfold_int_expr(EB,ND,CB,Type,B),
+                !,
+                make_conj(CA,CB,CAB),
+                ((number(A),
+                  number(B))
+                ->
+                    blocked_call(add(Type,D,A,B,R,UO)),
+%                    blocked_unify(R,R0),
+                    Cstr = CAB
+                ;   set_int_type(Type,R),
+                    insert_dep_inst(dep(R,D,[A,B])),
+                    make_conj(CAB,add(Type,D,A,B,R,UO),Cstr))))),
+    set_norm_expr(Norm).
+unfold_int_expr(EA - EB,D,Cstr,Type,R) ?-
+    get_norm_expr(Norm),
+    (normalize_expr(Norm,Type,EA-EB,D,Cstr,R,Goal) ->
+        !,
+        call(Goal)
+    ;   ((nonvar(EB),
+          EB = - OpEB)
         ->
             !,
-            unfold_int_expr(EB - OpEA,D,Cstr,Type,R)
+            unfold_int_expr(EA + OpEB,D,Cstr,Type,R)
         ;   ND is D + 1,
             unfold_int_expr(EA,ND,CA,Type,A),
             unfold_int_expr(EB,ND,CB,Type,B),
@@ -1842,32 +1881,14 @@ unfold_int_expr(EA + EB,D,Cstr,Type,R) ?-
             ((number(A),
               number(B))
             ->
-                add(Type,D,A,B,R0,UO),
-                blocked_unify(R,R0),
+                blocked_call(minus(Type,D,A,B,R,UO)),
+%                blocked_unify(R,R0),
                 Cstr = CAB
             ;   set_int_type(Type,R),
                 insert_dep_inst(dep(R,D,[A,B])),
-                make_conj(CAB,add(Type,D,A,B,R,UO),Cstr)))).
-unfold_int_expr(EA - EB,D,Cstr,Type,R) ?-
-    ((nonvar(EB),
-      EB = - OpEB)
-    ->
-        !,
-        unfold_int_expr(EA + OpEB,D,Cstr,Type,R)
-    ;   ND is D + 1,
-        unfold_int_expr(EA,ND,CA,Type,A),
-        unfold_int_expr(EB,ND,CB,Type,B),
-        !,
-        make_conj(CA,CB,CAB),
-        ((number(A),
-          number(B))
-        ->
-            minus(Type,D,A,B,R0,UO),
-            blocked_unify(R,R0),
-            Cstr = CAB
-        ;   set_int_type(Type,R),
-            insert_dep_inst(dep(R,D,[A,B])),
-            make_conj(CAB,minus(Type,D,A,B,R,UO),Cstr))).
+                make_conj(CAB,minus(Type,D,A,B,R,UO),Cstr)))),
+    set_norm_expr(Norm).
+/*
 unfold_int_expr((EA * EB) * EC,D,Cstr,Type,R) ?-
     Type == int,
     (remove_all_as(EA,A),
@@ -1887,21 +1908,27 @@ unfold_int_expr((EA * EB) * EC,D,Cstr,Type,R) ?-
      Z = EB),
     !,
     unfold_int_expr(X * (Y * Z),D,Cstr,Type,R).
+*/
 unfold_int_expr(EA * EB,D,Cstr,Type,R) ?-
-    ND is D + 1,
-    unfold_int_expr(EA,ND,CA,Type,A),
-    unfold_int_expr(EB,ND,CB,Type,B),
-    !,
-    make_conj(CA,CB,CAB),
-    ((number(A),
-      number(B))
-    ->
-        mult(Type,D,A,B,R0,UO),
-        blocked_unify(R,R0),
-        Cstr = CAB
-    ;   set_int_type(Type,R),
-        insert_dep_inst(dep(R,D,[A,B])),
-        make_conj(CAB,mult(Type,D,A,B,R,UO),Cstr)).
+    get_norm_expr(Norm),
+    (normalize_expr(Norm,Type,EA*EB,D,Cstr,R,Goal) ->
+        !,
+        call(Goal)
+    ;   ND is D + 1,
+        unfold_int_expr(EA,ND,CA,Type,A),
+        unfold_int_expr(EB,ND,CB,Type,B),
+        !,
+        make_conj(CA,CB,CAB),
+        ((number(A),
+          number(B))
+        ->
+            blocked_call(mult(Type,D,A,B,R,UO)),
+%            blocked_unify(R,R0),
+            Cstr = CAB
+        ;   set_int_type(Type,R),
+            insert_dep_inst(dep(R,D,[A,B])),
+            make_conj(CAB,mult(Type,D,A,B,R,UO),Cstr))),
+    set_norm_expr(Norm).
 
 % Surcharge pour les Int !
 unfold_int_expr(EA / EB,D,Cstr,Type,R) ?- !,
@@ -1989,6 +2016,7 @@ unfold_int_expr(EA mod EB,D,Cstr,Type,R) ?-
     make_conj(CABCond,chk_undef_ediv_mod(Bool,Type,A,B,Q,R),Cstr).
 
 unfold_int_expr(colibri_pow_int(EA,EN),D,Cstr,Type,R) ?-
+    Type == int,
     ND is D + 1,
     unfold_int_expr(EN,ND,CN,int,N),
     !,
@@ -2007,8 +2035,8 @@ unfold_int_expr(EA ^ EN,D,Cstr,Type,R) ?-
     ((number(A),
       number(N))
     ->
-        power(Type,D,A,N,R0,UO),
-        blocked_unify(R,R0),
+        blocked_call(power(Type,D,A,N,R,UO)),
+%        blocked_unify(R,R0),
         Cstr = CAN
     ;   make_conj(CAN,power(Type,D,A,N,R,UO),Cstr)).
 unfold_int_expr(min(EA,EB),D,Cstr,Type,R) ?-
@@ -2021,8 +2049,8 @@ unfold_int_expr(min(EA,EB),D,Cstr,Type,R) ?-
     ((number(A),
       number(B))
     ->
-        min_int(A,B,R0),
-        blocked_unify(R,R0),
+        blocked_call(min_int(A,B,R)),
+%        blocked_unify(R,R0),
         Cstr = CAB
     ;   make_conj(CAB,min_int(A,B,R),Cstr)).
 unfold_int_expr(max(EA,EB),D,Cstr,Type,R) ?-
@@ -2035,8 +2063,8 @@ unfold_int_expr(max(EA,EB),D,Cstr,Type,R) ?-
     ((number(A),
       number(B))
     ->
-        max_int(A,B,R0),
-        blocked_unify(R,R0),
+        blocked_call(max_int(A,B,R)),
+%        blocked_unify(R,R0),
         Cstr = CAB
     ;   make_conj(CAB,max_int(A,B,R),Cstr)).
 % Les inegalites entieres, les arguments
@@ -2222,7 +2250,7 @@ unfold_int_expr(alldiff(Type,L),D,Cstr,Bool,R) :-
                 unfold_int_expr(E,ND,CE,Type,RE)
             ;   % pas de NaN ici
                 (IType == real ->
-                    ensure_not_NaN(RE) %????
+                    ensure_not_NaN(RE)
                 ;   true),
                 unfold_real_expr(E,ND,CE,Type,RE)),
             insert_dep_inst(dep(RE,ND,[R])),
@@ -2460,15 +2488,21 @@ unfold_int_expr(EA $= EB,D,Cstr,Type0,R) ?-
         insert_dep_inst(dep(A,D,[R])),
         insert_dep_inst(dep(B,D,[R])),
         make_conj(CA,CB,CAB),
-        ((Type \== real,
-          (number(A),C = A;
-           number(EA),to_real(Type,EA,C)),
+        (((Type \== real;
+           fail,is_float_int_number(B)),
+          (number(A),
+           C = A;
+           number(EA),
+           to_real(Type,EA,C)),
           var(B))
         ->
             Goal = in_intervals_reif(Type,B,[C],R)
-        ;   ((Type \== real,
-              (number(B),C = B;
-               number(EB),to_real(Type,EB,C)),
+        ;   (((Type \== real;
+               fail,is_float_int_number(A)),
+              (number(B),
+               C = B;
+               number(EB),
+               to_real(Type,EB,C)),
               var(A))
             ->
                 Goal = in_intervals_reif(Type,A,[C],R)
@@ -2479,42 +2513,9 @@ unfold_int_expr(EA $= EB,D,Cstr,Type0,R) ?-
             make_conj(CA,CB,Cstr)
         ;   % R == 0
             make_conj(CA,CB,CAB),
-            make_conj(CAB,launch_diff_real(Type,A,B),Cstr))).
+            
+            make_conj(CAB,diff_real_float(Type,A,B),Cstr))).
 
-/*
-unfold_int_expr(fp_eq(EA,EB),D,Cstr,Type0,R) ?-
-    ND is D + 1,
-    Type0 = bool,
-    (R == 1 ->
-        ensure_not_NaN(A),
-        ensure_not_NaN(B)
-    ;   true),
-    unfold_real_expr(EA,ND,CA,Type,A),
-    unfold_real_expr(EB,ND,CB,Type,B),
-    !,
-    int_vars(bool,R),
-    unfold_int_expr(
-        chk_nan(isNaN(as(A,Type)) or isNaN(as(B,Type)),
-            as(0,bool),
-            chk_nan(as(R,bool),
-                chk_nan(isZero(as(A,Type)) and isZero(as(B,Type)),
-                    as(1,bool),
-                    as(A,Type) $= as(B,Type)),
-                chk_nan(isZero(as(A,Type)) and isZero(as(B,Type)),
-                    % pour echouer avec R = 0
-                    as(1,bool),
-                    % pour faire un diff_real avec R = 0
-                    as(A,Type) $= as(B,Type)))),
-        D,
-        Cond,bool,R),
-    get_reif_var_depth_from_labchoice(DD),
-    insert_dep_inst(inst_cstr(DD,R)),
-    insert_dep_inst(dep(R,D,[A,B])),
-    insert_dep_inst(dep(A,D,[R])),
-    insert_dep_inst(dep(B,D,[R])),
-    make_conj(CA,CB,CAB),
-    make_conj(CAB,Cond,Cstr).
-*/
 % Ancienne version
 unfold_int_expr(fp_eq(EA,EB),D,Cstr,Type0,R) ?-
     ND is D + 1,
@@ -2587,9 +2588,12 @@ unfold_int_expr(EA $\= EB,D,Cstr,Type0,R) ?- !,
                     Inter = [NA..1.0Inf]
                 ;   Inter = [-1.0Inf..PA,NA..1.0Inf])),
             Goal = in_intervals_reif(Type,B,Inter,R)
-        ;   ((Type \== real,
-              (number(B),C = B;
-               number(EB),to_real(Type,EB,C)),
+        ;   (((Type \== real;
+               fail,is_float_int_number(A)),
+              (number(B),
+               C = B;
+               number(EB),
+               to_real(Type,EB,C)),
               var(A))
             ->
                 % A < CB
@@ -2608,7 +2612,7 @@ unfold_int_expr(EA $\= EB,D,Cstr,Type0,R) ?- !,
             make_conj(CA,CB,Cstr)
         ;   % R == 1
             make_conj(CA,CB,CAB),
-            make_conj(CAB,launch_diff_real(Type,A,B),Cstr))).
+            make_conj(CAB,diff_real_float(Type,A,B),Cstr))).
 
 unfold_int_expr(EA $< EB,D,Cstr,Type0,R) ?-
     Type0 = bool,
@@ -2638,22 +2642,30 @@ unfold_int_expr(EA $< EB,D,Cstr,Type0,R) ?-
         insert_dep_inst(dep(A,D,[R])),
         insert_dep_inst(dep(B,D,[R])),
         min_max_lazy(Type,Min,Max,_),
-        ((Type \== real,
+        (((Type \== real;
+           fail,is_float_int_number(B),
+           FI = 1),
           (number(A),C = A;
            number(EA),to_real(Type,EA,C)),
           var(B))
         ->
             % CA < B
-            get_next_float(Type,C,NA),
+            (var(FI) ->
+                get_next_float(Type,C,NA)
+            ;   NA = C),
             Inter = [NA..Max],
             Goal = in_intervals_reif(Type,B,Inter,R)
-        ;   ((Type \== real,
+        ;   (((Type \== real;
+               fail,is_float_int_number(A),
+               FI = 1),
               (number(B),C = B;
                number(EB),to_real(Type,EB,C)),
               var(A))
             ->
                 % A < CB
-                get_previous_float(Type,C,PB),
+                (var(FI) ->
+                    get_previous_float(Type,C,PB)
+                ;   PB = C),
                 Inter = [Min..PB],
                 Goal = in_intervals_reif(Type,A,Inter,R)
             ;   Goal = gt_real_reif(Type,B,A,R))),
@@ -2733,7 +2745,8 @@ unfold_int_expr(EA $=< EB,D,Cstr,Type0,R) ?-
         insert_dep_inst(dep(A,D,[R])),
         insert_dep_inst(dep(B,D,[R])),
         min_max_lazy(Type,Min,Max,_),
-        ((Type \== real,
+        (((Type \== real;
+           fail,is_float_int_number(B)),
           (number(A),C = A;
            number(EA),to_real(Type,EA,C)),
           var(B))
@@ -2746,7 +2759,8 @@ unfold_int_expr(EA $=< EB,D,Cstr,Type0,R) ?-
             ;   NC = C),
             Inter = [NC..Max],
             Goal = in_intervals_reif(Type,B,Inter,R)
-        ;   ((Type \== real,
+        ;   (((Type \== real;
+               fail,is_float_int_number(A)),
               (number(B),C = B;
                number(EB),to_real(Type,EB,C)),
               var(A))
@@ -2851,6 +2865,7 @@ unfold_int_expr(neg(EA),D,Cstr,Type,R) ?- !,
             make_conj(CA,not_int(A,R),Cstr)
         ;   Cstr = CA)).
 
+
 /*
 unfold_int_expr(((EA1 and EA2) and EB),D,Cstr,Type,R) ?-
     nonvar(R),
@@ -2893,10 +2908,11 @@ unfold_int_expr((EA and EB),D,Cstr,Type,R) ?-
                 insert_dep_inst(dep(R,D,[A,B])),
                 insert_dep_inst(dep(A,D,[R])),
                 insert_dep_inst(dep(B,D,[R])),
-                ((TA \== real,
-                  is_intervals_def(CA,TA,VA,IA,BA,RestA),
+                ((is_intervals_def(CA,TA,VA,IA,BA,RestA),
                   is_intervals_def(CB,_TB,VB,IB,BB,RestB),
                   VA == VB,
+                  (TA \== real;
+                   fail,is_float_int_number(VA)),
                   var(BA),
                   var(BB))
                 ->
@@ -2917,11 +2933,13 @@ unfold_int_expr((EA and EB),D,Cstr,Type,R) ?-
 
 
 
+
+/*
 unfold_int_expr((EA or EB),D,Cstr,Type,R) ?- 
     var(R),
     !,
     unfold_int_expr(chk_nan(EA,as(1,bool),EB),D,Cstr,Type,R).
-
+*/
 unfold_int_expr((EA or EB),D,Cstr,Type,R) ?- 
     Type = bool,
     ND is D + 1,
@@ -2958,10 +2976,11 @@ unfold_int_expr((EA or EB),D,Cstr,Type,R) ?-
                 insert_dep_inst(dep(R,D,[A,B])),
                 insert_dep_inst(dep(A,D,[R])),
                 insert_dep_inst(dep(B,D,[R])),
-                ((TA \== real,
-                  is_intervals_def(CA,TA,VA,IA,BA,RestA),
+                ((is_intervals_def(CA,TA,VA,IA,BA,RestA),
                   is_intervals_def(CB,_TB,VB,IB,BB,RestB),
                   VA == VB,
+                  (TA \== real;
+                   fail,is_float_int_number(VA)),
                   var(BA),
                   var(BB))
                 ->
@@ -2984,6 +3003,7 @@ unfold_int_expr((EA xor EB),D,Cstr,Type,R) ?- !,
     Type = bool,
     unfold_int_expr((EA \= EB),D,Cstr,Type,R).
 unfold_int_expr((EA => EB),D,Cstr,Type,R) ?- !,
+/*
     Type = bool,
     ND is D + 1,
     (R == 0 ->
@@ -3015,7 +3035,8 @@ unfold_int_expr((EA => EB),D,Cstr,Type,R) ?- !,
                         insert_dep_inst(dep(A,D,[R])),
                         insert_dep_inst(dep(B,D,[R])),
                         make_conj(CAB,imply_reif(A,B,R),Cstr)))))).
-%    unfold_int_expr((neg(EA) or EB),D,Cstr,Type,R).
+*/
+    unfold_int_expr((neg(EA) or EB),D,Cstr,Type,R).
 unfold_int_expr(ite(Cond,Then,Else),D,Cstr,Type,R) ?-
     ND is D + 1,
     unfold_int_expr(Cond,ND,CC,bool,RCond),
@@ -3067,7 +3088,8 @@ unfold_int_expr(chk_nan(Cond,Then,Else),D,Cstr,Type,R) ?-
     unfold_int_expr(Else,ND,CE,Type,RE),
     !,
     int_vars(bool,RCond),
-    int_vars(bool,R),
+%    int_vars(bool,R),
+    int_vars(Type,R),
     insert_dep_inst(dep(R,D,[RCond,RT,RE])),
     insert_dep_inst(dep(RT,D,[RCond])),
     insert_dep_inst(dep(RE,D,[RCond])),
@@ -3416,6 +3438,7 @@ unfold_let(From,[(V,TypeV,EV)|T],E,D,Cstrs,Cstr,Type,R) :-
             ;   (real_type(TypeV,_) ->
                     unfold_real_expr(EV,D,CV,TypeV,V)
                 ;   unfold_int_expr(EV,D,CV,TypeV,V)),
+                % call(spy_here)@eclipse,
                 make_conj(Cstrs,CV,NCstrs))),
         (real_type(TypeV,_) ->
             real_vars(TypeV,V)
@@ -3427,16 +3450,17 @@ get_reif_var_depth_from_labchoice(D) :-
         D = 0
     ;   D is 2^32).
 
-/*
+
 bvnot_expr(Size,bvnot(Size,EA),E) ?- !,
     E = EA.
-*/
 %bvnot_expr(_,_,_) :- !,fail.
 
 bvnot_expr(Size,bvand(Size,EA,EB),E) ?- !,
     E = bvor(Size,bvnot(Size,EA),bvnot(Size,EB)).
+/*
 bvnot_expr(Size,bvor(Size,EA,EB),E) ?- !,
     E = bvand(Size,bvnot(Size,EA),bvnot(Size,EB)).
+*/
 bvnot_expr(1,as(0,_),R) ?- !,
     blocked_unify(R,1).
 bvnot_expr(1,as(1,_),R) ?- !,
@@ -3450,10 +3474,7 @@ not_expr(1,B) ?- !,
     blocked_unify(B,0).
 not_expr(neg(A),NA) ?- !,
     NA = A.
-not_expr(A => B,E) ?-
-    (cgiveInstancePath(neg(_),A,_);
-     cgiveInstancePath(neg(_),B,_)),
-    !,
+not_expr(A => B,E) ?- !,
     E = A and neg(B).
 not_expr(A and B,E) ?- 
     (cgiveInstancePath(neg(_),A,_);
@@ -3466,6 +3487,12 @@ not_expr(A or B,E) ?-
     !,
     E = neg(A) and neg(B).
 
+/*
+not_expr(let(Vars,P),E) ?- !,
+    E = let(Vars,neg(P)).
+not_expr(quant_abs(P),E) ?- !,
+    E = quant_abs(neg(P)).
+*/
 not_expr(A xor B,E) ?- !,
     E = (A #= B).
 not_expr(A #= B,E) ?- !,
@@ -3526,10 +3553,10 @@ not_expr(alldiff(Type,[A,B]),E) ?-
 % PAS DE real !!!
 in_intervals_reif(Type,Var,Inter0,1) ?- !,
     functor(Type,FType,_),
-    (occurs(FType,(float_simple,float_double)) ->
-        (Inter0 = [0.0] ->
-            Inter = [-0.0..0.0]
-        ;   Inter = Inter0),
+    ((occurs(FType,(float_simple,float_double));
+      is_float_int_number(Var))
+    ->
+        Inter = Inter0,
         NType = FType
     ;   set_int_type(Type,Var),
         Int = 1,
@@ -3540,13 +3567,18 @@ in_intervals_reif(Type,Var,Inter0,1) ?- !,
 
 in_intervals_reif(Type,Var,Inter0,0) ?- !,
     functor(Type,FType,_),
-    (occurs(FType,(float_simple,float_double)) ->
-        (Inter0 = [0.0] ->
-            Inter = [-0.0..0.0]
-        ;   Inter = Inter0),
+    ((occurs(FType,(float_simple,float_double));
+      is_float_int_number(Var))
+    ->
+        Inter = Inter0,
         NType = Type
     ;   NType = int,
         Inter = Inter0),
+    ((FType \== real;
+      is_float_int_number(Var))
+    ->
+        reduce_sub_intervals
+    ;   true),
     (NType == int ->
         set_int_type(Type,Dummy),
         mfd:get_intervals(Dummy,InitInter),
@@ -3560,12 +3592,12 @@ in_intervals_reif(Type,Var,Inter0,Bool) :-
     set_priority(1),
     save_cstr_suspensions(Var),
     functor(Type,FType,_),
-    (occurs(FType,(float_simple,float_double)) ->
+    ((occurs(FType,(float_simple,float_double));
+      is_float_int_number(Var))
+    ->
         set_real_type(Type,Var),
         mreal:get_intervals(Var,IVar),
-        (Inter0 = [0.0] ->
-            Inter = [-0.0..0.0]
-        ;   Inter = Inter0),
+        Inter = Inter0,
         T = Type
     ;   set_int_type(Type,Var),
         mfd:get_intervals(Var,IVar),
@@ -3591,6 +3623,11 @@ in_intervals_reif(Type,Var,Inter0,Bool) :-
                 mfd:set_intervals(Var,Inter)
             ;   set_typed_intervals(Var,Type,Inter))
         ;   % Bool == 0
+            ((FType \== real;
+              is_float_int_number(Var))
+            ->
+                reduce_sub_intervals
+            ;   true),
             (nonvar(Int) ->
                 (nonvar(Diff) ->
                     true
@@ -3611,7 +3648,8 @@ in_intervals_reif(Type,Var,Inter0,Bool) :-
             (Type == Type1 ->
                 true
             ;   % attention aux bveq !
-                call(spy_here)@eclipse),
+                % call(spy_here)@eclipse),
+                true),
             protected_unify(Bool,BBool)
         ;   my_suspend(in_intervals_reif(Type,Var,Com,Bool),0,(Var,Bool)->
                                suspend:constrained))),
@@ -3660,7 +3698,7 @@ is_intervals_def((R,eq_int_reif(Type,X,Y,Bool)),T,V,I,B,Rest) ?-
     B = Bool,
     Rest = R.
 
-/* DANGER en real sauf real_int ?
+% DANGER en real sauf real_int ?
 is_intervals_def(eq_real_reif(real,X,Y,Bool),T,V,I,B,Rest) ?-
     (number(X) ->
         var(Y),
@@ -3688,7 +3726,6 @@ is_intervals_def((R,eq_real_reif(real,X,Y,Bool)),T,V,I,B,Rest) ?-
     T = real,
     B = Bool,
     Rest = R.
-*/
 
 intervals_union(Type,Inter1,Inter2,Union) :-
     functor(Type,FType,_),
@@ -3982,6 +4019,7 @@ diff_reif(Type,_Kill,A,B,1) ?- !,
             set_priority(P),
             wake_if_other_scheduled(P))
     ;   (real_type(Type,_) ->
+            % on est sur un distinct nan=nan et -0<>0
             diff_real_chk_nan(Type,A,B)
         ;   launch_diff_int(A,B))).
 diff_reif(Type,Kill,A,B,Bool) :- !,
@@ -4002,68 +4040,71 @@ diff_reif(Type,Kill,A,B,Bool) :- !,
             protected_unify(Bool,BBool)
         ;   my_suspend(diff_reif(Type,Kill,A,B,Bool),0,(Kill,Bool,A,B)->suspend:constrained))).
               
-              
-diff_real_chk_nan(_Type,A,A) ?- !,
-    fail.
-diff_real_chk_nan(real_int,A,B) :- !,
+% On est sur un distinct pour real/float/double !
+% Pas de nan ici
+diff_real_chk_nan(real_int,A,B) ?- !,
     real_vars(real_int,[A,B]),
     launch_diff_real(real,A,B).
-diff_real_chk_nan(real,A,B) :- !,
+diff_real_chk_nan(real,A,B) ?- !,
     launch_diff_real(real,A,B).
+diff_real_chk_nan(_Type,A,A) ?- !,
+    % meme pour nan
+    % distinct(nan,nan) = false
+    fail.
+
+% Tout non nan est <> d'un nan
+diff_real_chk_nan(Type,A,nan) ?-
+    set_lazy_domain(Type,A),
+    check_not_NaN(A),
+    !.
+diff_real_chk_nan(Type,nan,A) ?-
+    set_lazy_domain(Type,A),
+    check_not_NaN(A),
+    !.
+% On passe aux autres cas float/double
 diff_real_chk_nan(Type,A,B) :-
+    set_lazy_domain(Type,A),
+    set_lazy_domain(Type,B),
     get_priority(P),
     set_priority(1),
-    (A == nan ->
+    % Si A|B <> nan -> B|A <> nan
+    (check_not_NaN(A) ->
         ensure_not_NaN(B)
-    ;   (B == nan ->
+    ;   (check_not_NaN(B) ->
             ensure_not_NaN(A)
-        ;   ((number(A) ->
-                 check_not_NaN(B),
-                 Val = A,
-                 Var = B
-             ;   number(B),
-                 check_not_NaN(A),
-                 Val = B,
-                 Var = A)
-            ->
-                mreal:dvar_remove_element(Var,Val)
-            ;   ((check_not_NaN(A),
-                  check_not_NaN(B),
-                  (not_zero(A);
-                   not_zero(B)))
-                ->
-                    launch_diff_real(Type,A,B)
-                ;   save_cstr_suspensions((A,B)),
-                    get_saved_cstr_suspensions(LSusp),
-                    ((member((Susp,diff_real_chk_nan(Type,AA,BB)),LSusp),
-                      get_suspension_data(Susp,state,State),
-                      State \= 2,
-                      (AA == A ->
-                          BB == B
-                      ;   AA == B,
-                          BB == A))
-                    ->
-                        true
-                    ;   % on est bloque par un NaN ou zero ?
-                        (check_not_NaN(A) ->
-                            (check_not_NaN(B) ->
-                                % A et B peuvent valoir zero 0
-                                true
-                            ;   ChkNan = 1,
-                                VNaN = B)
-                        ;   ChkNan = 1,
-                            VNaN = A),
-                        (nonvar(ChkNan) ->
-                            int_vars(bool,Bool),
-                            set_lazy_domain(Type,VNaN),
-                            isNaN(VNaN,Bool),
-                            insert_dep_inst(dep(Bool,0,[]))
-                        ;   true),
-                        (var(Bool) ->
-                            my_suspend(diff_real_chk_nan(Type,A,B),0,
-                                       (A,B,Bool)->suspend:
-                                                          constrained)
-                        ;   diff_real_chk_nan(Type,A,B))))))),
+        ;   (A == nan ->
+                B \== nan,
+                VNaN = B
+            ;   VNaN = A),
+            Continue = 1)),
+    (var(Continue) ->
+        % On n'a plus de pb sur nan
+        launch_diff_real(Type,A,B)
+    ;   % Pas de statut nan connu
+        % on est bloqué par le statut nan de VNaN
+        save_cstr_suspensions((A,B)),
+        get_saved_cstr_suspensions(LSusp),
+        (((Goal = diff_real_chk_nan(Type,AA,BB);
+           Goal = diff_real(Type,AA,BB),
+           NoNaN = 1),
+          member((Susp,diff_real_chk_nan(Type,AA,BB)),LSusp),
+          (AA == A ->
+              BB == B
+          ;   AA == B,
+              BB == A))
+        ->
+            % on factorise
+            (NoNaN == 1 ->
+                % call(spy_here)@eclipse,
+                ensure_not_NaN(A),
+                ensure_not_NaN(B)
+            ;   true)
+        ;   my_suspend(diff_real_chk_nan(Type,A,B),0,
+                       [(A,B)->suspend:constrained,
+                        Bool->suspend:inst]),
+            int_vars(bool,Bool),
+            insert_dep_inst(dep(Bool,0,[VNaN])),
+            isNaN(VNaN,Bool))),
     set_priority(P),
     wake_if_other_scheduled(P).
 
@@ -4109,7 +4150,7 @@ get_array_type(A,Type) :-
         ;   (nonvar(Type) ->
                 Type = array(TI,TE),
                 array_vars(TI,TE,Start)
-            ;   spy_here,
+            ;   % spy_here,
                 fail))).
 
 get_array_start(const_array(TI,TE,Const),Start) ?- !,
@@ -4183,11 +4224,11 @@ smtlib_select_bis(A,I,E,TypeI,TypeE) :-
         NewA = storec(_,J,_),
         ((TypeI \= sort(_),
           %var(I),var(J),
-          not is_float_int_number(I),
+          not is_float_int_number(I), % pourquoi ???
           % indice numérique
           %dvar_size(TypeI,I,SI),
           %SI =< 32,
-          suspensions(I,LS), % les contraintes sur I vont plus vite
+          suspensions(I,LS), % les contraintes pretes sur I vont plus vite
           LS \== [])
         ->
             % E et EJ ne sont pas traités mais les contraintes de J
@@ -4243,6 +4284,7 @@ smtlib_select0(Type,storec(A,J,EJ),I,E,SeenI,VarsI,NewA,Start,Suspend) ?- !,
             VarsI = SeenI,
             % I variable ou bien Ground = 0
             (SeenI == [] ->
+
                 % on a fini
                 (TypeE \= array(_,_) ->
                     protected_unify(E,VEJ)
@@ -4260,10 +4302,13 @@ smtlib_select0(Type,storec(A,J,EJ),I,E,SeenI,VarsI,NewA,Start,Suspend) ?- !,
                 % over-write, on peut ignorer cet etage sur J
                 smtlib_select0(Type,A,I,E,SeenI,VarsI,NewA,Start,Suspend)
             ;   ((TypeE \= array(_,_),
-                  not_unify(VEJ,E))
+                  not_unify(VEJ,E),
+                  CstrEJ == true)
                 ->
-                    alldiff(TypeI,[as(I,TypeI),as(J,TrypeI)]) #= as(1,bool),
+                    % cet étage peut disparaitre, le diff suffit pour échouer
+                    alldiff(TypeI,[as(I,TypeI),as(J,TypeI)]) #= as(1,bool),
                     NSeenI = SeenI,
+                    %NSeenI = [J|SeenI],
                     NewA = ENewA
                 ;   NewA = storec(ENewA,J,EJ),
                     NSeenI = [J|SeenI]),
@@ -4305,6 +4350,13 @@ check_seen_upper_index(J,SeenI) :-
         occurs(J,SeenI)
     ;   member(JJ,SeenI),
         JJ == J).
+
+diff_each_seen_upper_index(J,SeenI) :-
+    (foreach(I,SeenI),
+     param(Unif) do
+        (not_unify(I,J) ->
+            true
+        ;   Unif = 1)).
     
 
          
@@ -4479,7 +4531,7 @@ eq_clean_array(Type,Diff,A,B,Seen,SureA,SureB) :-
     eq_array0(Type,Diff,A,B,NA,_IA,Seen,SureA,Seen1,Work),
     eq_array0(Type,Diff,B,A,NB,_IB,Seen1,SureB,NSeen,Work),
     (nonvar(Work) ->
-        % on a lancee des select qui ont pu modifier
+        % on a lancé des select qui ont pu modifier
         % A ou B, SureA ou Sure B
         % on relance 
         clean_eq_array(Diff,NA,NewA,SureA,NewSureA),
@@ -6193,7 +6245,7 @@ real_vars(Type,T) :-
         (get_type(X,Type0) ->
             (RType == Type0 ->
                 true
-            ;   call(spy_here)@eclipse,
+            ;   % call(spy_here)@eclipse,
                 write(error,"Type error for variable "),
                 writeln(error,X:RType),
                 exit_block(syntax))
@@ -6257,11 +6309,17 @@ unfold_real_expr(X,_D,Cstr,Type,R) :-
       real_vars(Type,X))
     ->
         blocked_unify(X=R)
-    ;   call(spy_here)@eclipse,
+    ;   % call(spy_here)@eclipse,
         writeln(error,"Type unknown for variable":X),
         exit_block(syntax)),
     %insert_dep_inst(inst_cstr(D,X)),
     Cstr = true.
+unfold_real_expr(new_quantified_var(R0,Type0),D,Cstr,Type,R) ?- !,
+%    call(spy_here)@eclipse,
+    (nonvar(Type) ->
+        true
+    ;   real_type(Type0,Type)),
+    unfold_real_expr(R0,D,Cstr,Type,R).
 unfold_real_expr(pi,D,Cstr,Type,R) ?-
     Type = real,
     !,
@@ -6385,40 +6443,45 @@ unfold_real_expr(select(EA,EI), D, Cstr, Type, R) ?-
     make_conj(CIA,CES,Cstr).
 
 unfold_real_expr(- EA,D,Cstr,Type,R) ?-
-    ND is D + 1,
-    (check_not_NaN(R) ->
-        ensure_not_NaN(A)
-    ;   true),
-    unfold_real_expr(EA,ND,CA,Type,A),
-    !,
-    insert_dep_inst(dep(R,D,[A])),
-    real_type(Type,RType),
-    ((RType == real;
-      check_not_NaN(A);
-      check_not_NaN(R))
-    ->
-        ensure_not_NaN(A),
-        ensure_not_NaN(R),
-        make_conj(CA,op_real(RType,A,R),Cstr)
-    ;   make_conj(CA,(ensure_not_NaN((A,R)),op_real(RType,A,R)),Cstr)).
-unfold_real_expr(fp_neg(EA),D,Cstr,Type,R) ?-
-    (check_not_NaN(R) ->
+    get_norm_expr(Norm),
+    (normalize_expr(Norm,Type,-EA,D,Cstr,R,Goal) ->
         !,
-        unfold_real_expr(- EA,D,Cstr,Type,R)
+        call(Goal)
     ;   ND is D + 1,
+        (check_not_NaN(R) ->
+            ensure_not_NaN(A)
+        ;   true),
         unfold_real_expr(EA,ND,CA,Type,A),
-        unfold_int_expr(isNaN(as(A,Type)),D,Cond,bool,BCond),
         !,
+        insert_dep_inst(dep(R,D,[A])),
+        real_type(Type,RType),
+        ((RType == real;
+          check_not_NaN(A);
+          check_not_NaN(R))
+        ->
+            ensure_not_NaN(A),
+            ensure_not_NaN(R),
+            make_conj(CA,op_real(RType,A,R),Cstr)
+        ;   make_conj(CA,(ensure_not_NaN((A,R)),op_real(RType,A,R)),
+                      Cstr))),
+    set_norm_expr(Norm).
+unfold_real_expr(fp_neg(EA),D,Cstr,Type,R) ?-
+    ND is D + 1,
+    unfold_real_expr(EA,ND,CA,Type,A),
+    !,
+    ((check_not_NaN(A),
+      float(A))
+    ->
+        fp_neg(0,Type,A,R),
+        Cstr = CA
+    ;   unfold_int_expr(isNaN(as(A,Type)),D,Cond,bool,BCond),
         int_vars(bool,BCond),
         get_reif_var_depth_from_labchoice(DD),
         insert_dep_inst(inst_cstr(DD,BCond)),
         insert_dep_inst(dep(A,D,[BCond])),
         insert_dep_inst(dep(R,D,[A,BCond])),
-        (float(A) ->
-            R is -A,
-            Cstr = CA
-        ;   make_conj(CA,Cond,CACond),
-            make_conj(CACond,fp_neg(BCond,Type,A,R),Cstr))).
+        make_conj(CA,Cond,CACond),
+        make_conj(CACond,fp_neg(BCond,Type,A,R),Cstr)).
 % round to nearest integral
 unfold_real_expr(round(EA),D,Cstr,Type,R) :- !,
     unfold_real_expr(round(rne,EA),D,Cstr,Type,R).
@@ -6533,7 +6596,9 @@ unfold_real_expr(float_from_raw_uintN(EA),D,Cstr,Type,R) :-
     ;   Size == 64,
         Type = float_double),
     !,
-    (number(A) ->
+    ((number(A);
+      number(R))
+    ->
         Cstr = CA,
         blocked_call(float_from_raw_uintN(Type,A,R))
     ;   insert_dep_inst(dep(R,D,[A])),
@@ -6771,46 +6836,52 @@ unfold_real_expr(fp_abs(EA),D,Cstr,Type,R) ?-
     make_conj(CA,CR,Cstr).
 
 unfold_real_expr(EA + EB,D,Cstr,Type,R) ?-
-    ((nonvar(EA),
-      EA = - NE,
-      OE = EB;
-      nonvar(EB),
-      EB = - NE,
-      OE = EA)
-    ->
+    get_norm_expr(Norm),
+    (normalize_expr(Norm,Type,EA+EB,D,Cstr,R,Goal) ->
         !,
-        unfold_real_expr(OE - NE,D,Cstr,Type,R)
-    ;   ND is D + 1,
-        (Type == real ->
-            ensure_not_NaN((A,B,R))
-        ;   (check_not_NaN(R) ->
-                ensure_not_NaN((A,B))
-            ;   true)),
-        unfold_real_expr(EA,ND,CA,Type,A),
-        unfold_real_expr(EB,ND,CB,Type,B),
-        !,
-        ((fail,
-          nonvar(Type),
-          real_type(Type,real),
-          ((CA = (PC,op_real(_,Op,_));
-            CA = op_real(_,Op,_),
-            PC = true),
-           X = B,
-           make_conj(PC,CB,CAB);
-           (CB = (PC,op_real(_,Op,_));
-            CB = op_real(_,Op,_),
-            PC = true),
-           X = A,
-           make_conj(CA,PC,CAB)))
+        call(Goal)
+    ;   ((nonvar(EA),
+          EA = - NE,
+          OE = EB;
+          nonvar(EB),
+          EB = - NE,
+          OE = EA)
         ->
-            % X + -Op = R, pattern frequent dans QF_NIA
-            make_conj(CAB,minus_real(real,X,Op,R),Cstr),
-            insert_dep_inst(dep(R,D,[X,Op]))
-        ;   insert_dep_inst(dep(R,D,[A,B])),
-            make_conj(CA,CB,CAB),
-            (real_type(Type,real) ->
-                make_conj(CAB,add_real(real,A,B,R),Cstr)
-            ;   make_conj(CAB,(ensure_not_NaN((A,B,R)),add_real(Type,A,B,R)),Cstr)))).
+            !,
+            unfold_real_expr(OE - NE,D,Cstr,Type,R)
+        ;   ND is D + 1,
+            (Type == real ->
+                ensure_not_NaN((A,B,R))
+            ;   (check_not_NaN(R) ->
+                    ensure_not_NaN((A,B))
+                ;   true)),
+            unfold_real_expr(EA,ND,CA,Type,A),
+            unfold_real_expr(EB,ND,CB,Type,B),
+            !,
+            ((fail,
+              nonvar(Type),
+              real_type(Type,real),
+              ((CA = (PC,op_real(_,Op,_));
+                CA = op_real(_,Op,_),
+                PC = true),
+               X = B,
+               make_conj(PC,CB,CAB);
+               (CB = (PC,op_real(_,Op,_));
+                CB = op_real(_,Op,_),
+                PC = true),
+               X = A,
+               make_conj(CA,PC,CAB)))
+            ->
+                % X + -Op = R, pattern frequent dans QF_NIA
+                make_conj(CAB,minus_real(real,X,Op,R),Cstr),
+                insert_dep_inst(dep(R,D,[X,Op]))
+            ;   insert_dep_inst(dep(R,D,[A,B])),
+                make_conj(CA,CB,CAB),
+                (real_type(Type,real) ->
+                    make_conj(CAB,add_real(real,A,B,R),Cstr)
+                ;   make_conj(CAB,(ensure_not_NaN((A,B,R)),
+                                   add_real(Type,A,B,R)),Cstr))))),
+    set_norm_expr(Norm).
 unfold_real_expr(fp_add(EA,EB),D,Cstr,Type,R) ?-
     !,
     unfold_real_expr(fp_add(rne,EA,EB),D,Cstr,Type,R).
@@ -6828,29 +6899,28 @@ unfold_real_expr(fp_add(Rnd0,EA,EB),D,Cstr,Type,R) ?-
         !,
         unfold_real_expr(fp_sub(Rnd,OE,NE),D,ECstr,Type,R),
         make_conj(CRnd,ECstr,Cstr)
-    ;   ((check_not_NaN(R),
-          Rnd == rne)
+    ;   (check_not_NaN(R) ->
+            ensure_not_NaN((A,B))
+        ;   true),
+        unfold_real_expr(EA,ND,CA,Type,A),
+        unfold_real_expr(EB,ND,CB,Type,B),
+        int_vars(bool,BCond),
+        unfold_int_expr(chk_nan(isNaN(as(A,Type)) or isNaN(as(B,Type)),
+                                as(1,bool),
+                                chk_nan(isInfinite(as(A,Type)) and
+                                        isInfinite(as(B,Type)),
+                                        (as(A,Type) $\= as(B,Type)),
+                                        as(0,bool))),
+                        D,Cond,bool,BCond),
+        !,
+        ((BCond == 0,
+          nonvar(Rnd),
+          float(A),
+          float(B))
         ->
-            !,
-            make_conj(CRnd,ECstr,Cstr),
-            unfold_real_expr(EA + EB,D,ECstr,Type,R)
-        ;   (check_not_NaN(R) ->
-                ensure_not_NaN((A,B)),
-                BCond = 0
-            ;   true),
-            unfold_real_expr(EA,ND,CA,Type,A),
-            unfold_real_expr(EB,ND,CB,Type,B),
-
-            unfold_int_expr(chk_nan(isNaN(as(A,Type)) or isNaN(as(B,Type)),
-                                    as(1,bool),
-                                    chk_nan(isInfinite(as(A,Type)) and
-                                            isInfinite(as(B,Type)),
-                                            (as(A,Type) $\= as(B,Type)),
-                                            as(0,bool))),
-                            D,Cond,bool,BCond),
-            !,
-            int_vars(bool,BCond),
-            get_reif_var_depth_from_labchoice(DD),
+            make_conj(CA,CB,Cstr),
+            fp_add(0,Rnd,Type,A,B,R)
+        ;   get_reif_var_depth_from_labchoice(DD),
             insert_dep_inst(inst_cstr(DD,BCond)),
             insert_dep_inst(dep(A,D,[Rnd,BCond])),
             insert_dep_inst(dep(B,D,[Rnd,BCond])),
@@ -6861,25 +6931,33 @@ unfold_real_expr(fp_add(Rnd0,EA,EB),D,Cstr,Type,R) ?-
             make_conj(CABCond,fp_add(BCond,Rnd,Type,A,B,R),Cstr))).
 
 unfold_real_expr(EA - EB,D,Cstr,Type,R) ?-
-    ((nonvar(EB),
-      EB = - NEB)
-    ->
-        !,
-        unfold_real_expr(EA + NEB,D,Cstr,Type,R)
-    ;   ND is D + 1,
-        (Type == real ->
-            ensure_not_NaN((A,B,R))
-        ;   (check_not_NaN(R) ->
-                ensure_not_NaN((A,B))
-            ;   true)),
-        unfold_real_expr(EA,ND,CA,Type,A),
-        unfold_real_expr(EB,ND,CB,Type,B),
+    get_norm_expr(Norm),
+    (normalize_expr(Norm,Type,EA-EB,D,Cstr,R,Goal) ->
         !,
-        insert_dep_inst(dep(R,D,[A,B])),
-        make_conj(CA,CB,CAB),
-        (real_type(Type,real) ->
-            make_conj(CAB,minus_real(real,A,B,R),Cstr)
-        ;   make_conj(CAB,(ensure_not_NaN((A,B,R)),minus_real(Type,A,B,R)),Cstr))).
+        call(Goal)
+    ;   ((nonvar(EB),
+          EB = - NEB)
+        ->
+            !,
+            unfold_real_expr(EA + NEB,D,Cstr,Type,R)
+        ;   ND is D + 1,
+            (Type == real ->
+                ensure_not_NaN((A,B,R))
+            ;   (check_not_NaN(R) ->
+                    ensure_not_NaN((A,B))
+                ;   true)),
+            unfold_real_expr(EA,ND,CA,Type,A),
+            unfold_real_expr(EB,ND,CB,Type,B),
+            !,
+            insert_dep_inst(dep(R,D,[A,B])),
+            make_conj(CA,CB,CAB),
+            (real_type(Type,real) ->
+                make_conj(CAB,minus_real(real,A,B,R),Cstr)
+            ;   make_conj(CAB,(ensure_not_NaN((A,B,R)),minus_real(Type,
+                                                                  A,B,
+                                                                  R)),
+                          Cstr)))),
+    set_norm_expr(Norm).
 unfold_real_expr(fp_sub(EA,EB),D,Cstr,Type,R) ?-
     !,
     unfold_real_expr(fp_sub(rne,EA,EB),D,Cstr,Type,R).
@@ -6893,36 +6971,28 @@ unfold_real_expr(fp_sub(Rnd0,EA,EB),D,Cstr,Type,R) ?-
         !,
         unfold_real_expr(fp_add(Rnd,EA,NEB),D,ECstr,Type,R),
         make_conj(CRnd,ECstr,Cstr)
-    ;   mfd:set_intervals(Rnd,[rna,rne,rtn,rtp,rtz]),
-        ((check_not_NaN(R),
-          Rnd == rne)
-        ->
-            !,
-            make_conj(CRnd,ECstr,Cstr),
-            unfold_real_expr(EA - EB,D,ECstr,Type,R)
-        ;   (check_not_NaN(R) ->
-                ensure_not_NaN((A,B)),
-                BCond = 0
-            ;   true),
-            unfold_real_expr(EA,ND,CA,Type,A),
-            unfold_real_expr(EB,ND,CB,Type,B),
-
-            unfold_int_expr(chk_nan(isNaN(as(A,Type)) or isNaN(as(B,Type)),
-                                    as(1,bool),
-                                    chk_nan(isInfinite(as(A,Type)),
-                                            (as(A,Type) $= as(B,Type)),
-                                            as(0,bool))),
-/*
-            unfold_int_expr(chk_nan(isNaN(as(A,Type)) or isNaN(as(B,Type)),
-                                    as(1,bool),
-                                    (isInfinite(as(A,Type)) and
-                                     (as(A,Type) $= as(B,Type)))),
-*/
-                             D,Cond,bool,BCond),
-
+    ;   (check_not_NaN(R) ->
+            ensure_not_NaN((A,B))
+        ;   true),
+        unfold_real_expr(EA,ND,CA,Type,A),
+        unfold_real_expr(EB,ND,CB,Type,B),
+        int_vars(bool,BCond),
+        unfold_int_expr(chk_nan(isNaN(as(A,Type)) or isNaN(as(B,Type)),
+                                as(1,bool),
+                                chk_nan(isInfinite(as(A,Type)),
+                                        (as(A,Type) $= as(B,Type)),
+                                        as(0,bool))),
+                        D,Cond,bool,BCond),
+        
         !,
-            int_vars(bool,BCond),
-            get_reif_var_depth_from_labchoice(DD),
+        ((BCond == 0,
+          nonvar(Rnd),
+          float(A),
+          float(B))
+        ->
+            make_conj(CA,CB,Cstr),
+            fp_sub(0,Rnd,Type,A,B,R)
+        ;   get_reif_var_depth_from_labchoice(DD),
             insert_dep_inst(inst_cstr(DD,BCond)),
             insert_dep_inst(dep(A,D,[Rnd,BCond])),
             insert_dep_inst(dep(B,D,[Rnd,BCond])),
@@ -6932,6 +7002,7 @@ unfold_real_expr(fp_sub(Rnd0,EA,EB),D,Cstr,Type,R) ?-
             make_conj(CAB,Cond,CABCond),
             make_conj(CABCond,fp_sub(BCond,Rnd,Type,A,B,R),Cstr))).
 
+/*
 unfold_real_expr((EA * EB) * EC,D,Cstr,Type,R) ?-
     real_type(Type,real),
     (remove_upper_as(EA,A,_Type),
@@ -6996,38 +7067,47 @@ unfold_real_expr(EA * (EB / EC),D,Cstr,Type,R) ?-
         NExpr = (EB/EC)*EA),
     !,
     unfold_real_expr(NExpr,D,Cstr,Type,R).
+*/
 unfold_real_expr(EA * EB,D,Cstr,Type,R) ?-
-    ((nonvar(EA),
-      EA = fp_neg(NEA),
-      nonvar(EB),
-      EB = fp_neg(NEB))
-    ->
-        true
-    ;   NEA = EA,
-        NEB = EB),
-    ND is D + 1,
-    (Type == real ->
-        ensure_not_NaN((A,B,R))
-    ;   (check_not_NaN(R) ->
-            ensure_not_NaN((A,B))
-        ;   true)),
-    unfold_real_expr(NEA,ND,CA,Type,A),
-    unfold_real_expr(NEB,ND,CB,Type,B),
-    !,
-    make_conj(CA,CB,CAB),
-    ((nonvar(Type),
-      real_type(Type,real),
-      (A == -1.0,
-       Cst = A, X = B;
-       B == -1.0,
-       Cst = B, X = A))
-    ->
-        % X * -1 = R, pattern frequent dans QF_NIA
-        make_conj(CAB,op_real(real,X,R),Cstr)
-    ;   insert_dep_inst(dep(R,D,[A,B])),
-        (real_type(Type,real) ->
-            make_conj(CAB,mult_real(real,A,B,R),Cstr)
-        ;   make_conj(CAB,(ensure_not_NaN((A,B,R)),mult_real(Type,A,B,R)),Cstr))).
+    get_norm_expr(Norm),
+    (normalize_expr(Norm,Type,EA*EB,D,Cstr,R,Goal) ->
+        !,
+        call(Goal)
+    ;   ((nonvar(EA),
+          EA = fp_neg(NEA),
+          nonvar(EB),
+          EB = fp_neg(NEB))
+        ->
+            true
+        ;   NEA = EA,
+            NEB = EB),
+        ND is D + 1,
+        (Type == real ->
+            ensure_not_NaN((A,B,R))
+        ;   (check_not_NaN(R) ->
+                ensure_not_NaN((A,B))
+            ;   true)),
+        unfold_real_expr(NEA,ND,CA,Type,A),
+        unfold_real_expr(NEB,ND,CB,Type,B),
+        !,
+        make_conj(CA,CB,CAB),
+        ((nonvar(Type),
+          real_type(Type,real),
+          (A == -1.0,
+           Cst = A, X = B;
+           B == -1.0,
+           Cst = B, X = A))
+        ->
+            % X * -1 = R, pattern frequent dans QF_NIA
+            make_conj(CAB,op_real(real,X,R),Cstr)
+        ;   insert_dep_inst(dep(R,D,[A,B])),
+            (real_type(Type,real) ->
+                make_conj(CAB,mult_real(real,A,B,R),Cstr)
+            ;   make_conj(CAB,(ensure_not_NaN((A,B,R)),mult_real(Type,
+                                                                 A,B,
+                                                                 R)),
+                          Cstr)))),
+    set_norm_expr(Norm).
 unfold_real_expr(fp_mul(EA,EB),D,Cstr,Type,R) ?- !,
     unfold_real_expr(fp_mul(rne,EA,EB),D,Cstr,Type,R).
 unfold_real_expr(fp_mul(Rnd0,EA,EB),D,Cstr,Type,R) ?-
@@ -7043,42 +7123,33 @@ unfold_real_expr(fp_mul(Rnd0,EA,EB),D,Cstr,Type,R) ?-
     ;   NEA = EA,
         NEB = EB),
     (check_not_NaN(R) ->
-        ensure_not_NaN((A,B))
+        ensure_not_NaN((A,B)),
+        BCond = 0
     ;   true),
-    ((check_not_NaN(R),
-      Rnd == rne)
-    ->
-        !,
-        unfold_real_expr(NEA * NEB,D,ECstr,Type,R),
-        make_conj(CRnd,ECstr,Cstr)
-    ;   (check_not_NaN(R) ->
-            ensure_not_NaN((A,B))
-        ;   true),
-        (NEA == NEB ->
-            unfold_real_expr(NEA,ND,CAB,Type,A),
-            A = B,
-            (check_not_NaN(A) ->
-                ensure_not_NaN(R),
-                BCond = 0,
-                Cond = true
-            ;   unfold_int_expr(isNaN(as(A,Type)),D,Cond,bool,BCond))
-        ;   unfold_real_expr(NEA,ND,CA,Type,A),
-            unfold_real_expr(NEB,ND,CB,Type,B),
-            make_conj(CA,CB,CAB),
-
-            unfold_int_expr(chk_nan(isNaN(as(A,Type)) or isNaN(as(B,Type)),
-                                as(1,bool),
-                                chk_nan(isInfinite(as(A,Type)),
+    unfold_real_expr(NEA,ND,CA,Type,A),
+    unfold_real_expr(NEB,ND,CB,Type,B),
+    make_conj(CA,CB,CAB),
+    
+    unfold_int_expr(chk_nan(isNaN(as(A,Type)) or isNaN(as(B,Type)),
+                            as(1,bool),
+                            chk_nan(isInfinite(as(A,Type)),
                                     isZero(as(B,Type)),
                                     chk_nan(isInfinite(as(B,Type)),
-                                        isZero(as(A,Type)),
-                                        as(0,bool)))),
-                            D,Cond,bool,BCond)),
-        !,
-        (BCond == 0 ->
-            ensure_not_NaN((A,B,R))
-        ;   int_vars(bool,BCond)),
-        get_reif_var_depth_from_labchoice(DD),
+                                            isZero(as(A,Type)),
+                                            as(0,bool)))),
+                    D,Cond,bool,BCond),
+    !,
+    (BCond == 0 ->
+        ensure_not_NaN((A,B,R))
+    ;   int_vars(bool,BCond)),
+    ((BCond == 0,
+      nonvar(Rnd),
+      float(A),
+      float(B))
+    ->
+        Cstr = CAB,
+        fp_mul(0,Rnd,Type,A,B,R)
+    ;   get_reif_var_depth_from_labchoice(DD),
         insert_dep_inst(inst_cstr(DD,BCond)),
         insert_dep_inst(dep(A,D,[Rnd,BCond])),
         insert_dep_inst(dep(B,D,[Rnd,BCond])),
@@ -7169,33 +7240,34 @@ unfold_real_expr(fp_div(Rnd0,EA,EB),D,Cstr,Type,R) ?-
     ;   NEA = EA,
         NEB = EB),
     (check_not_NaN(R) ->
-        ensure_not_NaN((A,B)),
-        BCond = 0
+        ensure_not_NaN((A,B))
     ;   true),
     unfold_real_expr(NEA,ND,CA,Type,A),
     unfold_real_expr(NEB,ND,CB,Type,B),
     nonvar(Type),
     make_conj(CRnd,CA,CRndA),
     make_conj(CRndA,CB,CAB),
-    ((check_not_NaN(R),
-      Rnd == rne)
-    ->
-        !,
-        make_conj(CAB,div_real(Type,A,B,R),Cstr)
-    ;   unfold_int_expr(chk_nan(isNaN(as(A,Type)) or
+    unfold_int_expr(chk_nan(isNaN(as(A,Type)) or
                             isNaN(as(B,Type)),
                             as(1,bool),
                             chk_nan(isInfinite(as(A,Type)),
-                                isInfinite(as(B,Type)),
-                                chk_nan(isZero(as(A,Type)),
-                                    isZero(as(B,Type)),
-                                    as(0,bool)))),
-                        D,Cond,bool,BCond),
-        !,
-        (BCond == 0 ->
-            ensure_not_NaN((A,B,R))
-        ;   int_vars(bool,BCond)),
-        get_reif_var_depth_from_labchoice(DD),
+                                    isInfinite(as(B,Type)),
+                                    chk_nan(isZero(as(A,Type)),
+                                            isZero(as(B,Type)),
+                                            as(0,bool)))),
+                    D,Cond,bool,BCond),
+    !,
+    (BCond == 0 ->
+        ensure_not_NaN((A,B,R))
+    ;   int_vars(bool,BCond)),
+    ((BCond == 0,
+      nonvar(Rnd),
+      float(A),
+      float(B))
+    ->
+        Cstr = CAB,
+        fp_div(0,Rnd,Type,A,B,R)
+    ;   get_reif_var_depth_from_labchoice(DD),
         insert_dep_inst(inst_cstr(DD,BCond)),
         insert_dep_inst(dep(A,D,[Rnd,BCond])),
         insert_dep_inst(dep(B,D,[Rnd,BCond])),
@@ -7232,7 +7304,7 @@ unfold_real_expr(colibri_cdiv(EA,EB),D,Cstr,RType,Q) ?-
     nonvar(RType),
     real_type(RType,real),
     make_conj(CA,CB,CAB),
-    unfold_int_expr(as(0.0,RType) $= as(B,RType),ND,Cond,bool,Bool),
+    unfold_int_expr(as(0.0,RType) $\= as(B,RType),ND,Cond,bool,Bool),
     !,
     get_reif_var_depth_from_labchoice(DD),
     insert_dep_inst(inst_cstr(DD,Bool)),
@@ -7253,7 +7325,7 @@ unfold_real_expr(colibri_crem(EA,EB),D,Cstr,RType,R) ?-
     nonvar(RType),
     real_type(RType,real),
     make_conj(CA,CB,CAB),
-    unfold_int_expr(as(0.0,RType) $= as(B,RType),ND,Cond,bool,Bool),
+    unfold_int_expr(as(0.0,RType) $\= as(B,RType),ND,Cond,bool,Bool),
     !,
     get_reif_var_depth_from_labchoice(DD),
     insert_dep_inst(inst_cstr(DD,Bool)),
@@ -7796,8 +7868,432 @@ unfold_real_expr(Expr,_,_,_,_) :-
     writeln(error,"Syntax error on real expression":Expr),
     exit_block(syntax).
 
-:- local reference(real_cst).
+diff_real_float(_,A,A) ?- !,
+    fail.
+diff_real_float(real,A,B) ?- !,
+    launch_diff_real(real,A,B).
+diff_real_float(Type,nan,B) ?- !,
+    ensure_not_NaN(B).
+diff_real_float(Type,A,nan) ?- !,
+    ensure_not_NaN(A).
+diff_real_float(Type,A,B) :-
+    ((check_not_NaN(A),
+      check_not_NaN(B))
+    ->
+        launch_diff_real(Type,A,B)
+    ;   my_suspend(diff_real_float(Type,A,B),0,(A,B)->suspend:constrained)).
+
+:- setval(norm_expr,1).
+
+:- export
+   get_norm_expr/1,
+   set_norm_expr/1,
+   use_norm_expr/0,
+   no_norm_expr/0.
+
+get_norm_expr(N) :-
+    getval(norm_expr,N).
+set_norm_expr(N) :-
+    setval(norm_expr,N).
+use_norm_expr :-
+    setval(norm_expr,1).
+no_norm_expr :-
+    setval(norm_expr,0).
+
+%normalize_expr(Norm,Type,EA,D,Cstr,R,Goal) :- !,fail.
+normalize_expr(1,int,EA,D,Cstr,R,Goal) ?- !,
+    normalize_expr0(int,EA,CstNEA,NEA),
+    (NEA \== EA ->
+        true
+    ;   no_norm_expr,
+        fail),
+    Goal = (unfold_int_expr(NEA,D,Cstr0,int,R0),
+            (CstNEA == 0_1 ->
+                Cstr = Cstr0,
+                R = R0
+            ;   numerator(CstNEA,ICstNEA),
+                (is_val(R0,_) ->
+                    true
+                ;   insert_dep_inst(dep(R,D,[R0]))),
+                make_conj(Cstr0,add(ICstNEA,R0,R),Cstr))).
+
+normalize_expr(1,uint(N),EA,D,Cstr,R,Goal) ?- !,
+    normalize_expr0(uint(N),EA,CstNEA,NEA),
+    (NEA \== EA ->
+        true
+    ;   no_norm_expr,
+        fail),
+    Goal = (unfold_int_expr(NEA,D,Cstr0,uint(N),R0),
+            (CstNEA == 0_1 ->
+                Cstr = Cstr0,
+                R = R0
+            ;   numerator(CstNEA,ICstNEA),
+                CR is ICstNEA mod 2^N,
+                (is_val(R0,_) ->
+                    true
+                ;   insert_dep_inst(dep(R,D,[R0]))),
+                make_conj(Cstr0,add(uint(N),D,CR,R0,R,_),Cstr))).
+
+normalize_expr(1,Type0,EA,D,Cstr,R,Goal) ?-
+    atomic(Type0),
+    occurs(Type0,(real,real_int)),
+    real_type(Type0,Type),
+    normalize_expr0(Type,EA,CstNEA,NEA),
+    % les realString peuvent créer la <> !!
+    % on travaille trop dans ce cas
+    (NEA \== EA ->
+        true
+    ;   no_norm_expr,
+        fail),
+    Goal = (unfold_real_expr(NEA,D,Cstr0,Type,R0),
+             (CstNEA == 0_1 ->
+                 Cstr = Cstr0,
+                 R = R0
+             ;   real_from_rat(CstNEA,RCstNEA),
+                 (is_val(R0,_) ->
+                     true
+                 ;   insert_dep_inst(dep(R,D,[R0]))),
+                 make_conj(Cstr0,add_real(real,RCstNEA,R0,R),Cstr))).
+
+is_val(as(as(V,_),_),R) ?- !,
+    is_val(V,R).
+is_val(as(V,_),R) ?- !,
+    is_val(V,R).
+is_val(realString(V),R) ?- !,
+    unfold_real_expr(realString(V),_D,_Cstr,real,R).
+is_val(V,R) :-
+    number(V),
+    !,
+    R = V.
+is_val(V,R) :-
+    is_real_box_rat(V,_),
+    R = V.
+
+assoc_cst_mult(RV0,V*P,NewRV,NewP) ?-
+    is_val(V,VV),
+    !,
+    (var(VV) ->
+        is_real_box_rat(VV,RV)
+    ;   rational(VV,RV)),
+    NRV is RV0*RV,
+    assoc_cst_mult(NRV,P,NewRV,NewP).
+assoc_cst_mult(RV0,P*V,NewRV,NewP) ?-
+    is_val(V,VV),
+    !,
+    assoc_cst_mult(RV0,V*P,NewRV,NewP).
+assoc_cst_mult(RV,P,RV,P).
+
+get_Z_type(int,0).
+get_Z_type(uint(_),0).
+get_Z_type(real,0.0).
+get_Z_type(real_int,0.0).
+
+normalize_expr0(Type,EA,C,NEA) ?-
+    var(EA),
+    !,
+    C = 0_1,
+    (real_type(Type,NType) ->
+        true
+    ;   NType = Type),
+    NEA = as(EA,NType).
+normalize_expr0(Type,EA,C,NEA) :-
+    number(EA),
+    !,
+    rational(EA,C),
+    (real_type(Type,NType) ->
+        true
+    ;   NType = Type),
+    get_Z_type(NType,Z),
+    NEA = as(Z,NType).
+normalize_expr0(Treal,realString(EA),C,NEA) ?- !,
+    unfold_real_expr(realString(EA),_D,_Cstr,real,R),
+    (var(R) ->
+        % C = 0_1,
+        is_real_box_rat(R,C),
+        NEA = as(0.0,real)
+    ;   rational(R,C),
+        NEA = as(0.0,real)).
+
+normalize_expr0(_,as(EA,Type0),Cst,NEA) ?- !,
+    (real_type(Type0,Type) ->
+        true
+    ;   Type = Type0),
+    normalize_expr0(Type,EA,Cst,NEA0),
+    NEA = NEA0.
+normalize_expr0(Type,-EA,CstOpEA,OpEA) ?- !,
+    get_Z_type(Type,Z),
+    normalize_expr0(Type,as(Z,Type)-EA,CstOpEA,OpEA).
+normalize_expr0(Type,bvneg(S,EA),CstOpEA,OpEA) ?- !,
+    Type = uint(S),
+    normalize_expr0(Type,-EA,CstOpEA,OpEA).
+
+normalize_expr0(Type,(EA + EB),CstApB,EApB) ?- !,
+    normalize_expr0(Type,EA,CstA,NEA),
+    normalize_expr0(Type,EB,CstB,NEB),
+    CstApB is CstA+CstB,
+    get_Z_type(Type,Z),
+    ((NEA == as(Z,Type),
+      EApB = NEB;
+      NEB == as(Z,Type),
+      EApB = NEA)
+    ->
+        true
+    ;   EApB = NEA+NEB).
+normalize_expr0(Type,bvadd(S,EA,EB),CstApB,EApB) ?- !,
+    Type = uint(S),
+    normalize_expr0(Type,(EA + EB),CstApB,EApB).
+
+normalize_expr0(Type,(EA - EB),CstAmB,EApB) ?- !,
+    normalize_expr0(Type,EA,CstA,NEA),
+    normalize_expr0(Type,EB,CstB,NEB),
+    CstAmB is CstA-CstB,
+    get_Z_type(Type,Z),
+    ((NEA == as(Z,Type),
+      EApB = -NEB;
+      NEB == as(Z,Type),
+      EApB = NEA)
+    ->
+        true
+    ;   EApB = NEA-NEB).
+normalize_expr0(Type,bvsub(S,EA,EB),CstApB,EApB) ?- !,
+    Type = uint(S),
+    normalize_expr0(Type,(EA - EB),CstApB,EApB).
+
+normalize_expr0(Type,bvmul(S,EA,EA),CAA,AA) ?- !,
+    Type = uint(S),
+    normalize_expr0(Type,EA * EA,CAA,AA).
+normalize_expr0(Type,EA * EA,CAA,AA) ?- !,
+    CAA = 0_1,
+    AA = EA*EA.
+
+normalize_expr0(Type,bvmul(S,EA,bvmul(S,EB,EC)),C,P) ?- 
+    is_val(EA,_),
+    !,
+    Type = uint(S),
+    normalize_expr0(Type,EA * (EB * EC),C,P). 
+
+normalize_expr0(Type,EV * (EB * EC),C,P) ?- 
+    is_val(EV,V),
+    !,
+    (var(V) ->
+        is_real_box_rat(V,RV)
+    ;   rational(V,RV)),
+    get_Z_type(Type,Z),
+    (Z == V ->
+        C = 0_1,
+        P = as(Z,Type)
+    ;   normalize_expr0(Type,EB*EC,C0,P0),
+        assoc_cst_mult(RV,P0,NV,NP),
+        C is RV*C0,
+        (NV =:= 1 ->
+            P = NP
+        ;   functor(Type,FT,_),
+            (occurs(FT,(int,uint)) ->
+                numerator(NV,NRV)
+            ;   real_from_rat(NV,NRV)),
+            P = as(NRV,Type)*NP)).
+normalize_expr0(Type,EA * (EV * EC),C,P) ?- 
+    is_val(EV,V),
+    !,
+    normalize_expr0(Type,EV*(EA*EC),C,P).
+normalize_expr0(Type,EA * (EB * EV),C,P) ?- 
+    is_val(EV,V),
+    !,
+    normalize_expr0(Type,EV*(EA*EB),C,P).
+
+normalize_expr0(Type,bvmul(S,bvmul(S,EA,EB),EC),C,P) ?-  
+    is_val(EC,_),
+    !,
+    Type = uint(S),
+    normalize_expr0(Type,EC*(EA*EB),C,P).
+
+normalize_expr0(Type,(EV * EB) * EC,C,P) ?- 
+    is_val(EV,V),
+    !,
+    normalize_expr0(Type,EV*(EB*EC),C,P).
+normalize_expr0(Type,(EA * EV) * EC,C,P) ?- 
+    is_val(EV,V),
+    !,
+    normalize_expr0(Type,EV*(EA*EC),C,P).
+normalize_expr0(Type,(EA * EB) * EV,C,P) ?- 
+    is_val(EV,V),
+    !,
+    normalize_expr0(Type,EV*(EA*EB),C,P).
+
+% Distributivité
+normalize_expr0(Type,(EA*(EB+EC)),C,R) ?- 
+    is_val(EA,_),
+    once (is_val(EB,_);
+          is_val(EC,_)),
+    !,
+    normalize_expr0(Type,(EA*EB)+(EA*EC),C,R).
+normalize_expr0(Type,(EA*(EB-EC)),C,R) ?- 
+    is_val(EA,_),
+    once (is_val(EB,_);
+          is_val(EC,_)),
+    !,
+    normalize_expr0(Type,(EA*EB)-(EA*EC),C,R).
+normalize_expr0(Type,((EA+EB)*EC),C,R) ?- 
+    is_val(EC,_),
+    once (is_val(EA,_);
+          is_val(EB,_)),
+    !,
+    normalize_expr0(Type,(EA*EC)+(EB*EC),C,R).
+normalize_expr0(Type,((EA-EB)*EC),C,R) ?- 
+    is_val(EC,_),
+    once (is_val(EA,_);
+          is_val(EB,_)),
+    !,
+    normalize_expr0(Type,(EA*EC)-(EB*EC),C,R).
+
+normalize_expr0(Type,(EA*bvadd(S,EB,EC)),C,R) ?-
+    is_val(EA,_),
+    once (is_val(EB,_);
+          is_val(EC,_)),
+    !,
+    Type = uint(S),
+    normalize_expr0(Type,bvadd(S,bvmul(S,EA,EB),bvmul(S,EA,EC)),C,R).
+normalize_expr0(Type,bvmul(S,EA*bvadd(S,EB,EC)),C,R) ?- 
+    is_val(EA,_),
+    once (is_val(EB,_);
+          is_val(EC,_)),
+    !,
+    Type = uint(S),
+    normalize_expr0(Type,bvadd(S,bvmul(S,EA,EB),bvmul(S,EA,EC)),C,R).
+normalize_expr0(Type,(EA*bvsub(S,EB,EC)),C,R) ?- 
+    is_val(EA,_),
+    once (is_val(EB,_);
+          is_val(EC,_)),
+    !,
+    Type = uint(S),
+    normalize_expr0(Type,bvsub(S,bvmul(S,EA,EB),bvmul(S,EA,EC)),C,R).
+normalize_expr0(Type,bvmul(S,EA,bvsub(S,EB,EC)),C,R) ?- 
+    is_val(EA,_),
+    once (is_val(EB,_);
+          is_val(EC,_)),
+    !,
+    Type = uint(S),
+    normalize_expr0(Type,bvsub(S,bvmul(S,EA,EB),bvmul(S,EA,EC)),C,R).
+normalize_expr0(Type,(bvadd(S,EA,EB)*EC),C,R) ?- 
+    is_val(EC,_),
+    once (is_val(EA,_);
+          is_val(EB,_)),
+    !,
+    Type = uint(S),
+    normalize_expr0(Type,bvadd(S,bvmul(S,EA,EC),bvmul(S,EB,EC)),C,R).
+normalize_expr0(Type,bvmul(S,bvadd(S,EA,EB),EC),C,R) ?-  
+    is_val(EC,_),
+    once (is_val(EA,_);
+          is_val(EB,_)),
+    !,
+    Type = uint(S),
+    normalize_expr0(Type,bvadd(S,bvmul(S,EA,EC),bvmul(S,EB,EC)),C,R).
+normalize_expr0(Type,(bvsub(S,EA,EB)*EC),C,R) ?-  
+    is_val(EC,_),
+    once (is_val(EA,_);
+          is_val(EB,_)),
+    !,
+    Type = uint(S),
+    normalize_expr0(Type,bvsub(S,bvmul(S,EA,EC),bvmul(S,EB,EC)),C,R).
+normalize_expr0(Type,bvmul(S,bvsub(S,EA,EB),EC),C,R) ?-  
+    is_val(EC,_),
+    once (is_val(EA,_);
+          is_val(EB,_)),
+    !,
+    Type = uint(S),
+    normalize_expr0(Type,bvsub(S,bvmul(S,EA,EC),bvmul(S,EB,EC)),C,R).
+
+
+normalize_expr0(Type,bvmul(S,EA,EB),CAB,AB) ?- !,
+    Type = uint(S),
+    normalize_expr0(Type,(EA * EB),CAB,AB).
+normalize_expr0(Type0,(EA * EB),NCAB,NAB) ?- !,
+    real_type(Type0,Type),
+    normalize_expr0(Type,EA,CA,A),
+    normalize_expr0(Type,EB,CB,B),
+    get_Z_type(Type,Z),
+    ((nonvar(A),
+      A = as(ZA,Type),
+      ZA == Z)
+    ->
+        true
+    ;   true),
+    ((nonvar(B),
+      B = as(ZB,Type),
+      ZB == Z)
+    ->
+        true
+    ;   true),
+    functor(Type,FT,_),
+    (CA == 0_1 ->
+        (CB == 0_1 ->
+            CAB = 0_1,
+            ((nonvar(ZA);
+              nonvar(ZB))
+            ->
+                AB = as(Z,Type)
+            ;   AB = A*B)
+        ;   % A*(CB+B) = CB*A + A*B
+            CAB = 0_1,
+            (nonvar(ZA) ->
+                AB = as(Z,Type)
+            ;   (occurs(FT,(int,uint)) ->
+                    numerator(CB,RCB)
+                ;   real_from_rat(CB,RCB)),
+                (nonvar(ZB) ->
+                    AB =  as(RCB,Type)*A
+                ;   AB =  as(RCB,Type)*A+A*B)))
+    ;   (CB == 0_1 ->
+            % (CA+A)*B = CA*B + A*B
+            CAB = 0_1,
+            (nonvar(ZB) ->
+                AB = as(Z,Type)
+            ;   (occurs(FT,(int,uint)) ->
+                    numerator(CA,RCA)
+                ;   real_from_rat(CA,RCA)),
+                (nonvar(ZA) ->
+                    AB = as(RCA,Type)*B
+                ;   AB = as(RCA,Type)*B+A*B))
+        ;   CAB is CA*CB,
+            (nonvar(ZA) ->
+                (nonvar(ZB) ->
+                    AB = as(Z,Type)
+                ;   (occurs(FT,(int,uint)) ->
+                        numerator(CA,RCA)
+                    ;   real_from_rat(CA,RCA)),
+                    AB = as(RCA,Type)*B)
+            ;   (occurs(FT,(int,uint)) ->
+                    numerator(CB,RCB)
+                ;   real_from_rat(CB,RCB)),
+                (nonvar(ZB) ->
+                    AB = as(RCB,Type)*A
+                ;   (occurs(FT,(int,uint)) ->
+                        numerator(CA,RCA)
+                    ;   real_from_rat(CA,RCA)),
+                    % (CA+A)*(CB+B) = CA*CB + CA*B + A*CB + A*B
+                    AB = as(RCA,Type)*B+
+                         as(RCB,Type)*A+
+                         A*B)))),
+    (CAB =:= Z ->
+        ((remove_upper_as(EA,EA0,_),
+          remove_upper_as(EB,EB0,_),
+          AB = NEA*NEB,
+          remove_upper_as(NEA,EA1,_),
+          remove_upper_as(NEB,EB1,_),
+          EA0 == EA1,
+          EB0 == EB1)
+        ->
+            NCAB = CAB,
+            NAB = AB
+        ;   normalize_expr0(Type,AB,NCAB,NAB))
+    ;   (occurs(Type,(int,uint)) ->
+            numerator(CAB,CAB1)
+        ;   real_from_rat(CAB,CAB1)),
+        normalize_expr0(Type,as(CAB1,Type)+AB,NCAB,NAB)).
+% Pas intéressant pour "/"
+normalize_expr0(_,EA,0_1,EA).
    
+:- local reference(real_cst).
 init_real_cst :-
     hash_create(RCst),
     setval(real_cst,RCst).
@@ -9501,7 +9997,8 @@ eq_real_reif(Type,A,B,Bool) :-
         (Bool == 1 ->
             protected_unify(A,B)
         ;   % Bool = 0
-            launch_diff_real(Type,A,B))
+            diff_real_float(Type,A,B))
+%            launch_diff_real(Type,A,B))
     ;   eq_real_reif_bis(Type,A,B,Bool)).
 
 eq_real_reif_bis(Type,A,B,Bool) :-
@@ -9749,8 +10246,8 @@ float_from_raw_uintN(Type,Size,Int,Res) :-
     float_from_raw_uintN_inst(Type,Size,Int,Res,Continue),
     (var(Continue) ->
         true
-    ;   float_from_raw_uintN_rec(Type,Size,Int,Res),
-        get_saved_cstr_suspensions(LSusp),
+    ;   get_saved_cstr_suspensions(LSusp),
+        float_from_raw_uintN_rec(Type,Size,Int,Res),
         ((member((S,float_from_raw_uintN(Type,Size,IInt,R)),LSusp),
           (IInt == Int;
            Res == R,
@@ -9768,13 +10265,21 @@ check_before_susp_float_from_raw_uintN(Type,Size,Int,Res) :-
     float_from_raw_uintN_inst(Type,Size,Int,Res,Continue),
     (var(Continue) ->
         true
-    ;   my_suspend(float_from_raw_uintN(Type,Size,Int,Res),
-                   0,(Int,Res)->suspend:constrained),
-        (check_not_NaN(Res) ->
-            true
+    ;   (check_not_NaN(Res) ->
+            my_suspend(float_from_raw_uintN(Type,Size,Int,Res),
+                       0,(Int,Res)->suspend:constrained),
+            (get_sign(Res,_) ->
+                true
+            ;   % A VERIFIER SUR UnitTest QF_*BVFP* !!!
+                chk_nan(not(isZero((as(Res,Type)))),
+                        chk_nan(isNegative(as(Res,Type)),
+                                as(0.0,Type) $>= as(Res,Type),
+                                as(Res,Type) $>= as(0.0,Type)),
+                        as(1,bool)))
         ;   int_vars(bool,Bool),
-            isNaN(Res,Bool),
-            insert_dep_inst(dep(Bool,0,[])))).
+            my_suspend(float_from_raw_uintN(Type,Size,Int,Res),
+                       0,Bool->suspend:inst),
+            isNaN(Res,Bool))).
 
 float_from_raw_uintN_inst(Type,Size,Int,Res,Continue) :-
     (integer(Int) ->
@@ -10527,6 +11032,8 @@ undef_div_rem(Type,A,Q,R) :-
     protected_unify(R,A).
         
 % colibri_cdiv|crem
+% Q est l'entier arrondi vers O de A/B (truncate(A/B))
+% et A = B*Q + R
 chk_undef_cdiv_crem(Bool,A,B,Q,R) :-
     set_lazy_domain(real,A),
     set_lazy_domain(real,B),
@@ -10537,28 +11044,19 @@ chk_undef_cdiv_crem(Bool,A,B,Q,R) :-
     launch_float_int_number(B),
     launch_float_int_number(Q),
     launch_float_int_number(R),
-    save_cstr_suspensions((A,B)),
     ((nonvar(Bool);
       nonvar(B))
     ->
-        ((Bool == 1;
+        ((Bool == 0;
           B == 0.0)
         ->
-            protected_unify(Bool,1),
+            protected_unify(Bool,0),
             protected_unify(B,0.0),
             undef_cdiv_crem(A,Q,R)
-        ;   get_saved_cstr_suspensions(LSusp),
-            ((member((_,cdiv_crem(AA,BB,QQ,RR)),LSusp),
-              A == AA,
-              B == BB)
-            ->
-                protected_unify(Q,QQ),
-                protected_unify(R,RR)
-            ;   protected_unify(Bool,0),
-                % invariant
-                abs(as(R,real)) $< abs(as(B,real)),
-                cdiv_crem(A,B,Q,R)))
-    ;   get_saved_cstr_suspensions(LSusp),
+        ;   protected_unify(Bool,1),
+            cdiv_crem(A,B,Q,R))
+    ;   save_cstr_suspensions((Bool,A,B)),
+        get_saved_cstr_suspensions(LSusp),
         ((member((_,chk_undef_cdiv_crem(BBool,AA,BB,QQ,RR)),LSusp),
           A == AA,
           B == BB)
@@ -10573,7 +11071,21 @@ undef_cdiv_crem(A,Q,R) :-
     uninterp_trigger(cdiv_crem,[real],real,Trigger),
     uninterp(cdiv_crem,Trigger,[real],real,[A],(Q,R)).
 
+/*
+% def computer_division adacore
+cdiv_crem(A,B,Q,R) :-
+    get_priority(P),
+    set_priority(1),
+    ite(as(A,real) $>= as(0.0,real),
+        (as(Q,real) $= irdiv(as(A,real),as(B,real))) and
+        (as(R,real) $= irmod(as(A,real),as(B,real))),
+        (as(Q,real) $= (- irdiv((- as(A,real)),as(B,real)))) and
+        (as(Q,real) $= (- irmod((- as(A,real)),as(B,real))))),
+    set_priority(P),
+    wake_if_other_scheduled(P).
+*/
 
+% def C
 cdiv_crem(0.0,_B,Q,R) ?- !,
     protected_unify(Q,0.0),
     protected_unify(R,0.0).
@@ -10588,558 +11100,142 @@ cdiv_crem(A,B,Q,0.0) ?- !,
 cdiv_crem(A,A,Q,R) ?- !,
     protected_unify(Q,1.0),
     protected_unify(R,0.0).
-
-cdiv_crem(A,B,Q,A) ?- !,
-    % B*Q = 0 et abs(B) > abs(A)
-    (as(Q,real) $= as(0.0,real)) and (abs(as(B,real)) $> abs(as(A,real))).
 cdiv_crem(A,B,Q,R) :-
-    % B <> 0.0
     get_priority(P),
     set_priority(1),
-    save_cstr_suspensions((A,B,Q,R)),
-    % Congruences: pas de point fixe ici ?
-    % Pas de congruences pour cdiv et crem directement
-    % car div/mod inutilisables sauf dans le cas de mêmes signes ?
-    ((exists_congr(A,_,_),
-      exists_congr(B,_,_))
-    ->
-        congr_div_directe(real,A,B,Q),
-        congr_mod_directe(real,A,B,R)
-    ;   true),
-    ((exists_congr(B,CB,MB),
-      exists_congr(Q,CQ,MQ))
-    ->
-        congr_mult(CB,MB,CQ,MQ,CBQ,MBQ),
-        (exists_congr(A,CA,MA) ->
-            % R = A - BQ
-            inv_congr_add(CA,MA,CBQ,MBQ,CR,MR),
-            launch_congr(R,CR,MR)
-        ;   true),
-        (exists_congr(R,NCR,NMR) ->
-            % A = BQ + R
-            congr_add(CBQ,MBQ,NCR,NMR,NCA,NMA),
-            launch_congr(A,NCA,NMA)
-        ;   true)
-    ;   true),
-    check_exists_cdiv_crem(A,B,Q,R,Continue),
-    (var(Continue) ->
-        true
-    ;   (not_unify(R,0.0) ->
-            % donc A <> 0.0 et B ne divise pas A
-            mreal:dvar_remove_element(A,0.0)
-        ;   true),
-        (Q == 0.0 ->
-            protected_unify(A,R)
-        ;   true),
-        (A == R ->
-            protected_unify(Q,0.0)
-        ;   true),
-        (not_unify(A,R) ->
-            launch_diff_real(real,Q,0.0)
-        ;   true),
-        % A est du signe de R
-        mreal:dvar_range(R,LR,HR),
-        (LR >= 0.0 ->
-            mreal:dvar_remove_smaller(A,0.0)
-        ;   (HR =< 0.0 ->
-                mreal:dvar_remove_greater(A,0.0)
-            ;   mreal:dvar_range(A,LA,HA),
-                (LA >= 0.0 ->
-                    mreal:dvar_remove_smaller(R,0.0)
-                ;   (HA =< 0.0 ->
-                        mreal:dvar_remove_greater(R,0.0)
-                    ;   true)))),
-        (get_sign(B,SB) -> % <> 0
-            mreal:dvar_range(A,NLA,NHA),
-            (NLA >= 0.0 ->
-                SA = pos
-            ;   (NHA =< 0.0 ->
-                    SA = neg
-                ;   true)),
-            (SB == pos ->
-                % A et Q de meme signe ou nuls
-                (nonvar(SA) ->
-                    (SA == pos ->
-                        mreal:dvar_remove_smaller(Q,0.0)
-                    ;   mreal:dvar_remove_greater(Q,0.0))
-                ;   mreal:dvar_range(Q,LQ,HQ),
-                    ((LQ >= 0.0,
-                      SQ = pos;
-                      HQ =< 0.0,
-                      SQ = neg)
-                     ->
-                        (SQ == pos ->
-                            mreal:dvar_remove_smaller(A,0.0)
-                        ;   mreal:dvar_remove_greater(A,0.0))
-                    ;   true))
-            ;   % A et Q de signes opposes ou nuls
-                (nonvar(SA)->
-                    (SA == pos ->
-                        mreal:dvar_remove_greater(Q,0.0)
-                    ;   mreal:dvar_remove_smaller(Q,0.0))
-                ;   mreal:dvar_range(Q,LQ,HQ),
-                    ((LQ >= 0.0,
-                      SQ = pos;
-                      HQ =< 0.0,
-                      SQ = neg)
-                     ->
-                        (SQ == pos ->
-                            mreal:dvar_remove_greater(A,0.0)
-                        ;   mreal:dvar_remove_smaller(A,0.0))
-                    ;   true)))
-        ;   % on attend B signé
-            true),
-        ((not_unify(A,0.0),
-          not_unify(R,0.0))
-        ->
-            NZAR = 1,
-            ensure_real_absR_leq_absA(R,A,Q)
-        ;   true),
-        refute_real_A_equals_R(A,B,Q,R),
-        % au cas où
-        cdiv_crem_inst_free(A,B,Q,R,Continue1),
-        (var(Continue1) ->
-            true
-        ;   cdiv_crem_rec(A,B,Q,R),
-            (((%not_inf_bounds(A);
-               is_inside_mantissa(float_double,A);
-               is_real_box_rat(A,_RA)),
-              (%not_inf_bounds(B);
-               is_inside_mantissa(float_double,B);
-               is_real_box_rat(B,_RB)))
-            ->
-                % délégation aux entiers bornés
-                cast_real_int(real,A,IA),
-                cast_real_int(real,B,IB),
-                div_mod(IA,IB,IQ,IR),
-                cast_int_real(real,IQ,Q),
-                cast_int_real(real,IR,R)
-            ;   ((nonvar(B),
-                  nonvar(R),
-                  not_zero(A))
-                ->
-                    as(A,Real) $= (as(B,real)*as(Q,Real)) + as(R,real)
-                ;   (nonvar(SB) ->
-                        Prio = 4
-                    ;   Prio = 5),
-                    term_variables((A,B,Q,R),Vars),
-                    my_suspend(cdiv_crem(A,B,Q,R),
-                               Prio,
-                               Vars->suspend:constrained))))),
+    set_lazy_domain(real,RQ),
+    % en C: B <> 0 et Q = truncate(A/B) et A = B*Q + R
+    div_real(real,A,B,RQ),
+    truncate(real,RQ,Q),
+    set_lazy_domain(real,BQ),
+    launch_float_int_number(BQ),
+    mult_real(real,B,Q,BQ),
+    % A = BQ + R
+    add_real(real,BQ,R,A),
+    % cas à gérer explicitement pour forcer
+    % les signes de A et B 
+    chk_nan(as(A,real) $= as(0.0,real),
+            (as(Q,real) $= as(0.0,real)) and 
+            (as(R,real) $= as(0.0,real)),
+            chk_nan(as(A,real) $> as(0.0,real),
+                    chk_nan(as(B,real) $> as(0.0,real),
+                            as(Q,real) $>= as(0.0,real),
+                            as(Q,real) $=< as(0.0,real)),
+                    chk_nan(as(B,real) $> as(0.0,real),
+                            as(Q,real) $=< as(0.0,real),
+                            as(Q,real) $>= as(0.0,real)))),
+    check_cdiv_crem(A,B,Q,BQ,R),
     set_priority(P),
     wake_if_other_scheduled(P).
 
-ensure_real_absR_leq_absA(R,A,Q) :- !,
-    % A,R <> 0
-    (not_unify(Q,0.0) ->
-        abs(as(R,real)) $< abs(as(A,real))
-    ;   abs(as(R,real)) $=< abs(as(A,real))).
 
-/*
-ensure_real_absA_lt_absB(A,B) :-
-    A \== B,
-    % B <> 0,
-    (number(A) ->
-        (number(B) ->
-            abs(A) < abs(B)
-        ;   OpA is -A,
-            (A >= 0.0 ->
-                RInt = [OpA..A]
-            ;   RInt = [A..OpA]),
-            mreal:get_intervals(B,IntB),
-            mreal:finterval_difference(float_double,IntB,RInt,NIntB),
-            set_typed_intervals(B,real,NIntB))
-    ;   (number(B) ->
-            (B > 0.0 ->
-                Bp is B - 1.0,
-                OpBp is -Bp,
-                IntA = OpBp..Bp
-            ;   % B < 0,
-                Bm is B + 1.0,
-                OpBm is -Bm,
-                IntA = Bm..OpBm),
-            set_typed_intervals(A,real,[IntA])
-        ;   mreal:dvar_range(A,LA,HA),
-            ((get_sign(B,SB),
-              once (HA =< 0.0,
-                    SA = neg;
-                    LA >= 0.0,
-                    SA = pos))
-            ->
-                (SA == SB ->
-                    % A et B de meme signe
-                    (SA == pos ->
-                        % pos x pos
-                        launch_gt_real(real,B,A)
-                    ;   % neg x neg
-                        launch_gt_real(real,A,B))
-                ;   (SA == pos ->
-                        % SB = neg, OpB pos donc A < OpB
-                        op_real(real,B,OpB),
-                        launch_gt_real(real,OpB,A)
-                    ;   % SA = Neg, OpA pos donc OpA < B
-                        op_real(real,A,OpA),
-                        launch_gt_real(real,B,OpA)))
-            ;   ((get_rel_between_real_args(A,B,Rel),
-                  Rel \== '#',
-                  Rel \== '?')
-                ->
-                    (occurs(Rel,('>','>='))	->
-                        % |A| < |B| et A >= B
-                        % si B positif alors |A| >= |B| -> fail
-                        % donc B negatif
-                        mreal:dvar_remove_greater(B,-1.0)
-                    ;   % occurs(Rel,('<','=<'))
-                        % |A| < |B| et A =< B
-                        % si A negatif alors B positif et
-                        % si A positif alors B positif
-                        mreal:dvar_remove_smaller(B,1.0))
-                ;   true),
-                % On fait le menage dans A gt(abs(B),abs(A))
-                % absmin(A) < absmin(B),
-                % On peut retirer de B -MinAbsA..MinAbsA
-                mreal:mindomain(A,MinA),
-                mreal:get_intervals(A,IntA),
-                real_abs_min(IntA,MinA,MinAbsA),
-                OpMinAbsA is -MinAbsA,
-                RInt = [OpMinAbsA..MinAbsA],
-                mreal:get_intervals(B,IntB),
-                mreal:finterval_difference(float_double,IntB,RInt,NIntB),
-                set_typed_intervals(B,real,NIntB),
-                % absmax(A) < absmax(B),
-                % On peut retirer de A -MaxAbsB..MaxAbsB
-                mreal:dvar_range(B,MinB,MaxB),
-                AbsMaxBm1 is max(abs(MinB),abs(MaxB))-1.0,
-                OpAbsMaxBm1 is - AbsMaxBm1,
-                mreal:dvar_remove_smaller(A,OpAbsMaxBm1),
-                mreal:dvar_remove_greater(A,AbsMaxBm1)))).
-*/
+check_cdiv_crem(A,B,Q,BQ,R) :-
+    get_priority(P),
+    set_priority(1),
+    check_cdiv_crem1(A,B,Q,BQ,R),
+    set_priority(P),
+    wake_if_other_scheduled(P).
 
-real_abs_min([],AbsMin,AbsMin).
-real_abs_min([Int|LInt],Abs,AbsMin) :-
-    min_max_inter(Int,Min,Max),
-    (Min >= 0.0 ->
-        AbsMin is min(Abs,Min)
-    ;   % Min < 0
-        (Max =< 0.0 ->
-            NAbs is abs(Max),
-            real_abs_min(LInt,NAbs,AbsMin)
-        ;   % Max > 0
-            AbsMin = 0.0)).
-
-%cdiv_crem_rec(A,B,Q,R) :- !.
-cdiv_crem_rec(A,B,Q,R) :-
-    mult_real_interval(real,B,Q,BQ),
-    cdiv_crem_rec(3,A,B,BQ,Q,R).
-
-cdiv_crem_rec(0,A,B,BQ,Q,R) ?- !.
-cdiv_crem_rec(N,A,B,BQ,Q,R) :-
-    % A = B*Q + R
-    (var(A) ->
-        mreal:get_intervals(A,IA),
-        add_real_interval(real,BQ,R,A),
-        check_red_inter(A,IA,Red)
-    ;   true),
-    (var(R) ->
-        mreal:get_intervals(R,IR),
-        minus_real_interval(real,A,BQ,R),
-        check_red_inter(R,IR,Red)
-    ;   true),
-    (var(BQ) ->
-        mreal:get_intervals(BQ,IBQ),
-        minus_real_interval(real,A,R,BQ),
-        check_red_inter(BQ,IBQ,Red)
-    ;   true),
-    ((not_zero(Q),
-      var(B))
+check_cdiv_crem1(A,B,Q,BQ,A) ?- !,
+    protected_unify(BQ,0.0),
+    protected_unify(Q,0.0).
+check_cdiv_crem1(A,B,Q,BQ,R) :-
+    nonvar(A),
+    nonvar(B),
+    !,
+    div_real(real,A,B,RQ),
+    truncate(real,RQ,Q),
+    mult_real(real,B,Q,BQ),
+    add_real(real,BQ,R,A).
+check_cdiv_crem1(A,B,Q,BQ,R) :-
+    ((not not_zero(A),
+      not not_zero(Q),
+      (nonvar(A);
+       is_real_box_rat(A,_)),
+      (nonvar(B);
+       is_real_box_rat(B,_)))
     ->
-        mreal:get_intervals(B,IB),
-        div_real_interval(real,BQ,Q,B),
-        check_red_inter(B,IB,Red)
-    ;   true),
-    (var(Q) ->
-        mreal:get_intervals(Q,IQ),
-        div_real_interval(real,BQ,B,Q),
-        check_red_inter(Q,IQ,Red)
-    ;   true),
-    (var(BQ) ->
-        mreal:get_intervals(BQ,NIBQ),
-        mult_real_interval(real,B,Q,BQ),
-        check_red_inter(BQ,NIBQ,Red)
-    ;   true),
-    (var(Red) ->
         true
-    ;   NN is N - 1,
-        cdiv_crem_rec(NN,A,B,BQ,Q,R)).
-
-check_red_inter(V,IV,1) ?- !.
-check_red_inter(V,IV,Red) :-
-    mreal:get_intervals(V,NIV),
-    (NIV == IV ->
-        true
-    ;   Red = 1).
-
-% pour unsat.issue35.smt
-refute_real_A_equals_R(A,B,Q,R) :-
-    getval(refutation_chk,0)@eclipse,
-    !,
-    % A et R de meme signe et <> 0.0
-    setval(refutation_chk,1)@eclipse,
-    set_priority(4),
-    block((not (protected_unify(Q,0.0),
-                protected_unify(A,R),
-                wake)
-          ->
-              setval(refutation_chk,0)@eclipse,
-              set_priority(1),
-              launch_diff_real(real,A,R),
-              mreal:dvar_remove_element(Q,0.0),
-              force_lin_solve_var(A)
-          ;   (not (diff_real(real,A,R),
-                    mreal:dvar_remove_element(Q,0.0),
-                    wake)
-              ->
-                  setval(refutation_chk,0)@eclipse,
-                  set_priority(1),
-                  protected_unify(Q,0.0),
-                  protected_unify(A,R),
-                  force_lin_solve_var(A)
-              ;   (not_zero(A) ->
-                      setval(refutation_chk,0)@eclipse,
-                      set_priority(1)
-                  ;   (not (protected_unify(A,0.0),
-                            protected_unify(R,0.0),
-                            protected_unify(Q,0.0),
-                            wake)
-                      ->
-                          call(spy_here)@eclipse,
-                          setval(refutation_chk,0)@eclipse,
-                          set_priority(1),
-                          launch_diff_real(real,A,0.0)
-                      ;   setval(refutation_chk,0)@eclipse,
-                          set_priority(1))))),
-          Tag,
-          (setval(refutation_chk,0)@eclipse,
-           set_priority(1),
-           exit_block(Tag))),
-    % pour unsat/issue35.smt2 ????
-    get_cstr_suspensions(A,LA),
-    get_cstr_suspensions(B,LB),
-    get_cstr_suspensions(R,LR),
-    append(LA,LB,LAB),
-    append(LR,LAB,LS),
-    %get_saved_cstr_suspensions(LS),
-    (foreach(Susp,LS) do
-        (get_suspension_data(Susp,goal,add_real1(real,X,Y,Z)) ->
-            check_add_op_real(real,X,Y,Z)
+    ;   % A FAIRE: anti_congr,gestion des opposés ...
+        save_cstr_suspensions((A,B,Q,BQ,R)),
+        get_saved_cstr_suspensions(LS1),
+        attached_suspensions(cdcr,LST),
+        (foreach(S,LST),
+         fromto(LS1,ILS,OLS,LS) do
+            (get_suspension_data(S,goal,GS) ->
+                OLS = [(S,GS)|ILS]
+            ;   OLS = ILS)),
+        (foreach((S,G),LS),
+         foreach(Unif,LUnif),
+         param(A,B,Q,BQ,R) do
+            (G = check_cdiv_crem(AA,BB,QQ,BBQQ,RR) ->
+                (AA == A ->
+                    (BB == B ->
+                        % factorisation
+                        Stop = 1,
+                        Unif = (protected_unify(Q,QQ),
+                                protected_unify(BQ,BBQQ),
+                                protected_unify(R,RR))
+                    ;   (RR == R ->
+                            % R = A - BBQQ et R = A - BQ
+                            % donc BBQQ = BQ
+                            (QQ == Q ->
+                                % R = A - BBQ et R = A - BQ
+                                % donc BB == B
+                                Stop =  1,
+                                Unif = (protected_unify(B,BB),
+                                        protected_unify(BQ,BBQQ))
+                            ;   % ?
+                                Unif = protected_unify(BQ,BBQQ))
+                        ;   ((is_op_real(real,B,OpB),
+                              BB == OpB)
+                            ->
+                                Stop = 1,
+                                unif = (set_lazy_domain(real,QQ),
+                                        op_real_bis(real,Q,QQ),
+                                        protected_unify(R,RR))
+                            ;   BBQQ == BQ,
+                                % R = A - BQ et RR = A - BQ
+                                Stop = 1,
+                                Unif = protected_unify(R,RR))))
+                ;   ((is_op_real(real,A,OpA),
+                      AA == OpA)
+                    ->
+                        (B == BB ->
+                            % RR = OpA - BQQ  et  R = A -BQ
+                            % truncate(A/B) = Q
+                            % truncate(-A/B) = -truncate(A/B),
+                            % donc QQ = -Q et BQQ = -BQ
+                            % donc RR = OpA + BQ
+                            % donc RR = -R
+                            Stop = 1,
+                            Unif = (set_lazy_domain(real,Q,QQ),
+                                    op_real_bis(real,Q,QQ),
+                                    set_lazy_domain(real,RR),
+                                    op_real_bis(real,R,RR))
+                        ;   ((is_op_real(real,B,OpB),
+                              BB == OpB)
+                            ->
+                                % RR = OpA - opBQQ  et  R = A -BQ
+                                % truncate(A/B) = truncate(-A/-B) = Q,
+                                % donc QQ = Q et opBQQ = -BQ
+                                % donc RR = OpA + BQ
+                                % donc RR = -R
+                                Stop = 1,
+                                Unif = (protected_unify(Q,QQ),
+                                        set_lazy_domain(real,BBQQ),
+                                        op_real_bis(real,BQ,BBQQ),
+                                        set_lazy_domain(real,RR),
+                                        op_real_bis(real,R,RR))
+                            ;   Unif = true))
+                    ;    Unif = true))
+            ;   Unif = true)),
+        (foreach(U,LUnif) do
+            call_priority(U,2)),
+        (var(Stop) ->
+            my_suspend(check_cdiv_crem(A,B,Q,BQ,R),0,
+                       [trigger(cdcr),(A,B,Q,BQ,R)->suspend:constrained])
         ;   true)).
-refute_real_A_equals_R(A,B,Q,R).
-
-check_add_op_real(Type,A,B,C) :-
-    ((var(A),
-      get_sign(A,SA),
-      var(B),
-      get_sign(B,SB),
-      % var(C)
-      get_sign(C,SC),
-      op_sign(SB,SA),
-      (SC == SA ->
-          % abs(A) >= abs(B)
-          check_add_op_real(Type,SC,A,B,C,Goal)
-      ;   SC == SB,
-          % abs(B) >= abs(A)
-          check_add_op_real(Type,SC,B,A,C,Goal)))
-    ->
-        call(Goal)
-    ;   true).
-
-check_add_op_real(Type,SC,A,B,C,Goal) :-
-    % SC + SB -> SC
-    % si C pos alors A pos, B neg et A >= op(B)
-    % si C neg alors A neg, B pos et op(A) >= B
-    (not_zero(C) ->
-        Rel = '>'
-    ;   Rel = '>='),
-    (SC == pos ->
-        (has_op_real(B,OpB) ->
-            call(spy_here)@eclipse,
-            Goal = launch_real_ineq(Rel,Type,A,OpB)
-        ;   % si C pos alors A pos, B neg et op(A) =< B
-            has_op_real(A,OpA),
-            Goal = launch_real_ineq(Rel,Type,B,OpA))
-    ;   SC == neg,
-        (has_op_real(A,OpA) ->
-            Goal = launch_real_ineq(Rel,Type,OpA,B)
-        ;   % si C neg alors A neg, B pos et A =< op(B)
-            has_op_real(B,OpB),
-            Goal = launch_real_ineq(Rel,Type,OpB,A))).
-
-has_op_real(Var,OpVar) :-
-    suspensions(Var,LSusp),
-    Goal = op_real1(_,X,OpX),
-    member(Susp,LSusp),
-    get_suspension_data(Susp,goal,Goal),
-    (Var == X ->
-        OpVar = OpX
-    ;   Var == OpX,
-        OpVar = X),
-    !.
-
-cdiv_crem_inst_free(A,B,Q,R,Continue) :-
-    (A == 0.0 ->
-        protected_unify(Q,0.0),
-        protected_unify(R,0.0)
-    ;   (B == 1.0 ->
-            protected_unify(A,Q),
-            protected_unify(R,0.0)
-        ;   (B == -1.0 ->
-                op_real(real,A,Q),
-                protected_unify(R,0.0)
-            ;   (A == B ->
-                    protected_unify(Q,1.0),
-                    protected_unify(R,0.0)
-                ;   (A == R ->
-                        % BQ = 0 donc Q = 0
-                        abs_val_real(real,A,AbsA),
-                        abs_val_real(real,B,AbsB),
-                        gt_real(real,AbsB,AbsA),
-                        protected_unify(Q,0.0)
-                    ;   (Q == 0.0 ->
-                            abs_val_real(real,A,AbsA),
-                            abs_val_real(real,B,AbsB),
-                            gt_real(real,AbsB,AbsA),
-                            protected_unify(A,R)
-                        ;   % convergence lente sur cdiv_test_zero_sat.smt2
-                            % car on manque des congruences ici
-                            % A ajouter/adapter ?
-                            (R == 0.0 ->
-                                mult_real(real,B,Q,A)
-                            ;   cdiv_crem_inst(A,B,Q,R,Continue)))))))).
-cdiv_crem_inst(A,B,Q,R,Continue) :-
-    (check_rbox_rat(A,RA) ->
-        (check_rbox_rat(B,RB) ->
-            integer(RA,IA),
-            integer(RB,IB),
-            IQ is IA // IB,
-            IR is IA rem IB,
-            rational(IQ,RQ),
-            launch_box_rat(Q,RQ),
-            rational(IR,RR),
-            launch_box_rat(R,RR)
-        ;   ((check_rbox_rat(Q,RQ),
-              check_rbox_rat(R,RR))
-            ->
-                integer(RA,IA),
-                integer(RQ,IQ),
-                integer(RR,IR),
-                IBQ is IA - IR,
-                IB is IBQ // IQ,
-                % parano
-                mult(IB,IQ,IBQ),
-                %IQ is IA // IB,
-                IR is IA rem IB,
-                rational(IB,RB),
-                launch_box_rat(B,RB)
-            ;   Continue = 1))
-    ;   ((check_rbox_rat(B,RB),
-          check_rbox_rat(Q,RQ),
-          check_rbox_rat(R,RR))
-        ->
-            integer(RB,IB),
-            integer(RQ,IQ),
-            integer(RR,IR),
-            IA is IB*IQ + IR,
-            % parano
-            IQ is IA // IB,
-            IR is IA rem IB,
-            rational(IA,RA),
-            launch_box_rat(A,RA)
-        ;   Continue = 1)).
-
-check_exists_cdiv_crem(A,B,Q,R,Suspend) :-
-    get_saved_cstr_suspensions(LSusp),
-    ((member((_,cdiv_crem(AA,BB,QQ,RR)),LSusp),
-      (AA == A; BB == B),
-      (B == BB ->
-          (A == AA;
-           Q == QQ,
-           R == RR)
-      ;   A == AA,
-          Q == QQ,
-          R == RR,
-          (not_zero(Q) ->
-              true
-          ;   exists_diff_Rel(B,BB),
-              ZQ = 1)))
-    ->
-        (nonvar(ZQ) ->
-            Suspend = 1,
-            % A = B*Q + R, A = BB*Q + R et B <> BB
-            % donc B*Q = BB*Q avec B et BB <> 0.0
-            % et donc Q = 0.0 et A = R
-            protected_unify(Q,0.0),
-            protected_unify(BQ,0.0),
-            protected_unify(A,R)
-        ;   % Factorisation
-            protected_unify(A,AA),
-            protected_unify(B,BB),
-            protected_unify(Q,QQ),
-            protected_unify(R,RR))
-    ;   % issue 40: cas diviseur <> 0
-        % abs(X) = abs(A), abs(Y) = abs(B) =>
-        %   abs(X // Y) = abs(A // B) et abs(X rem Y) = abs(A rem B)
-        % capture aussi les 3 propagateurs suivants
-        % A // B = Q et -A // B = -Q et R = -RR
-        % A // B = Q et A // -B = -Q et R = RR
-        % A // B = Q et -A // -B = Q et R = -RR
-        ((once (member_begin_end((_,cdiv_crem(X,Y,QQ,RR)),LSusp,LSusp1,E1,E1),
-                same_abs(real,A,X,LSusp1,RelAX,LSusp2),
-                same_abs(real,B,Y,LSusp2,RelBY,_));
-          (var(A) ->
-              Var = A
-          ;   Var = B),
-          once (member((AbsOpVar,Rel1),[(abs_val_real1(real,V,OpAbsV),abs),
-                                        (op_real1(real,V,OpAbsV),op)]),
-                member_begin_end((_,AbsOpVar),LSusp,LSusp1,E1,E1),
-                (Var == V, NVar = OpAbsV;
-                 Var == OpAbsV, NVar = V)),
-          get_cstr_suspensions(NVar,NLSusp),
-          once (member(Susp,NLSusp),
-                get_suspension_data(Susp,goal,cdiv_crem(X,Y,QQ,RR)),
-                (var(A) ->
-                    % same_abs(A,X)
-                    RelAX = Rel1,
-                    same_abs(real,B,Y,LSusp,RelBY,_)
-                ;   % same_abs(B,Y),
-                    RelBY = Rel1,
-                    same_abs(real,A,X,LSusp,RelAX,_))))
-        ->
-            (RelAX == op ->
-               % A et R de même signe
-                op_real(real,R,RR),
-                (RelBY == eq ->
-                    % A // B = Q et -A // B = -Q et R = -RR
-                    op_real(real,Q,QQ)
-                ;   (RelBY == op ->
-                        % A // B = Q et -A // -B = Q et R = -RR
-                        protected_unify(Q,QQ)
-                    ;   % abs
-                        abs_val(Q,AQ),
-                        abs_val(QQ,AQ)))
-            ;   (RelAX == eq ->
-                    % A et R de même signe
-                    protected_unify(R,RR),
-                    (RelBY == op ->
-                        % A // B = Q et A // -B = -Q et R = RR
-                        op_real(real,Q,QQ)
-                    ;   abs_val(Q,AQ),
-                        abs_val(QQ,AQ))
-                ;   abs_val_real(real,Q,AQ),
-                    abs_val_real(real,QQ,AQ),
-                    abs_val_real(real,R,AR),
-                    abs_val_real(real,RR,AR))),
-            Suspend = 1
-        ;   Suspend = 1)).
 
 same_abs(Type,A,X,LSusp,Rel,NLSusp) :-
     (Type = real ->
@@ -11176,6 +11272,7 @@ same_abs(Type,A,X,LSusp,Rel,NLSusp) :-
           ;   A == Y,
               B == X)).
 
+
 chk_min_real(1,_Type,_A,_B,R) ?- !,
     protected_unify(R,nan).
 chk_min_real(_NaN,_Type,nan,B,R) ?- !,
@@ -11779,6 +11876,7 @@ get_range(V,_,V,V).
    ;   (local reference(new_dep))).
 
 solve_cstrs :-
+    % use_3B,
     % la TRIGO peut désactiver le simplex
     getval(use_simplex,US)@eclipse,
     garbage_collect,
@@ -11791,16 +11889,24 @@ solve_cstrs :-
     (DepConstraints \= [] ->
         clear_single_inst_cstr(DepConstraints,NDepConstraints),
         build_single_use_list(NDepConstraints,NSplitUseList),
-        (solve_cstrs_list([NSplitUseList]) ->
-            setval(use_simplex,US)@eclipse
-        ;   setval(use_simplex,US)@eclipse,
-            fail),
+        delayed_goals(DGS),
+        (DGS == [] ->
+            % on peut ignorer les quantificateurs
+            setval(quantifier,0)@colibri
+        ;   % term_variables(DGS,VDGs),
+            (solve_cstrs_list([NSplitUseList]) ->
+                setval(use_simplex,US)@eclipse
+            ;   setval(use_simplex,US)@eclipse,
+                fail)),
+        % show_vdgs(VDGs),
         % Si on continue dans la ligne de requete
         init_dep_constraints(_NPC)
     ;   true),
     attached_suspensions(diff_array,LS),
     (foreach(S,LS) do kill_suspension(S)).
 
+show_vdgs(_).
+
 try_noNaN :-
     attached_suspensions(isNaN,LS),
     (foreach(S,LS) do
@@ -11822,7 +11928,8 @@ add_last_var_fail(Var) :-
         getval(last_var_fail,LVN)@eclipse,
         append(LVN,[VN],NLVN),
         setval(last_var_fail,NLVN)@eclipse
-    ;   call(spy_here)@eclipse).
+    ;   % call(spy_here)@eclipse,
+        true).
     
 solve_cstrs_list([]) :- !,
     % on peut avoir un wake_lin_solve qui "traine"
@@ -11841,12 +11948,15 @@ solve_cstrs_list([UseList|SplitUseList]) :-
 
 solve_cstrs2(UseList,CVars,D) :-
     call(smt_check_disabled_delta)@eclipse,
+    % ça a l'air utile de voir si on a des réductions supplémentaires
+    % en essayant les sous-intervalles des variables
+    try_vars_sub_intervals,
     % on peut avoir un wake_lin_solve qui "traine"
     trigger(lin_solve),
     % Problème à voir sur sat/bignum_lia2.smt2 avec mult_real ?
     lin_solve(Status),
     ((Status == solved,
-      spy_here@eclipse,
+      % spy_here@eclipse,
       getval(gdbg,1)@eclipse)
     ->
         writeln(output,Status)
@@ -12173,6 +12283,7 @@ choose_fd_var(UseList0,Var,Size,NUseList) :-
 
     % NMinVars = MinVars,
 
+    %leaf_var_with_max_cstr_min_dom(MinVars,Leaves,Var0,Size0),
     leaf_var_with_max_cstr_min_dom(MinVars,[],Var0,Size0),
     (is_real_pow_prod_res(Var0,Size0,Var,Size) ->
         true
@@ -12594,7 +12705,8 @@ leaf_var_with_max_cstr_min_dom(L,Leaves,Var,MinSize) :-
         ;   OL = IL)),
     (Leaves == [] ->
         var_with_max_cstr_min_dom(NL,Var,MinSize)
-    ;   NL = [NV|ENL],
+    ;   %Leaves = [NV|ENL]
+        NL = [NV|ENL],
         get_type(NV,Type),
         dvar_size_check_real(Type,NV,Size0),
         (ENL == [] ->
@@ -12604,8 +12716,8 @@ leaf_var_with_max_cstr_min_dom(L,Leaves,Var,MinSize) :-
                 Leaf = 1
             ;   true),
             constraints_number(NV,NbV0),
-            leaf_var_with_max_cstr_min_dom0(ENL,Leaves,NV,NbV0,Size0,Leaf,
-                                            Var,MinSize))).
+            %leaf_var_with_max_cstr_min_dom0(Leaves,Leaves,NV,NbV0,Size0,Leaf,Var,MinSize)
+            leaf_var_with_max_cstr_min_dom0(ENL,Leaves,NV,NbV0,Size0,Leaf,Var,MinSize))).
 
 leaf_var_with_max_cstr_min_dom0([V|LV],Leaves,Var0,NbV0,Size0,Leaf0,Var,MinSize) :-
     (((occurs(V,Leaves) ->
@@ -12822,7 +12934,7 @@ simple_solve_var_type(sort(_),Var,_) ?- !,
     simple_solve_var_sort(Var).
 simple_solve_var_type(T,Var,_) :-
     writeln(pb_simple_solve_var_type(T,Var)),
-    call(spy_here)@eclipse,
+    % call(spy_here)@eclipse,
     exit_block(abort).
 
 simple_solve_var_sort(Var) :-
@@ -12832,8 +12944,8 @@ simple_solve_var_sort(Var) :-
 
 simple_solve_var_float(Type,Var) :-
     call_priority(
-       (Var = -0.0;
-        Var = 0.0;
+       (Var = 0.0;
+        Var = -0.0;
         forbid_zero(Type,Var),
         simple_resol_float(Var)),
        1).
@@ -12902,7 +13014,8 @@ simple_resol_int1(Int) :-
             (   protected_unify(Int,Min0)
             ;   mfd:dvar_remove_element(Int,Min0),
                 protected_unify(Int,Max0)
-            ;   mfd:dvar_remove_element(Int,Max0),
+            ;   mfd:dvar_remove_element(Int,Min0),
+                mfd:dvar_remove_element(Int,Max0),
                 mfd:get_intervals(Int,NIList),
                 (NIList = [_,_|_] ->
                     simple_resol_int(Int)
@@ -12915,7 +13028,8 @@ simple_resol_int1(Int) :-
                     get_small_random_value_in_interval(NInter,Size,C,Mod,Value),
 */
                     (   protected_unify(Int,Value)
-                    ;   mfd:dvar_remove_element(Int,Value)))))
+                    ;   % call(spy_here)@eclipse,
+                        mfd:dvar_remove_element(Int,Value)))))
     ;   true).
 
 /*
@@ -13052,7 +13166,10 @@ simple_resol_float(Var) :-
                 (is_float_int_number(Var) ->
                     % On reutilise le choix de la version entiere
                     get_small_random_value_in_real_interval_float_int(Type,Min..Max,Value)
-                ;   get_small_random_value_in_real_interval(Type,Min..Max,Size,Value)),
+%                ;   get_small_random_value_in_real_interval(Type,Min..Max,Size,Value)),
+                ;   mreal:dvar_domain(Var,NDom),
+                    mreal:dom_size(NDom,NSize),
+                    get_mid_random_value_in_real_interval(Type,Min..Max,NSize,Value)),
                 random_less(2,Rand),
                 % On essaye Value, puis au dessus/dessous de Value
                 (   Var = Value
@@ -13082,16 +13199,11 @@ get_previous_zfloat(Type,V,P) :-
 
 
 
-/*
 simple_resol_real(Var) :-
     var(Var),
     is_float_int_number(Var),
-    mreal:dvar_range(Var,L,H),
-    get_next_double_float(L,NL),
-    NL \== H,
     !,
     simple_resol_real_int(Var).
-*/
 
 simple_resol_real(Var) :-
     once (is_trans_no_rat(Var);
@@ -13235,31 +13347,34 @@ simple_resol_real_int1(Int) :-
     ;   % Un seul intervalle
         IList = [Inter],
         min_max_inter(Inter,Min0,Max0),
-        (Min0 == -1.0Inf ->
-            get_next_double_float(Min0,Min1),
-            (set_typed_intervals(Int,real,[Min1..Max0]);
-             set_typed_intervals(Int,real,[Min0..Min1]),
-             launch_box(Int))
-        ;   (Max0 == 1.0Inf ->
-                get_previous_double_float(Max0,Max1),
-                (set_typed_intervals(Int,real,[Min0..Max1]);
-                 set_typed_intervals(Int,real,[Max1..Max0]),
+        (is_real_box(Int) ->
+            get_rand_rat_in_rbox(Int,Min0,Max0,Rat),
+            launch_box_rat(Int,Rat)
+        ;   (Min0 == -1.0Inf ->
+                get_next_double_float(Min0,Min1),
+                (set_typed_intervals(Int,real,[Min1..Max0]);
+                 set_typed_intervals(Int,real,[Min0..Min1]),
                  launch_box(Int))
-            ;
-                (   protected_unify(Int,Min0)
-                ;   mreal:dvar_remove_element(Int,Min0),
-                    protected_unify(Int,Max0)
-                ;   mreal:dvar_remove_element(Int,Max0),
-                    mreal:get_intervals(Int,NIList),
-                    (NIList = [_,_|_] ->
-                        simple_resol_real_int1(Int)
-                    ;   NIList = [NInter],
-                        min_max_inter(NInter,L,H),
-                        get_number_of_floats_between(float_double,L,H,Dist),
-                        DistD2 is Dist div 2,
-                        get_nth_double_float_from(L,DistD2,Value),
-                        (   protected_unify(Int,Value)
-                        ;   mreal:dvar_remove_element(Int,Value))))))).
+            ;   (Max0 == 1.0Inf ->
+                    get_previous_double_float(Max0,Max1),
+                    (set_typed_intervals(Int,real,[Min0..Max1]);
+                     set_typed_intervals(Int,real,[Max1..Max0]),
+                     launch_box(Int))
+                ;
+                    (   protected_unify(Int,Min0)
+                    ;   mreal:dvar_remove_element(Int,Min0),
+                        protected_unify(Int,Max0)
+                    ;   mreal:dvar_remove_element(Int,Max0),
+                        mreal:get_intervals(Int,NIList),
+                        (NIList = [_,_|_] ->
+                            simple_resol_real_int1(Int)
+                        ;   NIList = [NInter],
+                            min_max_inter(NInter,L,H),
+                            get_number_of_floats_between(float_double,L,H,Dist),
+                            DistD2 is Dist div 2,
+                            get_nth_double_float_from(L,DistD2,Value),
+                            (   protected_unify(Int,Value)
+                            ;   mreal:dvar_remove_element(Int,Value)))))))).
 
 % ESSAI : instanciation pas un rat random dans une rbox finie
 get_rand_rat_in_rbox(Var,Value,NV,Rat) :-
@@ -13541,6 +13656,8 @@ smt_check_disabled_delta :-
                 writeln(output,"Delay/Steps disabled delta":Diff/Steps1/Steps2)
             ;   true),
             smt_disable_delta_check,
+            no_reduce_sub_intervals,
+            no_3B,
             ((getval(keep_deltas_if_arrays_or_reals,1)@eclipse) ->
                 no_simplex
             ;   no_delta) % donc no_simplex
diff --git a/Src/COLIBRI/solve_util.pl b/Src/COLIBRI/solve_util.pl
index 6e269a5f53b8fc40da2de1b951bb76ba483f1e23..b765320cff5e7cbc71487aac5e77d26a11169ec1 100755
--- a/Src/COLIBRI/solve_util.pl
+++ b/Src/COLIBRI/solve_util.pl
@@ -428,31 +428,31 @@ get_interval_at_rank_congr([Inter|IList],Rank,Mod,Interval) :-
 %% Value est une valeur de la fraction ("Fract" ou centree sur 0)
 %% contenant les plus petites valeurs absolues
 get_small_random_value_in_interval(Inter,Size,C,Mod,Value) :-
-	Fract = 1000,
-	min_max_inter(Inter,Low,High),
-	(Size < Fract ->
-		random_less(Size,Rank),
-		Value1 is Low + Rank
-	;	(	Low >= 0,
-			!,
-			random_less(Fract,Rank),
-			Value1 is Low + Rank
-		;
-			High =< 0,
-			!,
-			random_less(Fract,Rank),
-			Value1 is High - Rank
-		;
-			%% On encadre 0, on se centre autour
-			NLow is max(Low, -High),
-			NHigh is min(High, -Low),
-			NSize is (NHigh - NLow) + 1,
-			NFract is min(Fract,NSize),
-			random_less(NFract,Rank),
-			Value1 is Rank - (NFract div 2))),
-	%% On avance a la premiere valeur compatible
-	%% avec la congruence
-	Value is ((Value1 div Mod) * Mod) + C.
+    Fract = 1000,
+    min_max_inter(Inter,Low,High),
+    (Size < Fract ->
+        random_less(Size,Rank),
+        Value1 is Low + Rank
+    ;   (Low >= 0,
+         !,
+         random_less(Fract,Rank),
+         Value1 is Low + Rank
+        ;
+         High =< 0,
+         !,
+         random_less(Fract,Rank),
+         Value1 is High - Rank
+        ;
+         % On encadre 0, on se centre autour
+         NLow is max(Low, -High),
+         NHigh is min(High, -Low),
+         NSize is (NHigh - NLow) + 1,
+         NFract is min(Fract,NSize),
+         random_less(NFract,Rank),
+         Value1 is Rank - (NFract div 2))),
+    % On avance a la premiere valeur compatible
+    % avec la congruence
+    Value is ((Value1 div Mod) * Mod) + C.
 	
 
 %% Value est une valeur du tier central de Inter
@@ -525,8 +525,8 @@ signed_interval_real(Min,Max) :-
 %% contenant les plus petites valeurs absolues
 % Pour compatibilite on recupere le type dans float_eval
 get_small_random_value_in_real_interval(Inter,Size,Res) :-
-	getval(float_eval,Type)@eclipse,
-	get_small_random_value_in_real_interval(Type,Inter,Size,Res).
+    getval(float_eval,Type)@eclipse,
+    get_small_random_value_in_real_interval(Type,Inter,Size,Res).
 
 %%:- mode get_small_random_value_in_real_interval(++,++,++,?).
 get_small_random_value_in_real_interval(Type,LH..LH,_Size,Res) ?- !,
@@ -585,19 +585,19 @@ get_small_random_value_in_real_interval(_,Res,_Size,Res).
 %% contenant les plus petites valeurs absolues
 % Pour compatibilite on recupere le type dans float_eval
 get_small_random_value_in_real_interval_float_int(Inter,Res) :-
-	getval(float_eval,Type)@eclipse,
-	get_small_random_value_in_real_interval_float_int(Type,Inter,Res).
+    getval(float_eval,Type)@eclipse,
+    get_small_random_value_in_real_interval_float_int(Type,Inter,Res).
 
 %%:- mode get_small_random_value_in_real_interval_float_int(++,++,?).
 get_small_random_value_in_real_interval_float_int(Type,Low..High,Res) :- !,
-	ILow is protected_fix(Type,Low),
-	IHigh is protected_fix(Type,High),
-	ISize is (IHigh - ILow) + 1,
-	get_small_random_value_in_interval(ILow..IHigh,ISize,0,1,IValue),
-	%% BM meme si IValue n'est pas representable (hors de -2^53..2^53)
-	%% l'arrondi nearest dans la conversion retombe sur un representable
-	%% entre Low et High
-	int_to_float(Type,IValue,Res).
+    ILow is protected_fix(Type,Low),
+    IHigh is protected_fix(Type,High),
+    ISize is (IHigh - ILow) + 1,
+    get_small_random_value_in_interval(ILow..IHigh,ISize,0,1,IValue),
+    % BM meme si IValue n'est pas representable (hors de -2^53..2^53)
+    % l'arrondi nearest dans la conversion retombe sur un representable
+    % entre Low et High
+    int_to_float(Type,IValue,Res).
 get_small_random_value_in_real_interval_float_int(_,Res,Res).
 
 
@@ -626,23 +626,23 @@ protected_rational(Type,F,R) :-
     R is rational(NF).
 
 get_integer_interval_and_accurracy_bis(L,H,IL,IH,Exp) :-
-	FH is floor(H),
-	CL is ceiling(L),
-	(CL < FH ->
-		%% On a au moins 2 entiers
-		Exp = 0,
-		IL is integer(CL),
-		IH is integer(FH)
-	;	%% On estime l'exposant (negatif ou  nul) de la difference
-		Diff is H - L,
-		Exp1 is integer(floor(ln(Diff)/ln(10))),
-		%% Exp1 peut valoir 0 is CL = FH
-		Exp2 is min(-1,Exp1),
-		Shift is 10^(-1*Exp2),
-		SL is L*Shift,
-		SH is H*Shift,
-		get_integer_interval_and_accurracy_bis(SL,SH,IL,IH,NExp),
-		Exp is Exp2 + NExp).
+    FH is floor(H),
+    CL is ceiling(L),
+    (CL < FH ->
+        % On a au moins 2 entiers
+        Exp = 0,
+        IL is integer(CL),
+        IH is integer(FH)
+    ;   % On estime l'exposant (negatif ou  nul) de la difference
+        Diff is H - L,
+        Exp1 is integer(floor(ln(Diff)/ln(10))),
+        % Exp1 peut valoir 0 is CL = FH
+        Exp2 is min(-1,Exp1),
+        Shift is 10^(-1*Exp2),
+        SL is L*Shift,
+        SH is H*Shift,
+        get_integer_interval_and_accurracy_bis(SL,SH,IL,IH,NExp),
+        Exp is Exp2 + NExp).
 
 
 %% ANCIENNE VERSION AVEC CHOIX CENTRAL
@@ -651,6 +651,24 @@ get_mid_random_value_in_real_interval(Inter,Size,Value) :-
     getval(float_eval,Type)@eclipse,
     get_mid_random_value_in_real_interval(Type,Inter,Size,Value).
 
+get_mid_random_value_in_real_interval(Type,Inter,Size,Value) :- !,
+    min_max_inter(Inter,Low,High),
+    (get_mid_random_value_in_real_interval(Type,Low,High,Size,Value) ->
+        true
+    ;   call(spy_here)@eclipse,
+        get_mid_random_value_in_real_interval(Type,Low,High,Size,Value)).
+
+get_mid_random_value_in_real_interval(Type,Low,High,Size,Value) :-
+    (Size > 2 ->
+        Mid is fix(floor(Size/2.0)),
+        ((get_nth_float_from(Type,Low,Mid,Value),
+          Value >= Low,
+          Value =< High)
+        ->
+            true
+        ;   Value = Low)
+    ;   Value = Low).
+/*
 get_mid_random_value_in_real_interval(Type,Inter,Size,Value) :-
     min_max_inter(Inter,Low,High),
     Diff is High - Low,
@@ -711,7 +729,7 @@ get_mid_random_value_in_real_interval(Type,Inter,Size,Value) :-
             cast_double_to_simple_float(Value0,Value)
         ;   % real ou float_double
             Value = Value0)).
-
+*/
 
 integral_bounds(Low,High,ILow,IHigh) :-
     not_inf_val(Low),
@@ -735,28 +753,28 @@ try_to_keep_precision(_Val,Inter,Res) :-
 try_to_keep_precision(Val,Inter,Res) :-
     round_to_nearest_precision(Val,Inter,Res).
 
-	round_to_nearest_precision(Val,Min..Max,Res) :- !,
-		getval(precision,Prec)@eclipse,
-		DixPuisPrec is 10^(Prec),
-		round_to_smallest_precision(Val,Min,Max,DixPuisPrec,Res).
-	round_to_nearest_precision(_Val,Res,Res).
-
-	round_to_smallest_precision(Val,Min..Max,Res) :- !,
-		round_to_smallest_precision(Val,Min,Max,1,Res).
-	round_to_smallest_precision(_Val,Res,Res).
-
-	round_to_smallest_precision(Val,Min,Max,DixPuisPrec,Res) :-
-		PVal is Val * DixPuisPrec,
-		(not_inf_val(PVal) ->
-			IPVal is fix(PVal),
-			Res1 is IPVal / DixPuisPrec,
-			((Res1 =< Max,
-			  Res1 >= Min)
-			->
-				Res = Res1
-			;	NDixPuisPrec is 10 * DixPuisPrec,
-				round_to_smallest_precision(Val,Min,Max,NDixPuisPrec,Res))
-		;	Res = Val).
+round_to_nearest_precision(Val,Min..Max,Res) :- !,
+    getval(precision,Prec)@eclipse,
+    DixPuisPrec is 10^(Prec),
+    round_to_smallest_precision(Val,Min,Max,DixPuisPrec,Res).
+round_to_nearest_precision(_Val,Res,Res).
+
+round_to_smallest_precision(Val,Min..Max,Res) :- !,
+    round_to_smallest_precision(Val,Min,Max,1,Res).
+round_to_smallest_precision(_Val,Res,Res).
+
+round_to_smallest_precision(Val,Min,Max,DixPuisPrec,Res) :-
+    PVal is Val * DixPuisPrec,
+    (not_inf_val(PVal) ->
+        IPVal is fix(PVal),
+        Res1 is IPVal / DixPuisPrec,
+        ((Res1 =< Max,
+          Res1 >= Min)
+        ->
+            Res = Res1
+        ;   NDixPuisPrec is 10 * DixPuisPrec,
+            round_to_smallest_precision(Val,Min,Max,NDixPuisPrec,Res))
+    ;   Res = Val).
 
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -796,60 +814,87 @@ force_narrow_vars(L) :-
         ;   O = I)),
     narrow_vars_bounds(NewL).
 
-try_vars_sub_intervals([],[]).
-try_vars_sub_intervals([Var|L],NL) :-
+:- export reduce_sub_intervals/0.
+reduce_sub_intervals :-
+    setval(reduce_sub_intervals,1)@eclipse.
+:- export no_reduce_sub_intervals/0.
+no_reduce_sub_intervals :-
+    setval(reduce_sub_intervals,0)@eclipse.
+
+:- export try_vars_sub_intervals/0.
+%try_vars_sub_intervals :- !.
+try_vars_sub_intervals :-
+    (getval(reduce_sub_intervals,1)@eclipse ->
+        delayed_goals(DGs),
+        term_variables(DGs,DGVars0),
+        (foreach(V,DGVars0),
+         fromto(DGVars,O,I,[]) do
+            ((get_type(V,TV),
+              get_Mod_from_Type(TV,Mod),
+              delayed_goals_number(V) > 0)
+            ->
+                O = [V|I]
+            ;   O = I)),
+        (try_vars_sub_intervals(DGVars,_) ->
+            true
+        ;   getval(gdbg,1)@eclipse,
+            writeln(output,fail_try_sub_intervals),
+            fail)
+    ;   true).
+
+% on fait un point fixe (cher ?)
+try_vars_sub_intervals(L,NL) :- 
+    try_vars_sub_intervals(L,NL0,Work),
+    (fail,nonvar(Work) ->
+        try_vars_sub_intervals(L,NL)
+    ;   NL = NL0).
+
+%:- import col_timeout/3 from eclipse.
+try_vars_sub_intervals([],[],_).
+try_vars_sub_intervals([Var|L],NL,Work) :-
     ((var(Var),
       get_type(Var,Type),
+      delayed_goals_number(Var) > 0,
       get_Mod_from_Type(Type,Mod))
     ->
-        try_sub_intervals(Var,Type,Mod),
+        try_var_sub_intervals(Var,Type,Mod,Work),
         NL = [(l,Var,Type,Mod),(r,Var,Type,Mod)|ENL]
     ;   NL = ENL),
-    try_vars_sub_intervals(L,ENL).
+    try_vars_sub_intervals(L,ENL,Work).
 
 get_Mod_from_Type(int,mfd) :- !.
 get_Mod_from_Type(real,mreal) :- !.
 get_Mod_from_Type(float_simple,mreal) :- !.
 get_Mod_from_Type(float_double,mreal) :- !.
 
-try_sub_intervals(Var,Type,Mod) :-
+try_var_sub_intervals(Var,Type,Mod,Work) :-
     Mod:get_intervals(Var,LInter),
     (LInter = [_,_|_] ->
-        try_sub_intervals(Var,Type,Mod,LInter)
+        try_var_sub_intervals(Var,Type,Mod,LInter,Work)
+        ;   true).
+
+try_var_sub_intervals(Var,Type,Mod,LInter,Work) :-
+    try_sub_intervals(Var,Type,Mod,LInter,NLInter),
+    set_intervals(Type,Var,NLInter),
+    (NLInter \== LInter ->
+        Work = 1
     ;   true).
 
-try_sub_intervals(Var,int,mfd,LInter) :-
-    try_int_sub_intervals(Var,LInter,NLInter),
-    mfd:set_intervals(Var,NLInter).
-try_sub_intervals(Var,Type,mreal,LInter) :-
-    try_real_sub_intervals(Var,Type,LInter,NLInter),
-    mreal:set_typed_intervals(Var,Type,NLInter).
-
-try_int_sub_intervals(_Var,[],[]).
-try_int_sub_intervals(Var,[I|LI],NLI) :-
+try_sub_intervals(_Var,_Type,_Mod,[],[]).
+try_sub_intervals(Var,Type,Mod,[I|LI],NLI) :-
     ((not (
-              mfd:set_intervals(Var,[I]),
+              set_intervals(Type,Var,[I]),
               wake,
-              mfd:get_intervals(Var,LInter),
+              Mod:get_intervals(Var,LInter),
               setval(saved_intervals,LInter)))
     ->
-        try_int_sub_intervals(Var,LI,NLI)
-    ;   getval(saved_intervals,BegNLI),
+        % on peut oublier cet intervalle
+        try_sub_intervals(Var,Type,Mod,LI,NLI)
+    ;   % on garde une éventuelle réduction
+        getval(saved_intervals,BegNLI),
         append(BegNLI,EndNLI,NLI),
-        try_int_sub_intervals(Var,LI,EndNLI)).
+        try_sub_intervals(Var,Type,Mod,LI,EndNLI)).
 
-try_real_sub_intervals(_,_,[],[]).
-try_real_sub_intervals(Var,Type,[I|LI],NLI) :-
-    ((not (
-              mreal:set_typed_intervals(Var,Type,[I]),
-              wake,
-              mreal:get_intervals(Var,LInter),
-              setval(saved_intervals,LInter)))
-    ->
-        try_real_sub_intervals(Var,Type,LI,NLI)
-    ;   getval(saved_intervals,BegNLI),
-        append(BegNLI,EndNLI,NLI),
-        try_real_sub_intervals(Var,Type,LI,EndNLI)).
 
 % on rogne a gauche et a droite dans la limite du threshold general T
 % pour les reels/flottants et entiers (dimensionner T selon la taille
@@ -858,9 +903,10 @@ try_real_sub_intervals(Var,Type,[I|LI],NLI) :-
 narrow_vars_bounds([]) :- !.
 narrow_vars_bounds(L) :-
     get_threshold(T),
-    NT is T*1e-2,
+    %NT is T*1e-2,
+    NT is T,
     set_threshold(NT),
-    block((narrow_vars_bounds(L,1.0,T) ->
+    block((narrow_vars_bounds(L,1.0,0.008) ->
               set_threshold(T)
           ;   set_threshold(T),
               fail),
@@ -871,6 +917,8 @@ narrow_vars_bounds(L) :-
 narrow_vars_bounds(L,R,MinR) :-
     L = [_|_],
     R >= MinR,
+    call(smt_check_disabled_delta)@eclipse,
+    getval(use_3B,1),
     !,
     NR is R*0.5,
     (getval(gdbg,1)@eclipse ->
diff --git a/Src/COLIBRI/trans.pl b/Src/COLIBRI/trans.pl
index 4de64b17b4709a17c23ce842cb1aa9dae8b35d38..9ced0105616e7cc137792711094ac4f0ab820187 100644
--- a/Src/COLIBRI/trans.pl
+++ b/Src/COLIBRI/trans.pl
@@ -20,8 +20,8 @@ no_trans :-
 %:- import launch_box_prio/2 from colibri. 
 :- export trans/11.
 trans(DPi,OpDPi,Pi,OpPi,Pid2,OpPid2,Pid4,OpPid4,TPid4,OTPid4,E) :-
-    getval(trans,Trans),
-    (Trans == 0 ->
+    getval(trans,OTrans),
+    (OTrans == 0 ->
         (getval(use_trans,0)@colibri ->
             DPi is 2.0*pi,
             OpDPi is -DPi,
@@ -90,7 +90,8 @@ trans(DPi,OpDPi,Pi,OpPi,Pid2,OpPid2,Pid4,OpPid4,TPid4,OTPid4,E) :-
         (foreach(Trans,[DPi,OpDPi,Pi,OpPi,Pid2,OpPid2,Pid4,OpPid4,TPid4,OTPid4,E]) do
             trans_no_rat(Trans)),
         setval(trans,(DPi,OpDPi,Pi,OpPi,Pid2,OpPid2,Pid4,OpPid4,TPid4,OTPid4,E))
-    ;   Trans = (DPi,OpDPi,Pi,OpPi,Pid2,OpPid2,Pid4,OpPid4,TPid4,OTPid4,E)).
+    ;   % déjà fait
+        (DPi,OpDPi,Pi,OpPi,Pid2,OpPid2,Pid4,OpPid4,TPid4,OTPid4,E) = OTrans).
 
 m2pi(DPi) :-
     trans(DPi0,_,_,_,_,_,_,_,_,_,_),