diff --git a/colibri2/core/choice_group.ml b/colibri2/core/choice_group.ml
index 77a101da112be0d1c5a7c93d8bdcab9fd951867a..004d705cda42337799d9b45c7d955342c8d4b8e8 100644
--- a/colibri2/core/choice_group.ml
+++ b/colibri2/core/choice_group.ml
@@ -43,6 +43,7 @@ let register_decision d thterm choice =
   match HThTerm.find state d thterm with
   | Choosable -> Egraph.register_decision d choice
   | Init ->
+      (* HThTerm.set state d thterm (Wait { choices = [ choice ]; groups = [] }) *)
       HThTerm.set state d thterm Choosable;
       Egraph.register_decision d choice
   | Wait l ->
diff --git a/colibri2/core/colibri2_core.mli b/colibri2/core/colibri2_core.mli
index 77569584205602394fb8c226c5c9f72b90c9f24e..755416923967b8ce982bd8e8d20bc138c363108b 100644
--- a/colibri2/core/colibri2_core.mli
+++ b/colibri2/core/colibri2_core.mli
@@ -317,6 +317,36 @@ and Ground : sig
   val convert_one_binder :
     Subst.t -> 'a Egraph.t -> Expr.binder -> Expr.term -> Expr.ty -> Node.t
 
+  val convert_one_app_and_iter :
+    'a ->
+    Expr.term ->
+    Expr.ty list ->
+    Node.t Colibri2_popop_lib.IArray.t ->
+    Expr.ty ->
+    Subst.t ->
+    ('a -> t -> unit) ->
+    ('a -> ClosedQuantifier.t -> unit) ->
+    ('a -> NotTotallyApplied.t -> unit) ->
+    Node.t
+
+  val convert_one_cst_and_iter :
+    'a ->
+    Expr.term_cst ->
+    Subst.t ->
+    ('a -> t -> unit) ->
+    ('a -> NotTotallyApplied.t -> unit) ->
+    Node.t
+
+  val convert_one_binder_and_iter :
+    'a ->
+    Expr.binder ->
+    Expr.term ->
+    Expr.ty ->
+    Subst.t ->
+    ('a -> ClosedQuantifier.t -> unit) ->
+    ('a -> NotTotallyApplied.t -> unit) ->
+    Node.t
+
   val convert_let_seq :
     Subst.t ->
     'a ->
diff --git a/colibri2/core/ground.mli b/colibri2/core/ground.mli
index c331cda8a3d81f84bd78d25fc1aeab673565cf2a..6bef1d7e22a30a6620149b316c76bc3816d672f6 100644
--- a/colibri2/core/ground.mli
+++ b/colibri2/core/ground.mli
@@ -193,6 +193,36 @@ val convert_one_cst :
 val convert_one_binder :
   Subst.t -> 'a Egraph.t -> Expr.binder -> Expr.term -> Expr.ty -> Node.t
 
+val convert_one_app_and_iter :
+  'a ->
+  Expr.term ->
+  Expr.ty list ->
+  Node.t Colibri2_popop_lib.IArray.t ->
+  Expr.ty ->
+  Subst.t ->
+  ('a -> t -> unit) ->
+  ('a -> ClosedQuantifier.t -> unit) ->
+  ('a -> NotTotallyApplied.t -> unit) ->
+  Node.t
+
+val convert_one_cst_and_iter :
+  'a ->
+  Dolmen_std.Expr.term_cst ->
+  Subst.t ->
+  ('a -> t -> unit) ->
+  ('a -> NotTotallyApplied.t -> unit) ->
+  Node.t
+
+val convert_one_binder_and_iter :
+  'a ->
+  Expr.binder ->
+  Expr.term ->
+  Expr.ty ->
+  Subst.t ->
+  ('a -> ClosedQuantifier.t -> unit) ->
+  ('a -> NotTotallyApplied.t -> unit) ->
+  Node.t
+
 val convert_let_seq :
   Subst.t ->
   'a ->
diff --git a/colibri2/solver/scheduler.ml b/colibri2/solver/scheduler.ml
index 6adbd53951cad76c09afdcdeafc6e32e933f571a..5373ac754d47f6f5374e9f986a1132e90cf7fc94 100644
--- a/colibri2/solver/scheduler.ml
+++ b/colibri2/solver/scheduler.ml
@@ -578,13 +578,20 @@ let run_one_step_propagation ~nodec t =
             | Some (Steps step_limit) -> step_limit <= t.steps
             | _ -> false
           in
-          Debug.dprintf2 debug_queue "[Scheduler] LastEffort: %i%s"
-            (PrioLastEffort.size t.lasteffort)
-            (if last_effort_deactivated then " (deactivated)" else "");
-          if last_effort_deactivated then false
+          if last_effort_deactivated then (
+            Debug.dprintf1 debug_queue
+              "[Scheduler] LastEffort: %i (deactivated)"
+              (PrioLastEffort.size t.lasteffort);
+            false)
           else
             match PrioLastEffort.extract_min t.lasteffort with
             | Some att as o ->
+                Debug.dprintf3 debug_queue "[Scheduler] LastEffort: %i after %a"
+                  (PrioLastEffort.size t.lasteffort)
+                  (fun fmt (att : PrioLastEffort.Att.t) ->
+                    match att.v with
+                    | DaemonKey (k, _, _) -> Events.Dem.pp fmt k)
+                  att;
                 Debug.incr stats_lasteffort;
                 t.last_effort_made <- o;
                 protect_against_contradiction ~no_learning:true t
@@ -593,6 +600,7 @@ let run_one_step_propagation ~nodec t =
                     Backtrackable.run_daemon d att.v)
                   (fun () -> true)
             | None ->
+                Debug.dprintf0 debug_queue "[Scheduler] LastEffort: 0";
                 t.last_effort_made <- None;
                 false
           (* else false *)))
diff --git a/colibri2/tests/solve/all/unsat/wp_initialize.psmt2 b/colibri2/tests/solve/all/unsat/wp_initialize.psmt2
new file mode 100644
index 0000000000000000000000000000000000000000..ed012f60eaaaf68d9304017d949402769e7996d0
--- /dev/null
+++ b/colibri2/tests/solve/all/unsat/wp_initialize.psmt2
@@ -0,0 +1,1015 @@
+;; produced by local colibri2.drv ;;
+(set-logic ALL)
+(set-info :smt-lib-version 2.6)
+(set-option :max-steps-colibri2 8000)
+;;; SMT-LIB2: integer arithmetic
+;;; SMT-LIB2: real arithmetic
+(declare-sort string 0)
+
+(declare-datatypes ((tuple0 0))
+  (((Tuple0))))
+
+;; "abs"
+(define-fun abs1 ((x Int)) Int
+  (ite (>= x 0) x (- x)))
+
+;; "Abs_le"
+(assert
+  (forall ((x Int) (y Int)) (= (<= (abs1 x) y) (and (<= (- y) x) (<= x y)))))
+
+;; "Abs_pos"
+(assert (forall ((x Int)) (>= (abs1 x) 0)))
+
+;; "div"
+(declare-fun div1 (Int
+  Int) Int)
+
+;; "mod"
+(declare-fun mod1 (Int
+  Int) Int)
+
+;; "Div_mod"
+(assert
+  (forall ((x Int) (y Int))
+    (=> (not (= y 0)) (= x (+ (* y (div1 x y)) (mod1 x y))))))
+
+;; "Div_bound"
+(assert
+  (forall ((x Int) (y Int))
+    (=> (and (>= x 0) (> y 0)) (and (<= 0 (div1 x y)) (<= (div1 x y) x)))))
+
+;; "Mod_bound"
+(assert
+  (forall ((x Int) (y Int))
+    (=>
+      (not (= y 0))
+      (and (< (- (abs1 y)) (mod1 x y)) (< (mod1 x y) (abs1 y))))))
+
+;; "Div_sign_pos"
+(assert
+  (forall ((x Int) (y Int)) (=> (and (>= x 0) (> y 0)) (>= (div1 x y) 0))))
+
+;; "Div_sign_neg"
+(assert
+  (forall ((x Int) (y Int)) (=> (and (<= x 0) (> y 0)) (<= (div1 x y) 0))))
+
+;; "Mod_sign_pos"
+(assert
+  (forall ((x Int) (y Int))
+    (=> (and (>= x 0) (not (= y 0))) (>= (mod1 x y) 0))))
+
+;; "Mod_sign_neg"
+(assert
+  (forall ((x Int) (y Int))
+    (=> (and (<= x 0) (not (= y 0))) (<= (mod1 x y) 0))))
+
+;; "Rounds_toward_zero"
+(assert
+  (forall ((x Int) (y Int))
+    (=> (not (= y 0)) (<= (abs1 (* (div1 x y) y)) (abs1 x)))))
+
+;; "Div_1"
+(assert (forall ((x Int)) (= (div1 x 1) x)))
+
+;; "Mod_1"
+(assert (forall ((x Int)) (= (mod1 x 1) 0)))
+
+;; "Div_inf"
+(assert
+  (forall ((x Int) (y Int)) (=> (and (<= 0 x) (< x y)) (= (div1 x y) 0))))
+
+;; "Mod_inf"
+(assert
+  (forall ((x Int) (y Int)) (=> (and (<= 0 x) (< x y)) (= (mod1 x y) x))))
+
+;; "Div_mult"
+(assert
+  (forall ((x Int) (y Int) (z Int))
+    (! (=>
+         (and (> x 0) (and (>= y 0) (>= z 0)))
+         (= (div1 (+ (* x y) z) x) (+ y (div1 z x)))) :pattern ((div1
+                                                                  (+ (* x y) z)
+                                                                  x)) )))
+
+;; "Mod_mult"
+(assert
+  (forall ((x Int) (y Int) (z Int))
+    (! (=>
+         (and (> x 0) (and (>= y 0) (>= z 0)))
+         (= (mod1 (+ (* x y) z) x) (mod1 z x))) :pattern ((mod1
+                                                            (+ (* x y) z)
+                                                            x)) )))
+
+;; "add_div"
+(assert
+  (forall ((x Real) (y Real) (z Real))
+    (=> (not (= z 0.0)) (= (/ (+ x y) z) (+ (/ x z) (/ y z))))))
+
+;; "sub_div"
+(assert
+  (forall ((x Real) (y Real) (z Real))
+    (=> (not (= z 0.0)) (= (/ (- x y) z) (- (/ x z) (/ y z))))))
+
+;; "neg_div"
+(assert
+  (forall ((x Real) (y Real))
+    (=> (not (= y 0.0)) (= (/ (- x) y) (- (/ x y))))))
+
+;; "assoc_mul_div"
+(assert
+  (forall ((x Real) (y Real) (z Real))
+    (=> (not (= z 0.0)) (= (/ (* x y) z) (* x (/ y z))))))
+
+;; "assoc_div_mul"
+(assert
+  (forall ((x Real) (y Real) (z Real))
+    (=>
+      (and (not (= y 0.0)) (not (= z 0.0)))
+      (= (/ (/ x y) z) (/ x (* y z))))))
+
+;; "assoc_div_div"
+(assert
+  (forall ((x Real) (y Real) (z Real))
+    (=>
+      (and (not (= y 0.0)) (not (= z 0.0)))
+      (= (/ x (/ y z)) (/ (* x z) y)))))
+
+;; "infix +."
+(define-fun infix_pldt ((x Real) (y Real)) Real
+  (+ x y))
+
+;; "infix -."
+(define-fun infix_mndt ((x Real) (y Real)) Real
+  (- x y))
+
+;; "infix *."
+(define-fun infix_asdt ((x Real) (y Real)) Real
+  (* x y))
+
+;; "infix /."
+(define-fun infix_sldt ((x Real) (y Real)) Real
+  (/ x y))
+
+;; "prefix -."
+(define-fun prefix_mndt ((x Real)) Real
+  (- x))
+
+;; "inv"
+(define-fun inv ((x Real)) Real
+  (/ 1.0 x))
+
+;; "infix <=."
+(define-fun infix_lseqdt ((x Real) (y Real)) Bool
+  (<= x y))
+
+;; "infix >=."
+(define-fun infix_gteqdt ((x Real) (y Real)) Bool
+  (>= x y))
+
+;; "infix <."
+(define-fun infix_lsdt ((x Real) (y Real)) Bool
+  (< x y))
+
+;; "infix >."
+(define-fun infix_gtdt ((x Real) (y Real)) Bool
+  (> x y))
+
+;; "Zero"
+(assert (= (to_real 0) 0.0))
+
+;; "One"
+(assert (= (to_real 1) 1.0))
+
+;; "Add"
+(assert
+  (forall ((x Int) (y Int))
+    (= (to_real (+ x y)) (+ (to_real x) (to_real y)))))
+
+;; "Sub"
+(assert
+  (forall ((x Int) (y Int))
+    (= (to_real (- x y)) (- (to_real x) (to_real y)))))
+
+;; "Mul"
+(assert
+  (forall ((x Int) (y Int))
+    (= (to_real (* x y)) (* (to_real x) (to_real y)))))
+
+;; "Neg"
+(assert (forall ((x Int)) (= (to_real (- x)) (- (to_real x)))))
+
+;; "Injective"
+(assert (forall ((x Int) (y Int)) (=> (= (to_real x) (to_real y)) (= x y))))
+
+;; "Monotonic"
+(assert
+  (forall ((x Int) (y Int)) (=> (<= x y) (<= (to_real x) (to_real y)))))
+
+;; "eqb"
+(declare-fun eqb (par (a)
+  (a
+  a) Bool))
+
+;; "eqb"
+(assert (par (a) (forall ((x a) (y a)) (= (= (eqb x y) true) (= x y)))))
+
+;; "neqb"
+(declare-fun neqb (par (a)
+  (a
+  a) Bool))
+
+;; "neqb"
+(assert (par (a)
+  (forall ((x a) (y a)) (= (= (neqb x y) true) (not (= x y))))))
+
+;; "zlt"
+(declare-fun zlt (Int
+  Int) Bool)
+
+;; "zleq"
+(declare-fun zleq (Int
+  Int) Bool)
+
+;; "zlt"
+(assert (forall ((x Int) (y Int)) (= (= (zlt x y) true) (< x y))))
+
+;; "zleq"
+(assert (forall ((x Int) (y Int)) (= (= (zleq x y) true) (<= x y))))
+
+;; "rlt"
+(declare-fun rlt (Real
+  Real) Bool)
+
+;; "rleq"
+(declare-fun rleq (Real
+  Real) Bool)
+
+;; "rlt"
+(assert (forall ((x Real) (y Real)) (= (= (rlt x y) true) (infix_lsdt x y))))
+
+;; "rleq"
+(assert
+  (forall ((x Real) (y Real)) (= (= (rleq x y) true) (infix_lseqdt x y))))
+
+;; "real_of_int"
+(define-fun real_of_int ((x Int)) Real
+  (to_real x))
+
+;; "c_euclidian"
+(assert
+  (forall ((n Int) (d Int))
+    (! (=> (not (= d 0)) (= n (+ (* (div1 n d) d) (mod1 n d)))) :pattern (
+    (div1
+      n
+      d)
+    (mod1 n d)) )))
+
+;; "cmod_remainder"
+(assert
+  (forall ((n Int) (d Int))
+    (! (and
+         (=> (>= n 0) (=> (> d 0) (and (<= 0 (mod1 n d)) (< (mod1 n d) d))))
+         (and
+           (=>
+             (<= n 0)
+             (=> (> d 0) (and (< (- d) (mod1 n d)) (<= (mod1 n d) 0))))
+           (and
+             (=>
+               (>= n 0)
+               (=> (< d 0) (and (<= 0 (mod1 n d)) (< (mod1 n d) (- d)))))
+             (=>
+               (<= n 0)
+               (=> (< d 0) (and (< d (mod1 n d)) (<= (mod1 n d) 0))))))) :pattern (
+    (mod1
+      n
+      d)) )))
+
+;; "cdiv_neutral"
+(assert (forall ((a1 Int)) (! (= (div1 a1 1) a1) :pattern ((div1 a1 1)) )))
+
+;; "cdiv_inv"
+(assert
+  (forall ((a1 Int))
+    (! (=> (not (= a1 0)) (= (div1 a1 a1) 1)) :pattern ((div1 a1 a1)) )))
+
+;; "cdiv_closed_remainder"
+(assert
+  (forall ((a1 Int) (b Int) (n Int))
+    (=>
+      (<= 0 a1)
+      (=>
+        (<= 0 b)
+        (=>
+          (and (<= 0 (- b a1)) (< (- b a1) n))
+          (=> (= (mod1 a1 n) (mod1 b n)) (= a1 b)))))))
+
+(declare-sort infix_mngt 2)
+
+;; "infix @"
+(declare-fun infix_at (par (a1
+  b)
+  ((infix_mngt a1
+  b)
+  a1) b))
+
+;; "get"
+(define-fun get (par (a
+  b1)
+  ((f (infix_mngt a b1)) (x a)) b1
+  (infix_at f x)))
+
+;; "set"
+(declare-fun set (par (a
+  b1)
+  ((infix_mngt a
+  b1)
+  a
+  b1) (infix_mngt a
+  b1)))
+
+;; "set'def"
+(assert (par (a b1)
+  (forall ((f (infix_mngt a b1)) (x a) (v b1) (y a))
+    (= (infix_at (set f x v) y) (ite (= y x) v (infix_at f y))))))
+
+;; "mixfix []"
+(define-fun mixfix_lbrb (par (a
+  b1)
+  ((f (infix_mngt a b1)) (x a)) b1
+  (infix_at f x)))
+
+;; "mixfix [<-]"
+(define-fun mixfix_lblsmnrb (par (a
+  b1)
+  ((f (infix_mngt a b1)) (x a) (v b1)) (infix_mngt a b1)
+  (set f x v)))
+
+(declare-datatypes ((addr 0))
+  (((addrqtmk (base Int)(offset Int)))))
+
+;; "addr_le"
+(declare-fun addr_le (addr
+  addr) Bool)
+
+;; "addr_lt"
+(declare-fun addr_lt (addr
+  addr) Bool)
+
+;; "addr_le_bool"
+(declare-fun addr_le_bool (addr
+  addr) Bool)
+
+;; "addr_lt_bool"
+(declare-fun addr_lt_bool (addr
+  addr) Bool)
+
+;; "addr_le_def"
+(assert
+  (forall ((p addr) (q addr))
+    (! (=>
+         (= (base p) (base q))
+         (= (addr_le p q) (<= (offset p) (offset q)))) :pattern ((addr_le
+                                                                   p
+                                                                   q)) )))
+
+;; "addr_lt_def"
+(assert
+  (forall ((p addr) (q addr))
+    (! (=> (= (base p) (base q)) (= (addr_lt p q) (< (offset p) (offset q)))) :pattern (
+    (addr_lt
+      p
+      q)) )))
+
+;; "addr_le_bool_def"
+(assert
+  (forall ((p addr) (q addr))
+    (! (= (addr_le p q) (= (addr_le_bool p q) true)) :pattern ((addr_le_bool
+                                                                 p
+                                                                 q)) )))
+
+;; "addr_lt_bool_def"
+(assert
+  (forall ((p addr) (q addr))
+    (! (= (addr_lt p q) (= (addr_lt_bool p q) true)) :pattern ((addr_lt_bool
+                                                                 p
+                                                                 q)) )))
+
+;; "null"
+(define-fun null () addr
+  (addrqtmk 0 0))
+
+;; "global"
+(define-fun global ((b2 Int)) addr
+  (addrqtmk b2 0))
+
+;; "shift"
+(define-fun shift ((p addr) (k Int)) addr
+  (addrqtmk (base p) (+ (offset p) k)))
+
+;; "included"
+(define-fun included ((p addr) (a2 Int) (q addr) (b2 Int)) Bool
+  (=>
+    (> a2 0)
+    (and
+      (>= b2 0)
+      (and
+        (= (base p) (base q))
+        (and
+          (<= (offset q) (offset p))
+          (<= (+ (offset p) a2) (+ (offset q) b2)))))))
+
+;; "separated"
+(define-fun separated ((p addr) (a2 Int) (q addr) (b2 Int)) Bool
+  (or
+    (<= a2 0)
+    (or
+      (<= b2 0)
+      (or
+        (not (= (base p) (base q)))
+        (or
+          (<= (+ (offset q) b2) (offset p))
+          (<= (+ (offset p) a2) (offset q)))))))
+
+;; "eqmem"
+(define-fun eqmem (par (a)
+  ((m1 (infix_mngt addr a)) (m2 (infix_mngt addr a)) (p addr) (a2 Int)) Bool
+  (forall ((q addr))
+    (! (=> (included q 1 p a2) (= (mixfix_lbrb m1 q) (mixfix_lbrb m2 q))) :pattern (
+    (mixfix_lbrb
+      m1
+      p)) :pattern ((mixfix_lbrb m2 q)) ))))
+
+;; "havoc"
+(declare-fun havoc (par (a)
+  ((infix_mngt addr
+  a)
+  (infix_mngt addr
+  a)
+  addr
+  Int) (infix_mngt addr
+  a)))
+
+;; "valid_rw"
+(define-fun valid_rw ((m (infix_mngt Int Int)) (p addr) (n Int)) Bool
+  (=>
+    (> n 0)
+    (and
+      (< 0 (base p))
+      (and (<= 0 (offset p)) (<= (+ (offset p) n) (mixfix_lbrb m (base p)))))))
+
+;; "valid_rd"
+(define-fun valid_rd ((m (infix_mngt Int Int)) (p addr) (n Int)) Bool
+  (=>
+    (> n 0)
+    (and
+      (not (= 0 (base p)))
+      (and (<= 0 (offset p)) (<= (+ (offset p) n) (mixfix_lbrb m (base p)))))))
+
+;; "valid_obj"
+(define-fun valid_obj ((m (infix_mngt Int Int)) (p addr) (n Int)) Bool
+  (=>
+    (> n 0)
+    (or
+      (= p null)
+      (and
+        (not (= 0 (base p)))
+        (and
+          (<= 0 (offset p))
+          (<= (+ (offset p) n) (+ 1 (mixfix_lbrb m (base p)))))))))
+
+;; "invalid"
+(define-fun invalid ((m (infix_mngt Int Int)) (p addr) (n Int)) Bool
+  (or
+    (<= n 0)
+    (or
+      (= (base p) 0)
+      (or (<= (mixfix_lbrb m (base p)) (offset p)) (<= (+ (offset p) n) 0)))))
+
+;; "valid_rw_rd"
+(assert
+  (forall ((m (infix_mngt Int Int)))
+    (forall ((p addr))
+      (forall ((n Int)) (=> (valid_rw m p n) (valid_rd m p n))))))
+
+;; "valid_string"
+(assert
+  (forall ((m (infix_mngt Int Int)))
+    (forall ((p addr))
+      (=>
+        (< (base p) 0)
+        (=>
+          (and (<= 0 (offset p)) (< (offset p) (mixfix_lbrb m (base p))))
+          (and (valid_rd m p 1) (not (valid_rw m p 1))))))))
+
+;; "separated_1"
+(assert
+  (forall ((p addr) (q addr))
+    (forall ((a2 Int) (b2 Int) (i Int) (j Int))
+      (! (=>
+           (separated p a2 q b2)
+           (=>
+             (and (<= (offset p) i) (< i (+ (offset p) a2)))
+             (=>
+               (and (<= (offset q) j) (< j (+ (offset q) b2)))
+               (not (= (addrqtmk (base p) i) (addrqtmk (base q) j)))))) :pattern (
+      (separated
+        p
+        a2
+        q
+        b2)
+      (addrqtmk (base p) i)
+      (addrqtmk (base q) j)) ))))
+
+;; "region"
+(declare-fun region (Int) Int)
+
+;; "linked"
+(declare-fun linked ((infix_mngt Int
+  Int)) Bool)
+
+;; "sconst"
+(declare-fun sconst ((infix_mngt addr
+  Int)) Bool)
+
+;; "framed"
+(define-fun framed ((m (infix_mngt addr addr))) Bool
+  (forall ((p addr))
+    (! (=> (<= (region (base p)) 0) (<= (region (base (mixfix_lbrb m p))) 0)) :pattern (
+    (mixfix_lbrb
+      m
+      p)) )))
+
+;; "separated_included"
+(assert
+  (forall ((p addr) (q addr))
+    (forall ((a2 Int) (b2 Int))
+      (! (=>
+           (> a2 0)
+           (=>
+             (> b2 0)
+             (=> (separated p a2 q b2) (not (included p a2 q b2))))) :pattern (
+      (separated
+        p
+        a2
+        q
+        b2)
+      (included p a2 q b2)) ))))
+
+;; "included_trans"
+(assert
+  (forall ((p addr) (q addr) (r addr))
+    (forall ((a2 Int) (b2 Int) (c Int))
+      (! (=>
+           (included p a2 q b2)
+           (=> (included q b2 r c) (included p a2 r c))) :pattern ((included
+                                                                    p
+                                                                    a2
+                                                                    q
+                                                                    b2)
+      (included q b2 r c)) ))))
+
+;; "separated_trans"
+(assert
+  (forall ((p addr) (q addr) (r addr))
+    (forall ((a2 Int) (b2 Int) (c Int))
+      (! (=>
+           (included p a2 q b2)
+           (=> (separated q b2 r c) (separated p a2 r c))) :pattern (
+      (included
+        p
+        a2
+        q
+        b2)
+      (separated q b2 r c)) ))))
+
+;; "separated_sym"
+(assert
+  (forall ((p addr) (q addr))
+    (forall ((a2 Int) (b2 Int))
+      (! (= (separated p a2 q b2) (separated q b2 p a2)) :pattern ((separated
+                                                                    p
+                                                                    a2
+                                                                    q
+                                                                    b2)) ))))
+
+;; "eqmem_included"
+(assert (par (a)
+  (forall ((m1 (infix_mngt addr a)) (m2 (infix_mngt addr a)))
+    (forall ((p addr) (q addr))
+      (forall ((a2 Int) (b2 Int))
+        (! (=>
+             (included p a2 q b2)
+             (=> (eqmem m1 m2 q b2) (eqmem m1 m2 p a2))) :pattern ((eqmem
+                                                                    m1
+                                                                    m2
+                                                                    p
+                                                                    a2)
+        (eqmem m1 m2 q b2)) ))))))
+
+;; "eqmem_sym"
+(assert (par (a)
+  (forall ((m1 (infix_mngt addr a)) (m2 (infix_mngt addr a)))
+    (forall ((p addr))
+      (forall ((a2 Int)) (=> (eqmem m1 m2 p a2) (eqmem m2 m1 p a2)))))))
+
+;; "havoc_access"
+(assert (par (a)
+  (forall ((m0 (infix_mngt addr a)) (m1 (infix_mngt addr a)))
+    (forall ((q addr) (p addr))
+      (forall ((a2 Int))
+        (= (mixfix_lbrb (havoc m0 m1 p a2) q) (ite (separated q 1 p a2)
+                                                (mixfix_lbrb m1 q)
+                                                (mixfix_lbrb m0 q))))))))
+
+;; "cinits"
+(declare-fun cinits ((infix_mngt addr
+  Bool)) Bool)
+
+;; "is_init_range"
+(define-fun is_init_range ((m (infix_mngt addr Bool)) (p addr) (l Int)) Bool
+  (forall ((i Int))
+    (=> (and (<= 0 i) (< i l)) (= (mixfix_lbrb m (shift p i)) true))))
+
+;; "set_init"
+(declare-fun set_init ((infix_mngt addr
+  Bool)
+  addr
+  Int) (infix_mngt addr
+  Bool))
+
+;; "set_init_access"
+(assert
+  (forall ((m (infix_mngt addr Bool)))
+    (forall ((q addr) (p addr))
+      (forall ((a2 Int))
+        (= (mixfix_lbrb (set_init m p a2) q) (ite (separated q 1 p a2)
+                                               (mixfix_lbrb m q)
+                                               true))))))
+
+;; "monotonic_init"
+(define-fun monotonic_init ((m1 (infix_mngt addr Bool)) (m2 (infix_mngt addr Bool))) Bool
+  (forall ((p addr))
+    (=> (= (mixfix_lbrb m1 p) true) (= (mixfix_lbrb m2 p) true))))
+
+;; "int_of_addr"
+(declare-fun int_of_addr (addr) Int)
+
+;; "addr_of_int"
+(declare-fun addr_of_int (Int) addr)
+
+(declare-sort table 0)
+
+;; "table_of_base"
+(declare-fun table_of_base (Int) table)
+
+;; "table_to_offset"
+(declare-fun table_to_offset (table
+  Int) Int)
+
+;; "table_to_offset_zero"
+(assert (forall ((t table)) (= (table_to_offset t 0) 0)))
+
+;; "table_to_offset_monotonic"
+(assert
+  (forall ((t table))
+    (forall ((o1 Int) (o2 Int))
+      (= (<= o1 o2) (<= (table_to_offset t o1) (table_to_offset t o2))))))
+
+;; "int_of_addr_bijection"
+(assert (forall ((a2 Int)) (= (int_of_addr (addr_of_int a2)) a2)))
+
+;; "addr_of_int_bijection"
+(assert (forall ((p addr)) (= (addr_of_int (int_of_addr p)) p)))
+
+;; "addr_of_null"
+(assert (= (int_of_addr null) 0))
+
+;; "max_uint8"
+(define-fun max_uint8 () Int
+  256)
+
+;; "max_sint8"
+(define-fun max_sint8 () Int
+  128)
+
+;; "max_uint16"
+(define-fun max_uint16 () Int
+  65536)
+
+;; "max_sint16"
+(define-fun max_sint16 () Int
+  32768)
+
+;; "max_uint32"
+(define-fun max_uint32 () Int
+  4294967296)
+
+;; "max_sint32"
+(define-fun max_sint32 () Int
+  2147483648)
+
+;; "max_uint64"
+(define-fun max_uint64 () Int
+  18446744073709551616)
+
+;; "max_sint64"
+(define-fun max_sint64 () Int
+  9223372036854775808)
+
+;; "is_bool"
+(define-fun is_bool ((x Int)) Bool
+  (or (= x 0) (= x 1)))
+
+;; "is_uint8"
+(declare-fun is_uint8 (Int) Bool)
+
+;; "is_uint8_def"
+(assert
+  (forall ((x Int))
+    (! (= (is_uint8 x) (and (<= 0 x) (< x max_uint8))) :pattern ((is_uint8 x)) )))
+
+;; "is_sint8"
+(declare-fun is_sint8 (Int) Bool)
+
+;; "is_sint8_def"
+(assert
+  (forall ((x Int))
+    (! (= (is_sint8 x) (and (<= (- max_sint8) x) (< x max_sint8))) :pattern (
+    (is_sint8
+      x)) )))
+
+;; "is_uint16"
+(declare-fun is_uint16 (Int) Bool)
+
+;; "is_uint16_def"
+(assert
+  (forall ((x Int))
+    (! (= (is_uint16 x) (and (<= 0 x) (< x max_uint16))) :pattern ((is_uint16
+                                                                    x)) )))
+
+;; "is_sint16"
+(define-fun is_sint16 ((x Int)) Bool
+  (and (<= (- max_sint16) x) (< x max_sint16)))
+
+;; "is_uint32"
+(declare-fun is_uint32 (Int) Bool)
+
+;; "is_uint32_def"
+(assert
+  (forall ((x Int))
+    (! (= (is_uint32 x) (and (<= 0 x) (< x max_uint32))) :pattern ((is_uint32
+                                                                    x)) )))
+
+;; "is_sint32"
+(declare-fun is_sint32 (Int) Bool)
+
+;; "is_sint32_def"
+(assert
+  (forall ((x Int))
+    (! (= (is_sint32 x) (and (<= (- max_sint32) x) (< x max_sint32))) :pattern (
+    (is_sint32
+      x)) )))
+
+;; "is_uint64"
+(declare-fun is_uint64 (Int) Bool)
+
+;; "is_uint64_def"
+(assert
+  (forall ((x Int))
+    (! (= (is_uint64 x) (and (<= 0 x) (< x max_uint64))) :pattern ((is_uint64
+                                                                    x)) )))
+
+;; "is_sint64"
+(declare-fun is_sint64 (Int) Bool)
+
+;; "is_sint64_def"
+(assert
+  (forall ((x Int))
+    (! (= (is_sint64 x) (and (<= (- max_sint64) x) (< x max_sint64))) :pattern (
+    (is_sint64
+      x)) )))
+
+;; "is_bool0"
+(assert (is_bool 0))
+
+;; "is_bool1"
+(assert (is_bool 1))
+
+;; "to_bool"
+(define-fun to_bool ((x Int)) Int
+  (ite (= x 0) 0 1))
+
+;; "to_uint8"
+(declare-fun to_uint8 (Int) Int)
+
+;; "to_sint8"
+(declare-fun to_sint8 (Int) Int)
+
+;; "to_uint16"
+(declare-fun to_uint16 (Int) Int)
+
+;; "to_sint16"
+(declare-fun to_sint16 (Int) Int)
+
+;; "to_uint32"
+(declare-fun to_uint32 (Int) Int)
+
+;; "to_sint32"
+(declare-fun to_sint32 (Int) Int)
+
+;; "to_uint64"
+(declare-fun to_uint64 (Int) Int)
+
+;; "to_sint64"
+(declare-fun to_sint64 (Int) Int)
+
+;; "two_power_abs"
+(declare-fun two_power_abs (Int) Int)
+
+;; "is_uint"
+(define-fun is_uint ((n Int) (x Int)) Bool
+  (and (<= 0 x) (< x (two_power_abs n))))
+
+;; "is_sint"
+(define-fun is_sint ((n Int) (x Int)) Bool
+  (and (<= (- (two_power_abs n)) x) (< x (two_power_abs n))))
+
+;; "to_uint"
+(declare-fun to_uint (Int
+  Int) Int)
+
+;; "to_sint"
+(declare-fun to_sint (Int
+  Int) Int)
+
+;; "is_to_uint8"
+(assert (forall ((x Int)) (is_uint8 (to_uint8 x))))
+
+;; "is_to_sint8"
+(assert (forall ((x Int)) (is_sint8 (to_sint8 x))))
+
+;; "is_to_uint16"
+(assert (forall ((x Int)) (is_uint16 (to_uint16 x))))
+
+;; "is_to_sint16"
+(assert (forall ((x Int)) (is_sint16 (to_sint16 x))))
+
+;; "is_to_uint32"
+(assert (forall ((x Int)) (is_uint32 (to_uint32 x))))
+
+;; "is_to_sint32"
+(assert (forall ((x Int)) (is_sint32 (to_sint32 x))))
+
+;; "is_to_uint64"
+(assert (forall ((x Int)) (is_uint64 (to_uint64 x))))
+
+;; "is_to_sint64"
+(assert (forall ((x Int)) (is_sint64 (to_sint64 x))))
+
+;; "id_uint8"
+(assert
+  (forall ((x Int))
+    (! (=> (and (<= 0 x) (< x max_uint8)) (= (to_uint8 x) x)) :pattern (
+    (to_uint8
+      x)) )))
+
+;; "id_sint8"
+(assert
+  (forall ((x Int))
+    (! (=> (and (<= (- max_sint8) x) (< x max_sint8)) (= (to_sint8 x) x)) :pattern (
+    (to_sint8
+      x)) )))
+
+;; "id_uint16"
+(assert
+  (forall ((x Int))
+    (! (=> (and (<= 0 x) (< x max_uint16)) (= (to_uint16 x) x)) :pattern (
+    (to_uint16
+      x)) )))
+
+;; "id_sint16"
+(assert
+  (forall ((x Int))
+    (! (=> (and (<= (- max_sint16) x) (< x max_sint16)) (= (to_sint16 x) x)) :pattern (
+    (to_sint16
+      x)) )))
+
+;; "id_uint32"
+(assert
+  (forall ((x Int))
+    (! (=> (and (<= 0 x) (< x max_uint32)) (= (to_uint32 x) x)) :pattern (
+    (to_uint32
+      x)) )))
+
+;; "id_sint32"
+(assert
+  (forall ((x Int))
+    (! (=> (and (<= (- max_sint32) x) (< x max_sint32)) (= (to_sint32 x) x)) :pattern (
+    (to_sint32
+      x)) )))
+
+;; "id_uint64"
+(assert
+  (forall ((x Int))
+    (! (=> (and (<= 0 x) (< x max_uint64)) (= (to_uint64 x) x)) :pattern (
+    (to_uint64
+      x)) )))
+
+;; "id_sint64"
+(assert
+  (forall ((x Int))
+    (! (=> (and (<= (- max_sint64) x) (< x max_sint64)) (= (to_sint64 x) x)) :pattern (
+    (to_sint64
+      x)) )))
+
+;; "proj_int8"
+(assert
+  (forall ((x Int))
+    (! (= (to_sint8 (to_uint8 x)) (to_sint8 x)) :pattern ((to_sint8
+                                                            (to_uint8 x))) )))
+
+;; "proj_int16"
+(assert
+  (forall ((x Int))
+    (! (= (to_sint16 (to_uint16 x)) (to_sint16 x)) :pattern ((to_sint16
+                                                               (to_uint16 x))) )))
+
+;; "proj_int32"
+(assert
+  (forall ((x Int))
+    (! (= (to_sint32 (to_uint32 x)) (to_sint32 x)) :pattern ((to_sint32
+                                                               (to_uint32 x))) )))
+
+;; "proj_int64"
+(assert
+  (forall ((x Int))
+    (! (= (to_sint64 (to_uint64 x)) (to_sint64 x)) :pattern ((to_sint64
+                                                               (to_uint64 x))) )))
+
+;; "shiftfield_F1_S_a"
+(define-fun shiftfield_F1_S_a ((p addr)) addr
+  (shift p 1))
+
+;; "shift_sint32"
+(define-fun shift_sint32 ((p addr) (k Int)) addr
+  (shift p k))
+
+;; "shiftfield_F1_S_i"
+(define-fun shiftfield_F1_S_i ((p addr)) addr
+  (shift p 0))
+
+;; "IsInitArray_sint32"
+(define-fun IsInitArray_sint32 ((p addr) (n Int) (Init (infix_mngt addr Bool))) Bool
+  (forall ((i Int))
+    (=> (<= 0 i) (=> (< i n) (= (get Init (shift_sint32 p i)) true)))))
+
+;; "IsInit_S1_S"
+(define-fun IsInit_S1_S ((p addr) (Init (infix_mngt addr Bool))) Bool
+  (and
+    (IsInitArray_sint32 (shiftfield_F1_S_a p) 10 Init)
+    (= (get Init (shiftfield_F1_S_i p)) true)))
+
+;; "Q_IsInitArray_sint32_range"
+(assert
+  (forall ((p addr) (n Int) (Init (infix_mngt addr Bool)))
+    (= (is_init_range Init p n) (IsInitArray_sint32 p n Init))))
+
+;; "Q_IsInit_S1_S_range"
+(assert
+  (forall ((p addr) (Init (infix_mngt addr Bool)))
+    (= (is_init_range Init p 11) (IsInit_S1_S p Init))))
+
+;; Goal "wp_goal"
+(assert
+  (not
+  (forall ((t (infix_mngt addr Bool)) (t1 (infix_mngt addr Bool)) (i Int) (a2 addr))
+    (let ((a3 (shiftfield_F1_S_a a2)))
+      (let ((a4 (havoc
+                  t1
+                  (set t (shiftfield_F1_S_i a2) true)
+                  (shift_sint32 a3 0)
+                  10)))
+        (=>
+          (<= 0 i)
+          (=>
+            (<= (region (base a2)) 0)
+            (=>
+              (<= 10 i)
+              (=>
+                (<= i 10)
+                (=>
+                  (cinits t)
+                  (=>
+                    (is_sint32 i)
+                    (=>
+                      (cinits a4)
+                      (=>
+                        (forall ((i1 Int))
+                          (=>
+                            (<= 0 i1)
+                            (=>
+                              (< i1 i)
+                              (= (get a4 (shift_sint32 a3 i1)) true))))
+                        (IsInit_S1_S a2 a4))))))))))))))
+
+(check-sat)
diff --git a/colibri2/theories/quantifier/subst.ml b/colibri2/theories/quantifier/subst.ml
index 96990e7f243d254013983ad484d697995025afd6..913f47786a48191938b98e1e3e2c421c0b9c3b29 100644
--- a/colibri2/theories/quantifier/subst.ml
+++ b/colibri2/theories/quantifier/subst.ml
@@ -28,6 +28,26 @@ type mode = { context : bool; avoid_new_term : bool }
 
 exception New_term
 
+let ft choice_group d th =
+  match choice_group with
+  | Some choice_group -> Choice.Group.add_to_group d th choice_group
+  | None -> Choice.Group.make_choosable d th
+
+let fg choice_group d th = ft choice_group d (Ground.thterm th)
+
+let fcq choice_group d th =
+  ft choice_group d (Ground.ClosedQuantifier.thterm th)
+
+let fnt choice_group d th =
+  ft choice_group d (Ground.NotTotallyApplied.thterm th)
+
+(* let fg _ (_ : Ground.t) = () *)
+(* let fcq _ (_ : Ground.ClosedQuantifier.t) = () *)
+(* let fnt _ (_ : Ground.NotTotallyApplied.t) = () *)
+
+let skipped_builtin d builtin =
+  Info.Builtin_skipped_for_trigger.skipped d builtin
+
 let of_node mode d n =
   if mode.avoid_new_term && not (Egraph.is_registered d n) then raise New_term;
   Node.S.singleton n
@@ -39,7 +59,7 @@ let of_node mode d n =
  *)
 
 let rec convert_and_iter mode d (subst_old : Ground.Subst.t)
-    (subst_new : Ground.Subst.t) subst (t : Expr.Term.t) :
+    (subst_new : Ground.Subst.t) subst choice_group (t : Expr.Term.t) :
     Node.S.t * bool (* with freevars *) =
   match t.term_descr with
   | Var v -> (
@@ -64,7 +84,7 @@ let rec convert_and_iter mode d (subst_old : Ground.Subst.t)
           { term_descr = Cst { builtin = Expr.False; _ }; _ };
         ] ) ->
       (* Why3 generates spurious (if v then true else false) *)
-      convert_and_iter mode d subst_old subst_new subst cond
+      convert_and_iter mode d subst_old subst_new subst choice_group cond
   | App (({ term_descr = Cst cst; _ } as f), tyargs, args) ->
       Debug.dprintf2 debug "ci app cst %a" Expr.Term.pp t;
       let with_freevars = ref false in
@@ -72,7 +92,7 @@ let rec convert_and_iter mode d (subst_old : Ground.Subst.t)
         IArray.of_list_map
           ~f:(fun arg ->
             let arg', wf =
-              convert_and_iter mode d subst_old subst_new subst arg
+              convert_and_iter mode d subst_old subst_new subst choice_group arg
             in
             Debug.dprintf3 debug "fv %a: %b" Expr.Term.pp arg wf;
             with_freevars := !with_freevars || wf;
@@ -84,7 +104,7 @@ let rec convert_and_iter mode d (subst_old : Ground.Subst.t)
         (IArray.pp Node.S.pp) args Node.S.pp nodes;
       let mode =
         if mode.context then
-          if Info.Builtin_skipped_for_trigger.skipped d cst.builtin then mode
+          if skipped_builtin d cst.builtin then mode
           else { mode with context = false }
         else mode
       in
@@ -93,7 +113,10 @@ let rec convert_and_iter mode d (subst_old : Ground.Subst.t)
           Debug.dprintf2 debug "new term cst: %a" Expr.Term.pp t;
           raise New_term);
         let args = IArray.map ~f:Node.S.choose args in
-        let n = Ground.convert_one_app subst d f tyargs args t.term_ty in
+        let n =
+          Ground.convert_one_app_and_iter d f tyargs args t.term_ty subst
+            (fg choice_group) (fcq choice_group) (fnt choice_group)
+        in
         (Node.S.singleton n, !with_freevars))
       else (nodes, !with_freevars)
   | App (f, tyargs, args) ->
@@ -106,21 +129,29 @@ let rec convert_and_iter mode d (subst_old : Ground.Subst.t)
         IArray.of_list_map
           ~f:(fun arg ->
             let arg, wf =
-              convert_and_iter mode d subst_old subst_new subst arg
+              convert_and_iter mode d subst_old subst_new subst choice_group arg
             in
             with_freevars := !with_freevars || wf;
             arg)
           args
       in
       let args = IArray.map ~f:Node.S.choose args in
-      let n = Ground.convert_one_app subst d f tyargs args t.term_ty in
+      let n =
+        Ground.convert_one_app_and_iter d f tyargs args t.term_ty subst
+          (fg choice_group) (fcq choice_group) (fnt choice_group)
+      in
       (Node.S.singleton n, !with_freevars)
   | Cst f ->
       Debug.dprintf2 debug "ci cst %a" Expr.Term.pp t;
       (* even if it could create a new term, it will create it only once (global term) *)
-      (Node.S.singleton (Ground.convert_one_cst subst d f), false)
+      ( Node.S.singleton
+          (Ground.convert_one_cst_and_iter d f subst (fg choice_group)
+             (fnt choice_group)),
+        false )
   | Expr.Binder (((Exists _ | Forall _ | Lambda _) as b), body) ->
-      ( Ground.convert_one_binder subst d b body t.term_ty |> of_node mode d,
+      ( Ground.convert_one_binder_and_iter d b body t.term_ty subst
+          (fcq choice_group) (fnt choice_group)
+        |> of_node mode d,
         true )
   | Expr.Binder (Let_seq l, body) ->
       let subst_old, subst_new, subst =
@@ -129,7 +160,7 @@ let rec convert_and_iter mode d (subst_old : Ground.Subst.t)
             let n, fv =
               convert_and_iter
                 { mode with context = false }
-                d subst_old subst_new subst t
+                d subst_old subst_new subst choice_group t
             in
             let n = Node.S.choose n in
             let add (s : Ground.Subst.t) =
@@ -140,7 +171,7 @@ let rec convert_and_iter mode d (subst_old : Ground.Subst.t)
           (subst_old, subst_new, subst)
           l
       in
-      convert_and_iter mode d subst_old subst_new subst body
+      convert_and_iter mode d subst_old subst_new subst choice_group body
   | Expr.Binder (Let_par l, body) ->
       let subst_old, subst_new, subst =
         List.fold_left
@@ -148,7 +179,7 @@ let rec convert_and_iter mode d (subst_old : Ground.Subst.t)
             let n, fv =
               convert_and_iter
                 { mode with context = false }
-                d subst_old subst_new subst t
+                d subst_old subst_new subst choice_group t
             in
             let n = Node.S.choose n in
             let add (s : Ground.Subst.t) =
@@ -159,13 +190,14 @@ let rec convert_and_iter mode d (subst_old : Ground.Subst.t)
           (subst_old, subst_new, subst)
           l
       in
-      convert_and_iter mode d subst_old subst_new subst body
+      convert_and_iter mode d subst_old subst_new subst choice_group body
   | Expr.Match (_, _) -> invalid_arg "match from dolmen not implemented"
 (* TODO convert to one multitest like
    the match of why3  and projection *)
 
 let rec check_context_aux d (subst_old : Ground.Subst.t)
-    (subst_new : Ground.Subst.t) (subst : Ground.Subst.t) (t : Expr.Term.t) =
+    (subst_new : Ground.Subst.t) (subst : Ground.Subst.t)
+    (choice_group : Choice.Group.t option) (t : Expr.Term.t) =
   match t.term_descr with
   | Var _ -> true
   | App
@@ -177,15 +209,17 @@ let rec check_context_aux d (subst_old : Ground.Subst.t)
           { term_descr = Cst { builtin = Expr.False; _ }; _ };
         ] ) ->
       (* Why3 generates spurious (if v then true else false) *)
-      check_context d subst_old subst_new subst cond
+      check_context d subst_old subst_new subst choice_group cond
   | App ({ term_descr = Cst cst; _ }, _, args) ->
-      if Info.Builtin_skipped_for_trigger.skipped d cst.builtin then
-        List.for_all (check_context d subst_old subst_new subst) args
+      if skipped_builtin d cst.builtin then
+        List.for_all
+          (check_context d subst_old subst_new subst choice_group)
+          args
       else
         let n, _ =
           convert_and_iter
             { context = true; avoid_new_term = true }
-            d subst_old subst_new subst t
+            d subst_old subst_new subst choice_group t
         in
         not (Node.S.is_empty n)
   | App _ -> false
@@ -195,7 +229,8 @@ let rec check_context_aux d (subst_old : Ground.Subst.t)
        * |> of_node { context = true; avoid_new_term = true } d
        * |> Node.S.is_empty |> not *)
   | Expr.Binder (((Exists _ | Forall _ | Lambda _) as b), body) ->
-      Ground.convert_one_binder subst d b body t.term_ty
+      Ground.convert_one_binder_and_iter d b body t.term_ty subst
+        (fcq choice_group) (fnt choice_group)
       |> of_node { context = true; avoid_new_term = true } d
       |> Node.S.is_empty |> not
   | Expr.Binder (Let_seq l, body) ->
@@ -205,7 +240,7 @@ let rec check_context_aux d (subst_old : Ground.Subst.t)
             let n, fv =
               convert_and_iter
                 { context = false; avoid_new_term = true }
-                d subst_old subst_new subst t
+                d subst_old subst_new subst choice_group t
             in
             let n = Node.S.choose n in
             let add (s : Ground.Subst.t) =
@@ -216,7 +251,7 @@ let rec check_context_aux d (subst_old : Ground.Subst.t)
           (subst_old, subst_new, subst)
           l
       in
-      check_context d subst_old subst_new subst body
+      check_context d subst_old subst_new subst choice_group body
   | Expr.Binder (Let_par l, body) ->
       let subst_old, subst_new, subst =
         List.fold_left
@@ -224,7 +259,7 @@ let rec check_context_aux d (subst_old : Ground.Subst.t)
             let n, fv =
               convert_and_iter
                 { context = false; avoid_new_term = true }
-                d subst_old subst_new subst t
+                d subst_old subst_new subst choice_group t
             in
             let n = Node.S.choose n in
             let add (s : Ground.Subst.t) =
@@ -235,31 +270,31 @@ let rec check_context_aux d (subst_old : Ground.Subst.t)
           (subst_old, subst_new, subst)
           l
       in
-      check_context d subst_old subst_new subst body
+      check_context d subst_old subst_new subst choice_group body
   | Expr.Match (_, _) -> invalid_arg "match from dolmen not implemented"
 (* TODO convert to one multitest like
    the match of why3  and projection *)
 
-and check_context d subst_old subst_new subst t =
-  let c = check_context_aux d subst_old subst_new subst t in
+and check_context d subst_old subst_new subst choice_group t =
+  let c = check_context_aux d subst_old subst_new subst choice_group t in
   if not c then Debug.dprintf2 debug "check false: %a" Expr.Term.pp t;
   c
 
-let convert ~subst_old ~subst_new d t =
+let convert ~subst_old ~subst_new d choice_group t =
   let subst = Ground.Subst.distinct_union subst_old subst_new in
   try
     let n, _ =
       convert_and_iter
         { context = true; avoid_new_term = false }
-        d subst_old subst_new subst t
+        d subst_old subst_new subst choice_group t
     in
     Node.S.choose n
   with New_term -> assert false
 
-let convert_avoid_new_terms ~subst_old ~subst_new d t =
+let convert_avoid_new_terms ~subst_old ~subst_new d choice_group t =
   let subst = Ground.Subst.distinct_union subst_old subst_new in
   let b =
-    try check_context d subst_old subst_new subst t
+    try check_context d subst_old subst_new subst choice_group (* todo *) t
     with New_term ->
       Debug.dprintf0 debug "check_context";
       false
@@ -269,7 +304,7 @@ let convert_avoid_new_terms ~subst_old ~subst_new d t =
       let n, _ =
         convert_and_iter
           { context = true; avoid_new_term = true }
-          d subst_old subst_new subst t
+          d subst_old subst_new subst choice_group t
       in
       Some (Node.S.choose n)
     with New_term -> None
diff --git a/colibri2/theories/quantifier/subst.mli b/colibri2/theories/quantifier/subst.mli
index e9b262c70dd33c5d2057b0408b30b4ccf39e99e5..870e6629aa5d634666ffcddd04af0a09c8c4da03 100644
--- a/colibri2/theories/quantifier/subst.mli
+++ b/colibri2/theories/quantifier/subst.mli
@@ -22,6 +22,7 @@ val convert :
   subst_old:Ground.Subst.t ->
   subst_new:Ground.Subst.t ->
   _ Egraph.t ->
+  Choice.Group.t option ->
   Expr.Term.t ->
   Node.t
 (** Same as {!Ground.convert} but try to reuse terms that are equal and already
@@ -31,6 +32,7 @@ val convert_avoid_new_terms :
   subst_old:Ground.Subst.t ->
   subst_new:Ground.Subst.t ->
   _ Egraph.t ->
+  Choice.Group.t option ->
   Expr.Term.t ->
   Node.t option
 (** Same as {!convert} but doesn't create new terms (except for skipped builtins
diff --git a/colibri2/theories/quantifier/trigger.ml b/colibri2/theories/quantifier/trigger.ml
index 82f77593a271650ef96dd4419a4f11123875a99a..84094540e8b15ad91a4303b41fa725368161c093 100644
--- a/colibri2/theories/quantifier/trigger.ml
+++ b/colibri2/theories/quantifier/trigger.ml
@@ -402,6 +402,11 @@ let no_eager_instantiation =
       value & flag
       & info [ "no-eager-instantiation" ] ~doc:"Don't do eager instantiation")
 
+let eager_decision =
+  Options.register ~pp:Fmt.bool "Quant.eager_decision"
+    Cmdliner.Arg.(
+      value & flag & info [ "eager-decision" ] ~doc:"Do decisions with eager")
+
 let instantiate' d tri subst =
   let show_debug debug =
     Debug.dprintf11 debug
@@ -428,7 +433,7 @@ let instantiate' d tri subst =
   let no_eager_instantiation = Options.get d no_eager_instantiation in
   match level_inst with
   | Instantiated -> show_debug debug_full
-  | Delayed when no_eager_instantiation -> show_debug debug_full
+  | Delayed -> show_debug debug_full
   | NotSeen when no_eager_instantiation -> delayed ()
   | _ ->
       show_debug debug_instantiation;
@@ -446,12 +451,17 @@ let instantiate' d tri subst =
         else delayed ()
       else if tri.eager then
         let form = Ground.ClosedQuantifier.sem tri.form in
+        let choice_group =
+          if Options.get d eager_decision then None
+          else Some (Choice.Group.create d)
+        in
         match
           Subst.convert_avoid_new_terms ~subst_old:form.subst ~subst_new:subst d
-            form.body
+            choice_group form.body
         with
         | Some n ->
-            SubstTrie.set tri.substs subst Instantiated;
+            if Options.get d eager_decision then
+              SubstTrie.set tri.substs subst Instantiated;
             Debug.incr nb_instantiation;
             Debug.incr nb_eager_instantiation;
             if
@@ -463,6 +473,7 @@ let instantiate' d tri subst =
               tri.form Ground.Subst.pp subst Ground.Subst.pp form.subst;
             Egraph.register d n;
             Egraph.merge d n (Ground.ClosedQuantifier.node tri.form);
+            if not (Options.get d eager_decision) then delayed ();
             Debug.dprintf0 debug "[Quant]   Done"
         | None -> delayed ()
       else delayed ()