diff --git a/src_colibri2/bin/options.ml b/src_colibri2/bin/options.ml
index 50976d773f7dd5b9f089ad298fe74213abf1beb2..a386e155166adf712a5d6d02ee5e8c0d11044238 100644
--- a/src_colibri2/bin/options.ml
+++ b/src_colibri2/bin/options.ml
@@ -50,7 +50,7 @@ let gc_opts minor_heap_size major_heap_increment space_overhead max_overhead
 let mk_state theories gc gc_opt bt colors time_limit size_limit input_lang
     input_mode input header_check header_licenses header_lang_version type_check
     type_strict debug context max_warn step_limit debug_flags show_steps
-    check_status dont_print_result learning limit_last_effort =
+    check_status dont_print_result learning limit_last_effort options =
   let last_effort_limit =
     match limit_last_effort with
     | None -> None
@@ -75,7 +75,7 @@ let mk_state theories gc gc_opt bt colors time_limit size_limit input_lang
   ( Colibri2_solver.Input.mk_state ~gc ~gc_opt ~bt ~colors ~time_limit
       ~size_limit ?input_lang ?input_mode ~input ~header_check ~header_licenses
       ~header_lang_version ~type_check ~type_strict ~debug ~context ~max_warn
-      theories ~learning ?step_limit ?last_effort_limit,
+      theories ~learning ?step_limit ?last_effort_limit ~options,
     show_steps,
     check_status,
     not dont_print_result )
@@ -455,9 +455,11 @@ let state theories =
       & opt (some c_limit_last_effort) None
       & info [ "limit-last-effort" ] ~docs ~doc)
   in
+  let other_options = Colibri2_core.ForSchedulers.Options.parser () in
   Term.(
     const (mk_state theories)
     $ gc $ gc_t $ bt $ colors $ time $ size $ in_lang $ in_mode $ input
     $ header_check $ header_licenses $ header_lang_version $ typing $ strict
     $ debug $ context $ max_warn $ step_limit $ debug_flags $ show_steps
-    $ check_status $ dont_print_result $ learning $ last_effort_limit)
+    $ check_status $ dont_print_result $ learning $ last_effort_limit
+    $ other_options)
diff --git a/src_colibri2/core/colibri2_core.ml b/src_colibri2/core/colibri2_core.ml
index 95cca039e3abaa0be926223d58f93998a11271e8..7d0123c9d207617879df07b872ec576aa01bb31f 100644
--- a/src_colibri2/core/colibri2_core.ml
+++ b/src_colibri2/core/colibri2_core.ml
@@ -250,6 +250,8 @@ module ForSchedulers = struct
   let get_event_priority = Events.Wait.get_priority
 
   let flush_internal = Egraph.flush_internal
+
+  module Options = Options
 end
 
 module Choice = struct
@@ -269,3 +271,5 @@ module Choice = struct
 
   module Group = Choice_group
 end
+
+module Options = Options
diff --git a/src_colibri2/core/colibri2_core.mli b/src_colibri2/core/colibri2_core.mli
index 8743ba99bf2ca6e8649960629a418e83aae45521..20578036de813de2189e12835136864e058fa04b 100644
--- a/src_colibri2/core/colibri2_core.mli
+++ b/src_colibri2/core/colibri2_core.mli
@@ -1650,6 +1650,15 @@ module Debug : sig
   val decr : int stat -> unit
 end
 
+module Options : sig
+  type 'a t
+
+  val register : ?pp:'a Fmt.t -> string -> 'a Cmdliner.Term.t -> 'a t
+  (** Register a new option *)
+
+  val get : _ Egraph.t -> 'a t -> 'a
+end
+
 (** {3 For schedulers} *)
 
 (** The following functions are necessary only to the scheduler *)
@@ -1706,4 +1715,14 @@ module ForSchedulers : sig
     (** Add a level of decision for fixing the model, another level could be
       needed. Could raise unsatisfiable if all the model have been tried *)
   end
+
+  module Options : sig
+    type options
+
+    val set_egraph : _ Egraph.t -> options -> unit
+
+    val parser : unit -> options Cmdliner.Term.t
+
+    val default_options : unit -> options
+  end
 end
diff --git a/src_colibri2/core/dune b/src_colibri2/core/dune
index b258dddedc50d2f414b7bc6226c13296f5ea3605..a8235e738498a16dcde303952e863ad2c21bd97a 100644
--- a/src_colibri2/core/dune
+++ b/src_colibri2/core/dune
@@ -2,7 +2,7 @@
  (name colibri2_core)
  (public_name colibri2.core)
  (synopsis "core for colibri2, e.g. trail, egraph")
- (libraries containers ocamlgraph str colibri2.stdlib colibri2.popop_lib dolmen.std dolmen_loop)
+ (libraries containers ocamlgraph str colibri2.stdlib colibri2.popop_lib dolmen.std dolmen_loop cmdliner)
  (preprocess
   (pps ppx_deriving.std ppx_hash))
  (flags :standard -w +a-4-42-44-48-50-58-60-40-9@8 -color always -open
diff --git a/src_colibri2/core/options.ml b/src_colibri2/core/options.ml
new file mode 100644
index 0000000000000000000000000000000000000000..e09f16ce0ad75b8ded4caf5fedcf995e04124afc
--- /dev/null
+++ b/src_colibri2/core/options.ml
@@ -0,0 +1,51 @@
+module K = Keys.Make_key ()
+
+module Data = struct
+  type 'a data = { cmd : 'a Cmdliner.Term.t; id : 'a K.t; pp : 'a Fmt.t }
+
+  let pp d = d.pp
+
+  let key d = d.id
+end
+
+module Reg = K.Make_Registry (Data)
+
+type 'a t = 'a K.t
+
+let register (type a) ?(pp = Fmt.nop) name (cmd : a Cmdliner.Term.t) =
+  let id =
+    K.create
+      (module struct
+        type t = a
+
+        let name = name
+      end)
+  in
+  Reg.register { cmd; id; pp };
+  id
+
+module KM = K.MkMap (struct
+  type ('a, 'b) t = 'a
+end)
+
+let env = Datastructure.Ref.create Fmt.nop "Core.Options" KM.empty
+
+let get d k = KM.find k (Datastructure.Ref.get env d)
+
+type options = unit KM.t
+
+let set m k v = KM.add k v m
+
+let parser () : options Cmdliner.Term.t =
+  let fold acc data =
+    Cmdliner.Term.(
+      pure (fun acc v -> set acc data.Data.id v) $ acc $ data.Data.cmd)
+  in
+  Reg.fold_initialized { fold } (Cmdliner.Term.const KM.empty)
+
+let set_egraph d m = Datastructure.Ref.set env d m
+
+let default_options () =
+  match Cmdliner.Term.eval_peek_opts ~argv:[| "colibri2" |] (parser ()) with
+  | Some r, _ -> r
+  | None, _ -> invalid_arg "Some options are not optional"
diff --git a/src_colibri2/core/options.mli b/src_colibri2/core/options.mli
new file mode 100644
index 0000000000000000000000000000000000000000..cce31384391b9d63d0a4a9a65d7d3fbbd5e3a879
--- /dev/null
+++ b/src_colibri2/core/options.mli
@@ -0,0 +1,35 @@
+(*************************************************************************)
+(*  This file is part of Colibri2.                                       *)
+(*                                                                       *)
+(*  Copyright (C) 2014-2021                                              *)
+(*    CEA   (Commissariat à l'énergie atomique et aux énergies           *)
+(*           alternatives)                                               *)
+(*                                                                       *)
+(*  you can redistribute it and/or modify it under the terms of the GNU  *)
+(*  Lesser General Public License as published by the Free Software      *)
+(*  Foundation, version 2.1.                                             *)
+(*                                                                       *)
+(*  It is distributed in the hope that it will be useful,                *)
+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of       *)
+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        *)
+(*  GNU Lesser General Public License for more details.                  *)
+(*                                                                       *)
+(*  See the GNU Lesser General Public License version 2.1                *)
+(*  for more details (enclosed in the file licenses/LGPLv2.1).           *)
+(*************************************************************************)
+
+type 'a t
+
+val register : ?pp:'a Fmt.t -> string -> 'a Cmdliner.Term.t -> 'a t
+
+val get : _ Egraph.t -> 'a t -> 'a
+
+type options
+
+val set : options -> 'a t -> 'a -> options
+
+val parser : unit -> options Cmdliner.Term.t
+
+val set_egraph : _ Egraph.t -> options -> unit
+
+val default_options : unit -> options
diff --git a/src_colibri2/solver/input.ml b/src_colibri2/solver/input.ml
index 434729d7e5aedcdcb01ff50973a830f7431d9615..e69459bceb139d8207e06bef2dff4852d20f0469 100644
--- a/src_colibri2/solver/input.ml
+++ b/src_colibri2/solver/input.ml
@@ -47,8 +47,8 @@ let pp_status_colibri fmt = function
   | `Unsat -> Fmt.pf fmt "unsat"
   | `StepLimitReached -> Fmt.pf fmt "step limit reached"
 
-let create_ctx ?step_limit ?last_effort_limit learning theories =
-  let t = Scheduler.new_solver ~learning ?last_effort_limit () in
+let create_ctx ?step_limit ?last_effort_limit ?options learning theories =
+  let t = Scheduler.new_solver ~learning ?last_effort_limit ?options () in
   let ctx = Scheduler.get_context t in
   Scheduler.init_theories t ~theories;
   {
@@ -435,7 +435,8 @@ let mk_state ?(gc = false) ?(gc_opt = Gc.get ()) ?(bt = true) ?(colors = true)
     ?input_lang ?input_mode ~input ?(header_check = false)
     ?(header_licenses = []) ?(header_lang_version = None) ?(type_check = true)
     ?(type_strict = true) ?(debug = false) ?(context = true)
-    ?(max_warn = max_int) ?(learning = false) ?last_effort_limit theories =
+    ?(max_warn = max_int) ?(learning = false) ?last_effort_limit ?options
+    theories =
   (* Side-effects *)
   let () = Gc.set gc_opt in
   let () =
@@ -466,7 +467,8 @@ let mk_state ?(gc = false) ?(gc_opt = Gc.get ()) ?(bt = true) ?(colors = true)
       type_check;
       type_strict;
       type_state = Dolmen_loop.Typer.new_state ();
-      solve_state = create_ctx ?step_limit ?last_effort_limit learning theories;
+      solve_state =
+        create_ctx ?step_limit ?last_effort_limit ?options learning theories;
       export_lang = [];
     }
   in
diff --git a/src_colibri2/solver/scheduler.ml b/src_colibri2/solver/scheduler.ml
index 03dd7d3327daff3995ae07fdf8fe57202702be89..bb681d9dce497df4921ae14baf5506904e6b4545 100644
--- a/src_colibri2/solver/scheduler.ml
+++ b/src_colibri2/solver/scheduler.ml
@@ -233,7 +233,8 @@ let get_steps t = t.steps
  *    var_inc = t.var_inc
  *   } *)
 
-let new_solver ~learning ?last_effort_limit () =
+let new_solver ~learning ?last_effort_limit
+    ?(options = Options.default_options ()) () =
   let context = Context.create () in
   let creator = Context.creator context in
   let daemon_count = ref (-1) in
@@ -281,6 +282,9 @@ let new_solver ~learning ?last_effort_limit () =
     Prio.insert t.choices dec ~added_at:(-1)
   in
   Backtrackable.set_sched ~sched_daemon ~sched_decision t.solver_state;
+  let d = Backtrackable.get_delayed t.solver_state in
+  Options.set_egraph d options;
+  Backtrackable.delayed_stop t.solver_state;
   t
 
 let push kind t =
@@ -770,9 +774,9 @@ let check_sat ?step_limit t =
     if Backtrackable.get_unknown t.solver_state then `Unknown d else `Sat d
   with Contradiction -> `Unsat
 
-let run_exn ?nodec ?step_limit ?last_effort_limit ?(learning = false) ~theories
-    f =
-  let t = new_solver ~learning ?last_effort_limit () in
+let run_exn ?nodec ?step_limit ?last_effort_limit ?(learning = false) ?options
+    ~theories f =
+  let t = new_solver ~learning ?last_effort_limit ?options () in
   init_theories ~theories t;
   let check = add_assertion t f in
   flush t;
@@ -780,8 +784,8 @@ let run_exn ?nodec ?step_limit ?last_effort_limit ?(learning = false) ~theories
   let d = Backtrackable.get_delayed t.solver_state in
   check d
 
-let run ?nodec ?step_limit ?last_effort_limit ~theories f =
-  try `Done (run_exn ?nodec ?step_limit ?last_effort_limit ~theories f)
+let run ?nodec ?step_limit ?last_effort_limit ?options ~theories f =
+  try `Done (run_exn ?nodec ?step_limit ?last_effort_limit ?options ~theories f)
   with Contradiction -> `Contradiction
 
 let pop_to st bp = ignore (pop_to st bp)
diff --git a/src_colibri2/solver/scheduler.mli b/src_colibri2/solver/scheduler.mli
index ce31fa15d0fb26300474affc2c594c82816aac2b..42d85deb21415578f38804a9f8accb446265c68e 100644
--- a/src_colibri2/solver/scheduler.mli
+++ b/src_colibri2/solver/scheduler.mli
@@ -29,6 +29,7 @@ val run_exn :
   ?step_limit:int ->
   ?last_effort_limit:last_effort_limit ->
   ?learning:bool ->
+  ?options:ForSchedulers.Options.options ->
   theories:(Egraph.wt -> unit) list ->
   (Egraph.wt -> Egraph.wt -> 'a) ->
   'a
@@ -43,6 +44,7 @@ val run :
   ?nodec:unit ->
   ?step_limit:int ->
   ?last_effort_limit:last_effort_limit ->
+  ?options:ForSchedulers.Options.options ->
   theories:(Egraph.wt -> unit) list ->
   (Egraph.wt -> Egraph.wt -> 'a) ->
   [> `Contradiction | `Done of 'a ]
@@ -50,7 +52,11 @@ val run :
 type t
 
 val new_solver :
-  learning:bool -> ?last_effort_limit:last_effort_limit -> unit -> t
+  learning:bool ->
+  ?last_effort_limit:last_effort_limit ->
+  ?options:ForSchedulers.Options.options ->
+  unit ->
+  t
 
 val init_theories : theories:(Egraph.wt -> unit) list -> t -> unit
 
diff --git a/src_colibri2/stdlib/keys.ml b/src_colibri2/stdlib/keys.ml
index bcd44d0c3e98f13010abcb565b07141c4c66c867..873e56c320f165db891c63273b8d1e77ebcc271e 100644
--- a/src_colibri2/stdlib/keys.ml
+++ b/src_colibri2/stdlib/keys.ml
@@ -147,6 +147,11 @@ module Make_key(X:sig end) = struct
     let print (type a) (k : a t) fmt s =
       let data = get k in
       S.pp data fmt s
+
+    type ('b,'c) fold_initialized = ('b,'c) V.fold_initialized = { fold: 'a. 'c -> 'a data -> 'c }
+    let fold_initialized f acc = V.fold_initialized f acc registry
+    type 'b iter_initialized = 'b V.iter_initialized = { iter: 'a. 'a data -> unit }
+    let iter_initialized f = V.iter_initialized f registry
   end
 
 end
diff --git a/src_colibri2/stdlib/keys_sig.ml b/src_colibri2/stdlib/keys_sig.ml
index 68c1d4ce8c033253ec977eb8ee1b46ee9b5218d9..1cff4149009e34088856c3ba758782fc8246952d 100644
--- a/src_colibri2/stdlib/keys_sig.ml
+++ b/src_colibri2/stdlib/keys_sig.ml
@@ -41,6 +41,10 @@ module type Registry = sig
   val is_well_initialized : unit -> bool
   val get : 'a key -> 'a data
   val print : 'a key -> 'a Format.printer
+  type 'b iter_initialized = { iter: 'a. 'a data -> unit }
+  val iter_initialized : unit iter_initialized -> unit
+  type ('b,'c) fold_initialized = { fold: 'a. 'c -> 'a data -> 'c }
+  val fold_initialized : (unit,'c) fold_initialized -> 'c -> 'c
 
   (** the key shouldn't be used before its registration and shouldn't be
       registered again *)
diff --git a/src_colibri2/theories/LRA/LRA.ml b/src_colibri2/theories/LRA/LRA.ml
index 1ab90f49265458cea1a99edcacf56b4709f319bc..7aaa3bba203c27e744198fd015c3c1538a34f325 100644
--- a/src_colibri2/theories/LRA/LRA.ml
+++ b/src_colibri2/theories/LRA/LRA.ml
@@ -21,11 +21,18 @@
 open Colibri2_core
 module RealValue = RealValue
 
+let fourier_option =
+  Options.register ~pp:Fmt.bool "LRA.fourier"
+    Cmdliner.Arg.(
+      value & flag
+      & info [ "lra-fourier" ]
+          ~doc:"Use FourierMotskin engine instead of Simplex engine")
+
 let th_register env =
   Dom_interval.init env;
   Dom_polynome.init env;
   RealValue.init env;
-  Simplex.init env;
+  (if Options.get env fourier_option then Fourier.init else Simplex.init) env;
   Mul.init env;
   Dom_product.init env;
   ()