Basic formulation:
----------------
version 0.1 has the following env.

type value_status = ValueOK | LowerKO | UpperKO

type var_info =
{
  mini   : bound;
  maxi   : bound;
  min_ex : Ex.t;
  max_ex : Ex.t;
  value : R.t * R.t;
  vstatus : value_status;
  is_slake : bool;
}

type t =
{
  basic  : (var_info * P.t) MX.t;
  non_basic : (var_info * SX.t) MX.t;
  slake_cache  : Var.t SLAKE.t;
  fixme : SX.t;
  is_int : bool;
  status : simplex_status;
  debug : int;
  check_invariants : bool
}

(1)
forall x in basic U non_basic U used_by U polys(basic) U
            slake_cache U polys(slake_cache) U fixeme.
  is_int <=> Var.is_int x

(2) basic intersect non_basic = empty

(3) forall p in polys(basic) U polys(slake_cache).
     forall (x, c) in p.
     (x in basic xor x in non_basic)
     and c <> 0
     
(4) used_by intersect non_basic = empty

(5) forall y. forall x in used_by(y). (*y is no_basic and x is basic*)
    let _, p = basic(x)
    y in vars(p) (* i.e. with a coef != 0 *)

(6) forall s. forall p such that basic(s) = _, p.
    forall x in vars(p). s in used_by(x)

(* 5 and 6 mean that used_by contain exactly what needed *)

(7) forall x in non_basic.
    min_bound <= val(x) <= max_bound


(8) status = SAT =>
    forall x in basic.
    min_bound <= val(x) <= max_bound
    
(9) status = IntSAT =>
    (8) and forall x. val(x) is an integer

(10) is_int => (* ie simplex on integers *)
     coefs of delta_i's in min and max bounds are equal to zero

(11) not is_int => (* ie simplex on rationnals *)
     coefs of delta_i's in min bounds are in {0, 1} and
     coefs of delta_i's in max bounds are in {0, -1}

(12) status = SAT (sol) =>
     sol satisfies the bounds of every constraints and
     sol satisfies every equality s = p, with (s, p) in basic.

(13) status = UNSAT ({x_i, ex_i)} =>
     /\ min_bound_i <= x_i <= max_bound_i in UNSAT on
     rationnals (* use FM to check this ? *)

(14). fixme subset basic

(15) forall x.
     x in fixme =>
     ( val(x) < min_bound_x or
       val(x) > max_bound_x )

(16) status != UNSAT =>
     forall x. x not in fixme => min_bound_x <= val(x) <= max_bound_x

(17) status != Unknown => fixme = empty 
     (* When UNSAT is deduced, we empty fixme *)

(18) forall (s, p) in basic.
     val(s) = eval(p)

(19) forall (x, i) in basic U non_basic
     min_bound_x <= val(x) <= max_bound_x => i.vstatus = ValueOK) and
     val(x) < min_bound_x => i.vstatus = LowerKO and
     max_bound_x < val(x) => i.vstatus = UpperKO


(20) 
     status != Unsat =>
     forall (x, i) in basic U non_basic
     (min_bound_x <= max_bound_x)
