diff --git a/src/kernel_services/analysis/logic_deps.ml b/src/kernel_services/analysis/logic_deps.ml
new file mode 100644
index 0000000000000000000000000000000000000000..0087286b5bc9bdf5b34ed17042dd17b79666bbed
--- /dev/null
+++ b/src/kernel_services/analysis/logic_deps.ml
@@ -0,0 +1,626 @@
+(**************************************************************************)
+(*                                                                        *)
+(*  This file is part of Frama-C.                                         *)
+(*                                                                        *)
+(*  Copyright (C) 2007-2022                                               *)
+(*    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).            *)
+(*                                                                        *)
+(**************************************************************************)
+
+open Cil
+open Cil_types
+open Cil_datatype
+
+exception NYI of string
+let not_yet_implemented = ref ""
+
+(** [compute_term_deps] is provided by Eva; computes the memory zone on which a
+    term depends. *)
+let compute_term_deps = ref (fun _stmt _expr -> None)
+
+(* Reimport here the type definitions of Db.Properties.Interp. See
+    documentation there. *)
+type ctx = Db.Properties.Interp.To_zone.t_ctx =
+  {state_opt:bool option;
+   ki_opt:(stmt * bool) option;
+   kf:Kernel_function.t}
+
+type pragmas = Db.Properties.Interp.To_zone.t_pragmas =
+  {ctrl: Stmt.Set.t ; stmt: Stmt.Set.t}
+
+type t = Db.Properties.Interp.To_zone.t
+= {before:bool ; ki:stmt ; zone:Locations.Zone.t}
+type zone_info = Db.Properties.Interp.To_zone.t_zone_info
+
+type decl = Db.Properties.Interp.To_zone.t_decl =
+  {var: Varinfo.Set.t ; lbl: Logic_label.Set.t}
+
+let mk_ctx_func_contrat kf ~state_opt =
+  { state_opt = state_opt;
+    ki_opt = None;
+    kf = kf }
+
+let mk_ctx_stmt_contrat kf ki ~state_opt =
+  { state_opt=state_opt;
+    ki_opt= Some(ki, false);
+    kf = kf }
+
+let mk_ctx_stmt_annot kf ki =
+  { state_opt = Some true;
+    ki_opt = Some(ki, true);
+    kf = kf }
+
+type result = {
+  pragmas: pragmas;
+  locals: Varinfo.Set.t;
+  labels: Logic_label.Set.t;
+  zones: (Locations.Zone.t * Locations.Zone.t) Stmt.Map.t option;
+}
+
+let empty_pragmas =
+  { ctrl = Stmt.Set.empty;
+    stmt = Stmt.Set.empty }
+
+let empty_results = {
+  pragmas = empty_pragmas;
+  locals = Varinfo.Set.empty;
+  labels = Logic_label.Set.empty;
+  zones = Some Stmt.Map.empty;
+}
+
+let add_top_zone not_yet_implemented_msg =
+  function
+  | None -> (* top zone *) None
+  | Some _ ->
+    not_yet_implemented := not_yet_implemented_msg;
+    None
+
+let add_zone ~before ki zone =
+  function
+  | None -> (* top zone *) None
+  | Some other_zones ->
+    let zone_true, zone_false =
+      try Stmt.Map.find ki other_zones
+      with Not_found -> Locations.Zone.bottom, Locations.Zone.bottom
+    in
+    let new_zone =
+      if before
+      then Locations.Zone.join zone_true zone, zone_false
+      else zone_true, Locations.Zone.join zone_false zone
+    in
+    Some (Stmt.Map.add ki new_zone other_zones)
+
+let get_result result =
+  let zones =
+    match result.zones with
+    | None -> None
+    | Some other_zones ->
+      let zones =
+        Stmt.Map.to_seq other_zones |>
+        Seq.flat_map (fun (ki, (zone_true, zone_false)) ->
+            List.to_seq [
+              { before=false; ki; zone=zone_false } ;
+              { before=true; ki; zone=zone_true }
+            ]) |>
+        Seq.filter (fun x ->
+            not (Locations.Zone.equal Locations.Zone.bottom x.zone)) |>
+        List.of_seq
+      in
+      Some zones
+  in
+  zones, {var = result.locals; lbl = result.labels}
+
+let get_annot_result result =
+  get_result result, result.pragmas
+
+(** Logic_var utility: *)
+let extract_locals logicvars =
+  Logic_var.Set.fold
+    (fun lv cvars -> match lv.lv_origin with
+       | None -> cvars
+       | Some cvar ->
+         if cvar.Cil_types.vglob then cvars
+         else Varinfo.Set.add cvar cvars)
+    logicvars
+    Varinfo.Set.empty
+
+(** Term utility:
+    Extract C local variables occurring into a [term]. *)
+let extract_locals_from_term term =
+  extract_locals (extract_free_logicvars_from_term term)
+
+(** Predicate utility:
+    Extract C local variables occurring into a [term]. *)
+let extract_locals_from_pred pred =
+  extract_locals (extract_free_logicvars_from_predicate pred)
+
+type abs_label = | AbsLabel_here
+                 | AbsLabel_pre
+                 | AbsLabel_post
+                 | AbsLabel_init
+                 | AbsLabel_loop_entry
+                 | AbsLabel_loop_current
+                 | AbsLabel_stmt of stmt
+
+let is_same_label absl l =
+  match absl, l with
+  | AbsLabel_stmt s1, StmtLabel s2 -> Cil_datatype.Stmt.equal s1 !s2
+  | AbsLabel_here, BuiltinLabel Here -> true
+  | AbsLabel_pre, BuiltinLabel Pre -> true
+  | AbsLabel_post, BuiltinLabel Post -> true
+  | AbsLabel_init, BuiltinLabel Init -> true
+  | AbsLabel_loop_entry, BuiltinLabel LoopEntry -> true
+  | AbsLabel_loop_current, BuiltinLabel LoopCurrent -> true
+  | _, (StmtLabel _ | FormalLabel _ | BuiltinLabel _) -> false
+
+
+let populate_zone ctx visit cil_node current_zones =
+  let { state_opt=before_opt; ki_opt; kf } = ctx in
+  (* interpretation from the
+     - pre-state if  [before_opt=Some true]
+     - post-state if [before_opt=Some false]
+     - pre-state with possible reference to the post-state if
+        [before_opt=None] of a property relative to
+     - the contract of function [kf] when [ki_opt=None]
+        otherwise [ki_opt=Some(ki, code_annot)],
+     - the contract of the statement [ki] when [code_annot=false]
+     - the annotation of the statement [ki] when [code_annot=true] *)
+  let vis = object(self)
+    inherit Visitor.frama_c_inplace
+    val mutable current_label = AbsLabel_here
+    val mutable zones = current_zones
+    method get_zones = zones
+
+    method private get_ctrl_point () =
+      let get_fct_entry_point () =
+        (* TODO: to replace by true, None *)
+        true,
+        (try Some (Kernel_function.find_first_stmt kf)
+         with Kernel_function.No_Statement ->
+           (* raised when [kf] has no code. *)
+           None)
+      in
+      let get_ctrl_point dft =
+        let before = Option.value ~default:dft before_opt in
+        match ki_opt with
+        | None -> (* function contract *)
+
+          if before then get_fct_entry_point ()
+          else before, None
+        (* statement contract *)
+        | Some (ki,_) ->  (* statement contract and code annotation *)
+          before, Some ki
+      in
+      let result = match current_label with
+        | AbsLabel_stmt stmt -> true, Some stmt
+        | AbsLabel_pre -> get_fct_entry_point ()
+        | AbsLabel_here -> get_ctrl_point true
+        | AbsLabel_post -> get_ctrl_point false
+        | AbsLabel_init -> raise (NYI "[logic_interp] Init label")
+        | AbsLabel_loop_current ->
+          raise (NYI "[logic_interp] LoopCurrent label")
+        | AbsLabel_loop_entry ->
+          raise (NYI "[logic_interp] LoopEntry label")
+      in (* TODO: the method should be able to return result directly *)
+      match result with
+      | current_before, Some current_stmt -> current_before, current_stmt
+      | _ -> raise (NYI
+                      "[logic_interp] clause related to a function contract")
+
+    method private change_label: 'a.abs_label -> 'a -> 'a visitAction =
+      fun label x ->
+      let old_label = current_label in
+      current_label <- label;
+      ChangeDoChildrenPost
+        (x,fun x -> current_label <- old_label; x)
+
+    method private change_label_to_here: 'a.'a -> 'a visitAction =
+      fun x ->
+      self#change_label AbsLabel_here x
+
+    method private change_label_to_old: 'a.'a -> 'a visitAction =
+      fun x ->
+      match ki_opt,before_opt with
+      (* function contract *)
+      | None,Some true ->
+        failwith "The use of the label Old is forbidden inside clauses \
+                  related to the pre-state of function contracts."
+      | None,None
+      | None,Some false ->
+        (* refers to the pre-state of the contract. *)
+        self#change_label AbsLabel_pre x
+      (* statement contract *)
+      | Some (_ki,false),Some true  ->
+        failwith "The use of the label Old is forbidden inside clauses \
+                  related to the pre-state of statement contracts."
+      | Some (ki,false),None
+      | Some (ki,false),Some false  ->
+        (* refers to the pre-state of the contract. *)
+        self#change_label (AbsLabel_stmt ki) x
+      (* code annotation *)
+      | Some (_ki,true),None
+      | Some (_ki,true),Some _ ->
+        (* refers to the pre-state of the function contract. *)
+        self#change_label AbsLabel_pre x
+
+    method private change_label_to_post: 'a.'a -> 'a visitAction =
+      fun x ->
+      (* allowed when [before_opt=None] for function/statement contracts *)
+      match ki_opt,before_opt with
+      (* function contract *)
+      | None,Some _ ->
+        failwith "Function contract where the use of the label Post is \
+                  forbidden."
+      | None,None ->
+        (* refers to the post-state of the contract. *)
+        self#change_label AbsLabel_post x
+      (* statement contract *)
+      | Some (_ki,false),Some _  ->
+        failwith "Statement contract where the use of the label Post is \
+                  forbidden."
+      | Some (_ki,false),None ->
+        (* refers to the pre-state of the contract. *)
+        self#change_label AbsLabel_post x
+      (* code annotation *)
+      | Some (_ki,true), _ ->
+        failwith "The use of the label Post is forbidden inside code \
+                  annotations."
+
+    method private change_label_to_pre: 'a.'a -> 'a visitAction =
+      fun x ->
+      match ki_opt with
+      (* function contract *)
+      | None ->
+        failwith "The use of the label Pre is forbidden inside function \
+                  contracts."
+      (* statement contract *)
+      (* code annotation *)
+      | Some _ ->
+        (* refers to the pre-state of the function contract. *)
+        self#change_label AbsLabel_pre x
+
+    method private change_label_aux: 'a. _ -> 'a -> 'a visitAction =
+      fun lbl x -> self#change_label lbl x
+
+    method private change_label_to_stmt: 'a.stmt -> 'a -> 'a visitAction =
+      fun stmt x ->
+      match ki_opt with
+      (* function contract *)
+      | None ->
+        failwith "the use of C labels is forbidden inside clauses related \
+                  to function contracts."
+      (* statement contract *)
+      (* code annotation *)
+      | Some _ ->
+        (* refers to the state at the C label of the statement [stmt]. *)
+        self#change_label (AbsLabel_stmt stmt) x
+
+
+    method! vpredicate_node p =
+      let fail () =
+        raise (NYI (Format.asprintf
+                      "[logic_interp] %a" Printer.pp_predicate_node p))
+      in
+      match p with
+      | Pat (_, BuiltinLabel Old) -> self#change_label_to_old p
+      | Pat (_, BuiltinLabel Here) -> self#change_label_to_here p
+      | Pat (_, BuiltinLabel Pre) -> self#change_label_to_pre p
+      | Pat (_, BuiltinLabel Post) -> self#change_label_to_post p
+      | Pat (_, BuiltinLabel Init) ->
+        self#change_label_aux AbsLabel_init p
+      | Pat (_, BuiltinLabel LoopCurrent) ->
+        self#change_label_aux AbsLabel_loop_current p
+      | Pat (_, BuiltinLabel LoopEntry) ->
+        self#change_label_aux AbsLabel_loop_entry p
+      | Pat (_, FormalLabel s) ->
+        failwith ("unknown logic label" ^ s)
+      | Pat (_, StmtLabel st) -> self#change_label_to_stmt !st p
+      | Pfalse | Ptrue | Prel _ | Pand _ | Por _ | Pxor _ | Pimplies _
+      | Piff _ | Pnot _ | Pif _ | Plet _ | Pforall _ | Pexists _
+      | Papp (_, [], _) (* No label, thus cannot access memory *)
+      | Pseparated _ (* need only to preserve the values of each pointer *)
+        -> DoChildren
+
+      | Pinitialized (lbl, t) | Pdangling (lbl, t) ->
+        (* Dependencies of [\initialized(p)] or [\dangling(p)] are the
+            dependencies of [*p]. *)
+        if is_same_label current_label lbl then (
+          let typ = Logic_typing.type_of_pointed t.term_type in
+          let tlv = Cil.mkTermMem ~addr:t ~off:TNoOffset in
+          let tlv' = Logic_const.term (TLval tlv) typ in
+          self#do_term_lval tlv';
+          DoChildren
+        )
+        else fail ()
+
+      | Pvalid_read (_lbl, _) | Pvalid (_lbl, _) ->
+        (* Does not take dynamic allocation into account, but then
+            Value does not either. [lbl] can be ignored because they are
+            taken into account by the functions [from_...] below *)
+        DoChildren
+
+      | Pobject_pointer _ | Pvalid_function _ ->
+        DoChildren
+
+      | Papp _ | Pallocable _ | Pfreeable _ | Pfresh _
+        -> fail ()
+
+    method private do_term_lval t =
+      let current_before, current_stmt = self#get_ctrl_point () in
+      match !compute_term_deps current_stmt t with
+      | Some zone ->
+        let filter = function Base.CLogic_Var _ -> false | _ -> true in
+        let zone = Locations.Zone.filter_base filter zone in
+        zones <- add_zone ~before:current_before current_stmt zone zones
+      | None ->
+        raise (NYI "[logic_interp] dependencies of a term lval")
+
+    method! vterm t =
+      match t.term_node with
+      | TAddrOf _ | TLval (TMem _,_)
+      | TLval(TVar {lv_origin = Some _},_) | TStartOf _  ->
+        self#do_term_lval t;
+        SkipChildren
+      | Tat (_, BuiltinLabel Old) -> self#change_label_to_old t
+      | Tat (_, BuiltinLabel Here) -> self#change_label_to_here t
+      | Tat (_, BuiltinLabel Pre) -> self#change_label_to_pre t
+      | Tat (_, BuiltinLabel Post) -> self#change_label_to_post t
+      | Tat (_, BuiltinLabel Init) ->
+        self#change_label_aux AbsLabel_init t
+      | Tat (_, BuiltinLabel LoopCurrent) ->
+        self#change_label_aux AbsLabel_loop_current t
+      | Tat (_, BuiltinLabel LoopEntry) ->
+        self#change_label_aux AbsLabel_loop_entry t
+      | Tat (_, StmtLabel st) -> self#change_label_to_stmt !st t
+      | Tat (_, FormalLabel s) ->
+        failwith ("unknown logic label" ^ s)
+      | TSizeOf _ | TSizeOfE _ | TSizeOfStr _ | TAlignOf _ | TAlignOfE _ ->
+        (* These are static constructors, there are no dependencies here *)
+        SkipChildren
+      | _ -> DoChildren
+  end
+  in
+  try
+    ignore (visit (vis :> Visitor.frama_c_inplace) cil_node);
+    vis#get_zones
+  with NYI msg ->
+    add_top_zone msg (vis#get_zones)
+
+let update_pragmas f results =
+  { results with pragmas = f results.pragmas }
+
+let add_ctrl_pragma stmt =
+  update_pragmas (fun x -> { x with ctrl = Stmt.Set.add stmt x.ctrl })
+
+let add_stmt_pragma stmt =
+  update_pragmas (fun x -> { x with stmt = Stmt.Set.add stmt x.stmt })
+
+let add_results_from_term ctx results t =
+  let zones = populate_zone ctx Visitor.visitFramacTerm t results.zones in
+  {
+    results with
+    zones;
+    locals = Varinfo.Set.union (extract_locals_from_term t) results.locals;
+    labels = Logic_label.Set.union (extract_labels_from_term t) results.labels
+  }
+
+let add_results_from_pred ctx results p =
+  let zones = populate_zone ctx Visitor.visitFramacPredicate p results.zones in
+  {
+    results with
+    zones;
+    locals = Varinfo.Set.union (extract_locals_from_pred p) results.locals;
+    labels = Logic_label.Set.union (extract_labels_from_pred p) results.labels
+  }
+
+(** Entry point to get the list of [ki] * [Locations.Zone.t]
+    needed to evaluate the list of [terms]
+    relative to the [ctx] of interpretation. *)
+let from_terms terms ctx =
+  List.fold_left (add_results_from_term ctx) empty_results terms |>
+  get_result
+
+(** Entry point to get the list of [ki] * [Locations.Zone.t]
+    needed to evaluate the [term]
+    relative to the [ctx] of interpretation. *)
+let from_term term ctx =
+  add_results_from_term ctx empty_results term |>
+  get_result
+
+(** Entry point to get the list of [ki] * [Locations.Zone.t]
+    needed to evaluate the list of [preds]
+    relative to the [ctx] of interpretation. *)
+let from_preds preds ctx =
+  List.fold_left (add_results_from_pred ctx) empty_results preds |>
+  get_result
+
+(** Entry point to get the list of [ki] * [Locations.Zone.t]
+    needed to evaluate the [pred]
+    relative to the [ctx] of interpretation. *)
+let from_pred pred ctx =
+  add_results_from_pred ctx empty_results pred |>
+  get_result
+
+(** Used by annotations entry points. *)
+let get_zone_from_annot a (ki,kf) loop_body_opt results =
+  let get_zone_from_term k term results =
+    let ctx = { state_opt = Some true; ki_opt = Some (k, true); kf } in
+    add_results_from_term ctx results term
+  and get_zone_from_pred k pred results =
+    let ctx = { state_opt = Some true; ki_opt = Some (k, true); kf } in
+    add_results_from_pred ctx results pred
+  in
+  match a.annot_content with
+  | APragma (Slice_pragma (SPexpr term) | Impact_pragma (IPexpr term)) ->
+    results |>
+    (* to preserve the interpretation of the pragma *)
+    get_zone_from_term ki term |>
+    (* to select the reachability of the pragma *)
+    add_ctrl_pragma ki
+  | APragma (Slice_pragma SPctrl) ->
+    (* to select the reachability of the pragma *)
+    add_ctrl_pragma ki results
+  | APragma (Slice_pragma SPstmt | Impact_pragma IPstmt) ->
+    (* to preserve the effect of the statement *)
+    add_stmt_pragma ki results
+  | AAssert (_behav,pred) ->
+    (* to preserve the interpretation of the assertion *)
+    get_zone_from_pred ki pred.tp_statement results
+  | AInvariant (_behav,true,pred) -> (* loop invariant *)
+    (* WARNING this is obsolete *)
+    (* [JS 2010/09/02] TODO: so what is the right way to do? *)
+    (* to preserve the interpretation of the loop invariant *)
+    get_zone_from_pred (Option.get loop_body_opt) pred.tp_statement results
+  | AInvariant (_behav,false,pred) -> (* code invariant *)
+    (* to preserve the interpretation of the code invariant *)
+    get_zone_from_pred ki pred.tp_statement results
+  | AVariant (term,_) ->
+    (* to preserve the interpretation of the variant *)
+    get_zone_from_term (Option.get loop_body_opt) term results
+  | APragma (Loop_pragma (Unroll_specs terms))
+  | APragma (Loop_pragma (Widen_hints terms))
+  | APragma (Loop_pragma (Widen_variables terms)) ->
+    (* to select the declaration of the variables *)
+    List.fold_left
+      (fun results term -> {
+           results with
+           locals = Varinfo.Set.union (extract_locals_from_term term) results.locals;
+           labels = Logic_label.Set.union (extract_labels_from_term term) results.labels
+         })
+      results terms
+  | AAllocation (_,FreeAllocAny) -> results
+  | AAllocation (_,FreeAlloc(f,a)) ->
+    let get_zone results x =
+      get_zone_from_term (Option.get loop_body_opt) x.it_content results
+    in
+    let results = List.fold_left get_zone results f in
+    let results = List.fold_left get_zone results a in
+    results
+  | AAssigns (_, WritesAny) -> results
+  | AAssigns (_, Writes l) -> (* loop assigns *)
+    let get_zone results x =
+      get_zone_from_term (Option.get loop_body_opt) x.it_content results
+    in
+    List.fold_left
+      (fun results (zone,deps) ->
+         let results = get_zone results zone in
+         match deps with
+           FromAny -> results
+         | From l -> List.fold_left get_zone results l)
+      results l
+  | AStmtSpec _ -> (* TODO *)
+    raise (NYI "[logic_interp] statement contract")
+  | AExtended _ -> raise (NYI "[logic_interp] extension")
+
+(* Used by annotations entry points. *)
+let get_from_stmt_annots code_annot_filter ((ki, _kf) as stmt) results =
+  Option.fold
+    ~none:results
+    ~some:(fun caf ->
+        let loop_body_opt = match ki.skind with
+          | Loop(_, { bstmts = body :: _ }, _, _, _) -> Some body
+          | _ -> None
+        in
+        Annotations.fold_code_annot
+          (fun _ a results ->
+             if caf a
+             then get_zone_from_annot a stmt loop_body_opt results
+             else results)
+          ki results)
+    code_annot_filter
+
+(** Used by annotations entry points. *)
+let from_ki_annot annot ((ki, _kf) as stmt) =
+  let real_ki = match ki.skind with
+      Loop(_,{bstmts = loop_entry::_},_,_,_) -> Some loop_entry
+    | _ -> None
+  in
+  get_zone_from_annot annot stmt real_ki
+
+(** Entry point to get the list of [ki] * [Locations.Zone.t]
+    needed to evaluate the code annotations related to this [stmt]. *)
+let from_stmt_annot annot stmt =
+  from_ki_annot annot stmt empty_results |>
+  get_annot_result
+
+(** Entry point to get the list of [ki] * [Locations.Zone.t]
+    needed to evaluate the code annotations related to this [stmt]. *)
+let from_stmt_annots code_annot_filter stmt =
+  get_from_stmt_annots code_annot_filter stmt empty_results |>
+  get_annot_result
+
+(** Entry point to get the list of [ki] * [Locations.Zone.t]
+    needed to evaluate the code annotations related to this [kf]. *)
+let from_func_annots iter_on_kf_stmt code_annot_filter kf =
+  let results = ref empty_results in
+  let from_stmt_annots ki =
+    results := get_from_stmt_annots code_annot_filter (ki, kf) !results
+  in
+  iter_on_kf_stmt from_stmt_annots kf;
+  get_annot_result !results
+
+(** To quickly build a annotation filter *)
+let code_annot_filter annot ~threat ~user_assert ~slicing_pragma ~loop_inv ~loop_var ~others =
+  match annot.annot_content with
+  | APragma (Slice_pragma _) -> slicing_pragma
+  | AAssert _ ->
+    (match Alarms.find annot with
+     | None -> user_assert
+     | Some _a -> threat)
+  | AVariant _ -> loop_var
+  | AInvariant(_behav,true,_pred) -> loop_inv
+  | AInvariant(_,false,_) -> others
+  | AAllocation _ -> others
+  | AAssigns _ -> others
+  | APragma (Loop_pragma _)| APragma (Impact_pragma _) -> others
+  | AStmtSpec _  | AExtended _ (* TODO *) -> false
+
+
+exception Prune
+
+let to_result_from_pred p =
+  let visitor = object (_self)
+    inherit Visitor.frama_c_inplace
+
+    method! vterm_lhost t =
+      match t with
+      | TResult _ -> raise Prune
+      | _ -> DoChildren
+
+  end
+  in
+  (try
+     ignore(Visitor.visitFramacPredicate visitor p);
+     false
+   with Prune ->
+     true)
+
+
+let () =
+  Db.Properties.Interp.To_zone.code_annot_filter := code_annot_filter;
+  Db.Properties.Interp.To_zone.mk_ctx_func_contrat := mk_ctx_func_contrat;
+  Db.Properties.Interp.To_zone.mk_ctx_stmt_contrat := mk_ctx_stmt_contrat;
+  Db.Properties.Interp.To_zone.mk_ctx_stmt_annot := mk_ctx_stmt_annot;
+
+  Db.Properties.Interp.To_zone.from_term := from_term;
+  Db.Properties.Interp.To_zone.from_terms := from_terms;
+  Db.Properties.Interp.To_zone.from_pred := from_pred;
+  Db.Properties.Interp.To_zone.from_preds := from_preds;
+  Db.Properties.Interp.To_zone.from_stmt_annot := from_stmt_annot;
+  Db.Properties.Interp.To_zone.from_stmt_annots := from_stmt_annots;
+  Db.Properties.Interp.To_zone.from_func_annots := from_func_annots;
+
+  Db.Properties.Interp.to_result_from_pred := to_result_from_pred;
diff --git a/src/kernel_services/analysis/logic_deps.mli b/src/kernel_services/analysis/logic_deps.mli
new file mode 100644
index 0000000000000000000000000000000000000000..fa485d47605aa6940c809fe51c0e5fbbd4820d4e
--- /dev/null
+++ b/src/kernel_services/analysis/logic_deps.mli
@@ -0,0 +1,96 @@
+(**************************************************************************)
+(*                                                                        *)
+(*  This file is part of Frama-C.                                         *)
+(*                                                                        *)
+(*  Copyright (C) 2007-2022                                               *)
+(*    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).            *)
+(*                                                                        *)
+(**************************************************************************)
+
+open Cil_types
+
+val compute_term_deps: (stmt -> term -> Locations.Zone.t option) ref
+
+type ctx = Db.Properties.Interp.To_zone.t_ctx
+
+val mk_ctx_func_contrat: kernel_function -> state_opt:bool option -> ctx
+(** To build an interpretation context relative to function
+    contracts. *)
+
+val mk_ctx_stmt_contrat: kernel_function -> stmt -> state_opt:bool option -> ctx
+(** To build an interpretation context relative to statement
+    contracts. *)
+
+val mk_ctx_stmt_annot: kernel_function -> stmt -> ctx
+(** To build an interpretation context relative to statement
+    annotations. *)
+
+type t = Db.Properties.Interp.To_zone.t
+type zone_info = Db.Properties.Interp.To_zone.t_zone_info
+(** list of zones at some program points.
+ *   None means that the computation has failed. *)
+
+type decl = Db.Properties.Interp.To_zone.t_decl
+type pragmas = Db.Properties.Interp.To_zone.t_pragmas
+
+val from_term: term -> ctx -> zone_info * decl
+(** Entry point to get zones needed to evaluate the [term] relative to
+    the [ctx] of interpretation. *)
+
+val from_terms: term list -> ctx -> zone_info * decl
+(** Entry point to get zones needed to evaluate the list of [terms]
+    relative to the [ctx] of interpretation. *)
+
+val from_pred: predicate -> ctx -> zone_info * decl
+(** Entry point to get zones needed to evaluate the [predicate]
+    relative to the [ctx] of interpretation. *)
+
+val from_preds: predicate list -> ctx -> zone_info * decl
+(** Entry point to get zones needed to evaluate the list of
+    [predicates] relative to the [ctx] of interpretation. *)
+
+val from_stmt_annot:
+  code_annotation -> stmt * kernel_function ->
+  (zone_info * decl) * pragmas
+(** Entry point to get zones needed to evaluate an annotation on the
+    given stmt. *)
+
+val from_stmt_annots:
+  (code_annotation -> bool) option ->
+  stmt * kernel_function -> (zone_info * decl) * pragmas
+(** Entry point to get zones needed to evaluate annotations of this
+    [stmt]. *)
+
+val from_func_annots:
+  ((stmt -> unit) -> kernel_function -> unit) ->
+  (code_annotation -> bool) option ->
+  kernel_function -> (zone_info * decl) * pragmas
+(** Entry point to get zones
+    needed to evaluate annotations of this [kf]. *)
+
+val code_annot_filter:
+  code_annotation ->
+  threat:bool -> user_assert:bool -> slicing_pragma:bool ->
+  loop_inv:bool -> loop_var:bool -> others:bool -> bool
+(** To quickly build an annotation filter *)
+
+(** Does the interpretation of the predicate rely on the interpretation
+    of the term result? *)
+val to_result_from_pred: predicate -> bool
+
+(** The follow declarations are kept for compatibility and should not be used *)
+exception NYI of string
+val not_yet_implemented: string ref
diff --git a/src/kernel_services/analysis/logic_interp.ml b/src/kernel_services/analysis/logic_interp.ml
index c2545b30ac9ab205c9cacb82fe05ad423b6a2927..6c96f61d9b9a3b34dd459b0776c136894184fb06 100644
--- a/src/kernel_services/analysis/logic_interp.ml
+++ b/src/kernel_services/analysis/logic_interp.ml
@@ -20,699 +20,10 @@
 (*                                                                        *)
 (**************************************************************************)
 
-open Cil
-open Cil_types
-open Cil_datatype
-
 exception Error = Logic_parse_string.Error
 
-
-(** Utilities to identify [Locations.Zone.t] involved into
-    [code_annotation]. *)
-module To_zone : sig
-
-  type ctx = Db.Properties.Interp.To_zone.t_ctx =
-    {state_opt:bool option;
-     ki_opt:(stmt * bool) option;
-     kf:Kernel_function.t}
-
-  val mk_ctx_func_contrat: kernel_function -> state_opt:bool option -> ctx
-  (** [mk_ctx_func_contrat] to define an interpretation context related to
-      [kernel_function] contracts.
-      The control point of the interpretation is defined as follows:
-      - pre-state if  [state_opt=Some true]
-      - post-state if [state_opt=Some false]
-      - pre-state with possible reference to the post-state if
-        [state_opt=None]. *)
-
-  val mk_ctx_stmt_contrat:
-    kernel_function -> stmt -> state_opt:bool option -> ctx
-  (** [mk_ctx_stmt_contrat] to define an interpretation context related to
-      [stmt] contracts.
-      The control point of the interpretation is defined as follows:
-      - pre-state if  [state_opt=Some true]
-      - post-state if [state_opt=Some false]
-      - pre-state with possible reference to the post-state if
-        [state_opt=None]. *)
-
-  val mk_ctx_stmt_annot: kernel_function -> stmt -> ctx
-  (** [mk_ctx_stmt_annot] to define an interpretation context related to an
-      annotation attached before the [stmt]. *)
-
-  type zone_info = Db.Properties.Interp.To_zone.t_zone_info
-  type decl = Db.Properties.Interp.To_zone.t_decl
-  type pragmas = Db.Properties.Interp.To_zone.t_pragmas
-  val not_yet_implemented : string ref
-  exception NYI of string
-
-  val compute_term_deps: (stmt -> term -> Locations.Zone.t option) ref
-  (** Provided by Eva, compute the memory zone on which a term depends. *)
-
-  val from_term: term -> ctx -> (zone_info * decl)
-  (** Entry point to get zones
-      needed to evaluate the [term] relative to the [ctx] of
-      interpretation. *)
-
-  val from_terms: term list -> ctx -> (zone_info * decl)
-  (** Entry point to get zones
-      needed to evaluate the list of [terms] relative to the [ctx] of
-      interpretation. *)
-
-  val from_pred: predicate -> ctx -> (zone_info * decl)
-  (** Entry point to get zones
-      needed to evaluate the [predicate] relative to the [ctx] of
-      interpretation. *)
-
-  val from_preds: predicate list -> ctx -> (zone_info * decl)
-  (** Entry point to get zones
-      needed to evaluate the list of [predicates] relative to the [ctx] of
-      interpretation. *)
-
-  val from_stmt_annot:
-    code_annotation -> (stmt * kernel_function) ->
-    (zone_info * decl) * pragmas
-  (** Entry point to get zones needed to evaluate code annotations of this
-      [stmt]. *)
-
-  val from_stmt_annots:
-    (code_annotation -> bool) option ->
-    (stmt * kernel_function) -> (zone_info * decl) * pragmas
-  (** Entry point to get zones needed to evaluate code annotations of this
-      [stmt]. *)
-
-  val from_func_annots:
-    ((stmt -> unit) -> kernel_function -> unit) ->
-    (code_annotation  -> bool) option ->
-    kernel_function -> (zone_info * decl) * pragmas
-  (** Entry point to get zones needed to evaluate code annotations of this
-      [kf]. *)
-
-  val code_annot_filter:
-    code_annotation ->
-    threat:bool -> user_assert:bool -> slicing_pragma:bool ->
-    loop_inv:bool -> loop_var:bool -> others:bool -> bool
-    (** To quickly build a annotation filter *)
-end
-=
+module To_zone =
 struct
-
-  exception NYI of string
-  (* Reimport here the type definitions of Db.Properties.Interp. See
-     documentation there. *)
-  type ctx = Db.Properties.Interp.To_zone.t_ctx =
-    {state_opt:bool option;
-     ki_opt:(stmt * bool) option;
-     kf:Kernel_function.t}
-
-  type pragmas = Db.Properties.Interp.To_zone.t_pragmas =
-    {ctrl: Stmt.Set.t ; stmt: Stmt.Set.t}
-
-  type t = Db.Properties.Interp.To_zone.t
-  = {before:bool ; ki:stmt ; zone:Locations.Zone.t}
-  type zone_info = Db.Properties.Interp.To_zone.t_zone_info
-
-  type decl = Db.Properties.Interp.To_zone.t_decl =
-    {var: Varinfo.Set.t ; lbl: Logic_label.Set.t}
-
-  let mk_ctx_func_contrat kf ~state_opt =
-    { state_opt = state_opt;
-      ki_opt = None;
-      kf = kf }
-
-  let mk_ctx_stmt_contrat kf ki ~state_opt =
-    { state_opt=state_opt;
-      ki_opt= Some(ki, false);
-      kf = kf }
-
-  let mk_ctx_stmt_annot kf ki =
-    { state_opt = Some true;
-      ki_opt = Some(ki, true);
-      kf = kf }
-
-  type result = {
-    pragmas: pragmas;
-    locals: Varinfo.Set.t;
-    labels: Logic_label.Set.t;
-    zones: (Locations.Zone.t * Locations.Zone.t) Stmt.Map.t option;
-  }
-
-  let empty_pragmas =
-    { ctrl = Stmt.Set.empty;
-      stmt = Stmt.Set.empty }
-
-  let empty_results = {
-    pragmas = empty_pragmas;
-    locals = Varinfo.Set.empty;
-    labels = Logic_label.Set.empty;
-    zones = Some Stmt.Map.empty;
-  }
-
-  let not_yet_implemented = ref ""
-
-  let compute_term_deps = ref (fun _stmt _expr -> None)
-
-  let add_top_zone not_yet_implemented_msg =
-    function
-    | None -> (* top zone *) None
-    | Some _ ->
-      not_yet_implemented := not_yet_implemented_msg;
-      None
-
-  let add_zone ~before ki zone =
-    function
-    | None -> (* top zone *) None
-    | Some other_zones ->
-      let zone_true, zone_false =
-        try Stmt.Map.find ki other_zones
-        with Not_found -> Locations.Zone.bottom, Locations.Zone.bottom
-      in
-      let new_zone =
-        if before
-        then Locations.Zone.join zone_true zone, zone_false
-        else zone_true, Locations.Zone.join zone_false zone
-      in
-      Some (Stmt.Map.add ki new_zone other_zones)
-
-  let get_result result =
-    let zones =
-      match result.zones with
-      | None -> None
-      | Some other_zones ->
-        let zones =
-          Stmt.Map.to_seq other_zones |>
-          Seq.flat_map (fun (ki, (zone_true, zone_false)) ->
-              List.to_seq [
-                { before=false; ki; zone=zone_false } ;
-                { before=true; ki; zone=zone_true }
-              ]) |>
-          Seq.filter (fun x ->
-              not (Locations.Zone.equal Locations.Zone.bottom x.zone)) |>
-          List.of_seq
-        in
-        Some zones
-    in
-    zones, {var = result.locals; lbl = result.labels}
-
-  let get_annot_result result =
-    get_result result, result.pragmas
-
-  (** Logic_var utility: *)
-  let extract_locals logicvars =
-    Logic_var.Set.fold
-      (fun lv cvars -> match lv.lv_origin with
-         | None -> cvars
-         | Some cvar ->
-           if cvar.Cil_types.vglob then cvars
-           else Varinfo.Set.add cvar cvars)
-      logicvars
-      Varinfo.Set.empty
-
-  (** Term utility:
-      Extract C local variables occurring into a [term]. *)
-  let extract_locals_from_term term =
-    extract_locals (extract_free_logicvars_from_term term)
-
-  (** Predicate utility:
-      Extract C local variables occurring into a [term]. *)
-  let extract_locals_from_pred pred =
-    extract_locals (extract_free_logicvars_from_predicate pred)
-
-  type abs_label = | AbsLabel_here
-                   | AbsLabel_pre
-                   | AbsLabel_post
-                   | AbsLabel_init
-                   | AbsLabel_loop_entry
-                   | AbsLabel_loop_current
-                   | AbsLabel_stmt of stmt
-
-  let is_same_label absl l =
-    match absl, l with
-    | AbsLabel_stmt s1, StmtLabel s2 -> Cil_datatype.Stmt.equal s1 !s2
-    | AbsLabel_here, BuiltinLabel Here -> true
-    | AbsLabel_pre, BuiltinLabel Pre -> true
-    | AbsLabel_post, BuiltinLabel Post -> true
-    | AbsLabel_init, BuiltinLabel Init -> true
-    | AbsLabel_loop_entry, BuiltinLabel LoopEntry -> true
-    | AbsLabel_loop_current, BuiltinLabel LoopCurrent -> true
-    | _, (StmtLabel _ | FormalLabel _ | BuiltinLabel _) -> false
-
-
-  let populate_zone ctx visit cil_node current_zones =
-    let { state_opt=before_opt; ki_opt; kf } = ctx in
-    (* interpretation from the
-       - pre-state if  [before_opt=Some true]
-       - post-state if [before_opt=Some false]
-       - pre-state with possible reference to the post-state if
-         [before_opt=None] of a property relative to
-       - the contract of function [kf] when [ki_opt=None]
-         otherwise [ki_opt=Some(ki, code_annot)],
-       - the contract of the statement [ki] when [code_annot=false]
-       - the annotation of the statement [ki] when [code_annot=true] *)
-    let vis = object(self)
-      inherit Visitor.frama_c_inplace
-      val mutable current_label = AbsLabel_here
-      val mutable zones = current_zones
-      method get_zones = zones
-
-      method private get_ctrl_point () =
-        let get_fct_entry_point () =
-          (* TODO: to replace by true, None *)
-          true,
-          (try Some (Kernel_function.find_first_stmt kf)
-           with Kernel_function.No_Statement ->
-             (* raised when [kf] has no code. *)
-             None)
-        in
-        let get_ctrl_point dft =
-          let before = Option.value ~default:dft before_opt in
-          match ki_opt with
-          | None -> (* function contract *)
-
-            if before then get_fct_entry_point ()
-            else before, None
-          (* statement contract *)
-          | Some (ki,_) ->  (* statement contract and code annotation *)
-            before, Some ki
-        in
-        let result = match current_label with
-          | AbsLabel_stmt stmt -> true, Some stmt
-          | AbsLabel_pre -> get_fct_entry_point ()
-          | AbsLabel_here -> get_ctrl_point true
-          | AbsLabel_post -> get_ctrl_point false
-          | AbsLabel_init -> raise (NYI "[logic_interp] Init label")
-          | AbsLabel_loop_current ->
-            raise (NYI "[logic_interp] LoopCurrent label")
-          | AbsLabel_loop_entry ->
-            raise (NYI "[logic_interp] LoopEntry label")
-        in (* TODO: the method should be able to return result directly *)
-        match result with
-        | current_before, Some current_stmt -> current_before, current_stmt
-        | _ -> raise (NYI
-                        "[logic_interp] clause related to a function contract")
-
-      method private change_label: 'a.abs_label -> 'a -> 'a visitAction =
-        fun label x ->
-        let old_label = current_label in
-        current_label <- label;
-        ChangeDoChildrenPost
-          (x,fun x -> current_label <- old_label; x)
-
-      method private change_label_to_here: 'a.'a -> 'a visitAction =
-        fun x ->
-        self#change_label AbsLabel_here x
-
-      method private change_label_to_old: 'a.'a -> 'a visitAction =
-        fun x ->
-        match ki_opt,before_opt with
-        (* function contract *)
-        | None,Some true ->
-          failwith "The use of the label Old is forbidden inside clauses \
-                    related to the pre-state of function contracts."
-        | None,None
-        | None,Some false ->
-          (* refers to the pre-state of the contract. *)
-          self#change_label AbsLabel_pre x
-        (* statement contract *)
-        | Some (_ki,false),Some true  ->
-          failwith "The use of the label Old is forbidden inside clauses \
-                    related to the pre-state of statement contracts."
-        | Some (ki,false),None
-        | Some (ki,false),Some false  ->
-          (* refers to the pre-state of the contract. *)
-          self#change_label (AbsLabel_stmt ki) x
-        (* code annotation *)
-        | Some (_ki,true),None
-        | Some (_ki,true),Some _ ->
-          (* refers to the pre-state of the function contract. *)
-          self#change_label AbsLabel_pre x
-
-      method private change_label_to_post: 'a.'a -> 'a visitAction =
-        fun x ->
-        (* allowed when [before_opt=None] for function/statement contracts *)
-        match ki_opt,before_opt with
-        (* function contract *)
-        | None,Some _ ->
-          failwith "Function contract where the use of the label Post is \
-                    forbidden."
-        | None,None ->
-          (* refers to the post-state of the contract. *)
-          self#change_label AbsLabel_post x
-        (* statement contract *)
-        | Some (_ki,false),Some _  ->
-          failwith "Statement contract where the use of the label Post is \
-                    forbidden."
-        | Some (_ki,false),None ->
-          (* refers to the pre-state of the contract. *)
-          self#change_label AbsLabel_post x
-        (* code annotation *)
-        | Some (_ki,true), _ ->
-          failwith "The use of the label Post is forbidden inside code \
-                    annotations."
-
-      method private change_label_to_pre: 'a.'a -> 'a visitAction =
-        fun x ->
-        match ki_opt with
-        (* function contract *)
-        | None ->
-          failwith "The use of the label Pre is forbidden inside function \
-                    contracts."
-        (* statement contract *)
-        (* code annotation *)
-        | Some _ ->
-          (* refers to the pre-state of the function contract. *)
-          self#change_label AbsLabel_pre x
-
-      method private change_label_aux: 'a. _ -> 'a -> 'a visitAction =
-        fun lbl x -> self#change_label lbl x
-
-      method private change_label_to_stmt: 'a.stmt -> 'a -> 'a visitAction =
-        fun stmt x ->
-        match ki_opt with
-        (* function contract *)
-        | None ->
-          failwith "the use of C labels is forbidden inside clauses related \
-                    to function contracts."
-        (* statement contract *)
-        (* code annotation *)
-        | Some _ ->
-          (* refers to the state at the C label of the statement [stmt]. *)
-          self#change_label (AbsLabel_stmt stmt) x
-
-
-      method! vpredicate_node p =
-        let fail () =
-          raise (NYI (Format.asprintf
-                        "[logic_interp] %a" Printer.pp_predicate_node p))
-        in
-        match p with
-        | Pat (_, BuiltinLabel Old) -> self#change_label_to_old p
-        | Pat (_, BuiltinLabel Here) -> self#change_label_to_here p
-        | Pat (_, BuiltinLabel Pre) -> self#change_label_to_pre p
-        | Pat (_, BuiltinLabel Post) -> self#change_label_to_post p
-        | Pat (_, BuiltinLabel Init) ->
-          self#change_label_aux AbsLabel_init p
-        | Pat (_, BuiltinLabel LoopCurrent) ->
-          self#change_label_aux AbsLabel_loop_current p
-        | Pat (_, BuiltinLabel LoopEntry) ->
-          self#change_label_aux AbsLabel_loop_entry p
-        | Pat (_, FormalLabel s) ->
-          failwith ("unknown logic label" ^ s)
-        | Pat (_, StmtLabel st) -> self#change_label_to_stmt !st p
-        | Pfalse | Ptrue | Prel _ | Pand _ | Por _ | Pxor _ | Pimplies _
-        | Piff _ | Pnot _ | Pif _ | Plet _ | Pforall _ | Pexists _
-        | Papp (_, [], _) (* No label, thus cannot access memory *)
-        | Pseparated _ (* need only to preserve the values of each pointer *)
-          -> DoChildren
-
-        | Pinitialized (lbl, t) | Pdangling (lbl, t) ->
-          (* Dependencies of [\initialized(p)] or [\dangling(p)] are the
-             dependencies of [*p]. *)
-          if is_same_label current_label lbl then (
-            let typ = Logic_typing.type_of_pointed t.term_type in
-            let tlv = Cil.mkTermMem ~addr:t ~off:TNoOffset in
-            let tlv' = Logic_const.term (TLval tlv) typ in
-            self#do_term_lval tlv';
-            DoChildren
-          )
-          else fail ()
-
-        | Pvalid_read (_lbl, _) | Pvalid (_lbl, _) ->
-          (* Does not take dynamic allocation into account, but then
-             Value does not either. [lbl] can be ignored because they are
-             taken into account by the functions [from_...] below *)
-          DoChildren
-
-        | Pobject_pointer _ | Pvalid_function _ ->
-          DoChildren
-
-        | Papp _ | Pallocable _ | Pfreeable _ | Pfresh _
-          -> fail ()
-
-      method private do_term_lval t =
-        let current_before, current_stmt = self#get_ctrl_point () in
-        match !compute_term_deps current_stmt t with
-        | Some zone ->
-          let filter = function Base.CLogic_Var _ -> false | _ -> true in
-          let zone = Locations.Zone.filter_base filter zone in
-          zones <- add_zone ~before:current_before current_stmt zone zones
-        | None ->
-          raise (NYI "[logic_interp] dependencies of a term lval")
-
-      method! vterm t =
-        match t.term_node with
-        | TAddrOf _ | TLval (TMem _,_)
-        | TLval(TVar {lv_origin = Some _},_) | TStartOf _  ->
-          self#do_term_lval t;
-          SkipChildren
-        | Tat (_, BuiltinLabel Old) -> self#change_label_to_old t
-        | Tat (_, BuiltinLabel Here) -> self#change_label_to_here t
-        | Tat (_, BuiltinLabel Pre) -> self#change_label_to_pre t
-        | Tat (_, BuiltinLabel Post) -> self#change_label_to_post t
-        | Tat (_, BuiltinLabel Init) ->
-          self#change_label_aux AbsLabel_init t
-        | Tat (_, BuiltinLabel LoopCurrent) ->
-          self#change_label_aux AbsLabel_loop_current t
-        | Tat (_, BuiltinLabel LoopEntry) ->
-          self#change_label_aux AbsLabel_loop_entry t
-        | Tat (_, StmtLabel st) -> self#change_label_to_stmt !st t
-        | Tat (_, FormalLabel s) ->
-          failwith ("unknown logic label" ^ s)
-        | TSizeOf _ | TSizeOfE _ | TSizeOfStr _ | TAlignOf _ | TAlignOfE _ ->
-          (* These are static constructors, there are no dependencies here *)
-          SkipChildren
-        | _ -> DoChildren
-    end
-    in
-    try
-      ignore (visit (vis :> Visitor.frama_c_inplace) cil_node);
-      vis#get_zones
-    with NYI msg ->
-      add_top_zone msg (vis#get_zones)
-
-  let update_pragmas f results =
-    { results with pragmas = f results.pragmas }
-
-  let add_ctrl_pragma stmt =
-    update_pragmas (fun x -> { x with ctrl = Stmt.Set.add stmt x.ctrl })
-
-  let add_stmt_pragma stmt =
-    update_pragmas (fun x -> { x with stmt = Stmt.Set.add stmt x.stmt })
-
-  let add_results_from_term ctx results t =
-    let zones = populate_zone ctx Visitor.visitFramacTerm t results.zones in
-    {
-      results with
-      zones;
-      locals = Varinfo.Set.union (extract_locals_from_term t) results.locals;
-      labels = Logic_label.Set.union (extract_labels_from_term t) results.labels
-    }
-
-  let add_results_from_pred ctx results p =
-    let zones = populate_zone ctx Visitor.visitFramacPredicate p results.zones in
-    {
-      results with
-      zones;
-      locals = Varinfo.Set.union (extract_locals_from_pred p) results.locals;
-      labels = Logic_label.Set.union (extract_labels_from_pred p) results.labels
-    }
-
-  (** Entry point to get the list of [ki] * [Locations.Zone.t]
-      needed to evaluate the list of [terms]
-      relative to the [ctx] of interpretation. *)
-  let from_terms terms ctx =
-    List.fold_left (add_results_from_term ctx) empty_results terms |>
-    get_result
-
-  (** Entry point to get the list of [ki] * [Locations.Zone.t]
-      needed to evaluate the [term]
-      relative to the [ctx] of interpretation. *)
-  let from_term term ctx =
-    add_results_from_term ctx empty_results term |>
-    get_result
-
-  (** Entry point to get the list of [ki] * [Locations.Zone.t]
-      needed to evaluate the list of [preds]
-      relative to the [ctx] of interpretation. *)
-  let from_preds preds ctx =
-    List.fold_left (add_results_from_pred ctx) empty_results preds |>
-    get_result
-
-  (** Entry point to get the list of [ki] * [Locations.Zone.t]
-      needed to evaluate the [pred]
-      relative to the [ctx] of interpretation. *)
-  let from_pred pred ctx =
-    add_results_from_pred ctx empty_results pred |>
-    get_result
-
-  (** Used by annotations entry points. *)
-  let get_zone_from_annot a (ki,kf) loop_body_opt results =
-    let get_zone_from_term k term results =
-      let ctx = { state_opt = Some true; ki_opt = Some (k, true); kf } in
-      add_results_from_term ctx results term
-    and get_zone_from_pred k pred results =
-      let ctx = { state_opt = Some true; ki_opt = Some (k, true); kf } in
-      add_results_from_pred ctx results pred
-    in
-    match a.annot_content with
-    | APragma (Slice_pragma (SPexpr term) | Impact_pragma (IPexpr term)) ->
-      results |>
-      (* to preserve the interpretation of the pragma *)
-      get_zone_from_term ki term |>
-      (* to select the reachability of the pragma *)
-      add_ctrl_pragma ki
-    | APragma (Slice_pragma SPctrl) ->
-      (* to select the reachability of the pragma *)
-      add_ctrl_pragma ki results
-    | APragma (Slice_pragma SPstmt | Impact_pragma IPstmt) ->
-      (* to preserve the effect of the statement *)
-      add_stmt_pragma ki results
-    | AAssert (_behav,pred) ->
-      (* to preserve the interpretation of the assertion *)
-      get_zone_from_pred ki pred.tp_statement results
-    | AInvariant (_behav,true,pred) -> (* loop invariant *)
-      (* WARNING this is obsolete *)
-      (* [JS 2010/09/02] TODO: so what is the right way to do? *)
-      (* to preserve the interpretation of the loop invariant *)
-      get_zone_from_pred (Option.get loop_body_opt) pred.tp_statement results
-    | AInvariant (_behav,false,pred) -> (* code invariant *)
-      (* to preserve the interpretation of the code invariant *)
-      get_zone_from_pred ki pred.tp_statement results
-    | AVariant (term,_) ->
-      (* to preserve the interpretation of the variant *)
-      get_zone_from_term (Option.get loop_body_opt) term results
-    | APragma (Loop_pragma (Unroll_specs terms))
-    | APragma (Loop_pragma (Widen_hints terms))
-    | APragma (Loop_pragma (Widen_variables terms)) ->
-      (* to select the declaration of the variables *)
-      List.fold_left
-        (fun results term -> {
-             results with
-             locals = Varinfo.Set.union (extract_locals_from_term term) results.locals;
-             labels = Logic_label.Set.union (extract_labels_from_term term) results.labels
-           })
-        results terms
-    | AAllocation (_,FreeAllocAny) -> results
-    | AAllocation (_,FreeAlloc(f,a)) ->
-      let get_zone results x =
-        get_zone_from_term (Option.get loop_body_opt) x.it_content results
-      in
-      let results = List.fold_left get_zone results f in
-      let results = List.fold_left get_zone results a in
-      results
-    | AAssigns (_, WritesAny) -> results
-    | AAssigns (_, Writes l) -> (* loop assigns *)
-      let get_zone results x =
-        get_zone_from_term (Option.get loop_body_opt) x.it_content results
-      in
-      List.fold_left
-        (fun results (zone,deps) ->
-           let results = get_zone results zone in
-           match deps with
-             FromAny -> results
-           | From l -> List.fold_left get_zone results l)
-        results l
-    | AStmtSpec _ -> (* TODO *)
-      raise (NYI "[logic_interp] statement contract")
-    | AExtended _ -> raise (NYI "[logic_interp] extension")
-
-  (* Used by annotations entry points. *)
-  let get_from_stmt_annots code_annot_filter ((ki, _kf) as stmt) results =
-    Option.fold
-      ~none:results
-      ~some:(fun caf ->
-          let loop_body_opt = match ki.skind with
-            | Loop(_, { bstmts = body :: _ }, _, _, _) -> Some body
-            | _ -> None
-          in
-          Annotations.fold_code_annot
-            (fun _ a results ->
-               if caf a
-               then get_zone_from_annot a stmt loop_body_opt results
-               else results)
-            ki results)
-      code_annot_filter
-
-  (** Used by annotations entry points. *)
-  let from_ki_annot annot ((ki, _kf) as stmt) =
-    let real_ki = match ki.skind with
-        Loop(_,{bstmts = loop_entry::_},_,_,_) -> Some loop_entry
-      | _ -> None
-    in
-    get_zone_from_annot annot stmt real_ki
-
-  (** Entry point to get the list of [ki] * [Locations.Zone.t]
-      needed to evaluate the code annotations related to this [stmt]. *)
-  let from_stmt_annot annot stmt =
-    from_ki_annot annot stmt empty_results |>
-    get_annot_result
-
-  (** Entry point to get the list of [ki] * [Locations.Zone.t]
-      needed to evaluate the code annotations related to this [stmt]. *)
-  let from_stmt_annots code_annot_filter stmt =
-    get_from_stmt_annots code_annot_filter stmt empty_results |>
-    get_annot_result
-
-  (** Entry point to get the list of [ki] * [Locations.Zone.t]
-      needed to evaluate the code annotations related to this [kf]. *)
-  let from_func_annots iter_on_kf_stmt code_annot_filter kf =
-    let results = ref empty_results in
-    let from_stmt_annots ki =
-      results := get_from_stmt_annots code_annot_filter (ki, kf) !results
-    in
-    iter_on_kf_stmt from_stmt_annots kf;
-    get_annot_result !results
-
-  (** To quickly build a annotation filter *)
-  let code_annot_filter annot ~threat ~user_assert ~slicing_pragma ~loop_inv ~loop_var ~others =
-    match annot.annot_content with
-    | APragma (Slice_pragma _) -> slicing_pragma
-    | AAssert _ ->
-      (match Alarms.find annot with
-       | None -> user_assert
-       | Some _a -> threat)
-    | AVariant _ -> loop_var
-    | AInvariant(_behav,true,_pred) -> loop_inv
-    | AInvariant(_,false,_) -> others
-    | AAllocation _ -> others
-    | AAssigns _ -> others
-    | APragma (Loop_pragma _)| APragma (Impact_pragma _) -> others
-    | AStmtSpec _  | AExtended _ (* TODO *) -> false
+  exception NYI = Logic_deps.NYI
+  let not_yet_implemented = Logic_deps.not_yet_implemented
 end
-
-exception Prune
-
-let to_result_from_pred p =
-  let visitor = object (_self)
-    inherit Visitor.frama_c_inplace
-
-    method! vterm_lhost t =
-      match t with
-      | TResult _ -> raise Prune
-      | _ -> DoChildren
-
-  end
-  in
-  (try
-     ignore(Visitor.visitFramacPredicate visitor p);
-     false
-   with Prune ->
-     true)
-
-
-let () =
-  Db.Properties.Interp.To_zone.code_annot_filter := To_zone.code_annot_filter;
-  Db.Properties.Interp.To_zone.mk_ctx_func_contrat :=
-    To_zone.mk_ctx_func_contrat;
-  Db.Properties.Interp.To_zone.mk_ctx_stmt_contrat :=
-    To_zone.mk_ctx_stmt_contrat;
-  Db.Properties.Interp.To_zone.mk_ctx_stmt_annot := To_zone.mk_ctx_stmt_annot;
-
-  Db.Properties.Interp.To_zone.from_term := To_zone.from_term;
-  Db.Properties.Interp.To_zone.from_terms := To_zone.from_terms;
-  Db.Properties.Interp.To_zone.from_pred := To_zone.from_pred;
-  Db.Properties.Interp.To_zone.from_preds := To_zone.from_preds;
-  Db.Properties.Interp.To_zone.from_stmt_annot := To_zone.from_stmt_annot;
-  Db.Properties.Interp.To_zone.from_stmt_annots := To_zone.from_stmt_annots;
-  Db.Properties.Interp.To_zone.from_func_annots := To_zone.from_func_annots;
-
-  Db.Properties.Interp.to_result_from_pred := to_result_from_pred;
diff --git a/src/kernel_services/analysis/logic_interp.mli b/src/kernel_services/analysis/logic_interp.mli
index 739821d75e5c0bfaaeec7ed8ec41f1f396323ec8..4e8a7e6d648fc250f0e197a1388088b9045c17fa 100644
--- a/src/kernel_services/analysis/logic_interp.mli
+++ b/src/kernel_services/analysis/logic_interp.mli
@@ -20,12 +20,14 @@
 (*                                                                        *)
 (**************************************************************************)
 
+(* This module exists for compatibility only and will be removed in future
+   versions *)
+
 open Cil_types
 
 module To_zone : sig
   exception NYI of string
   val not_yet_implemented : string ref
-  val compute_term_deps: (stmt -> term -> Locations.Zone.t option) ref
 end
 
 exception [@alert deprecated "Use directly Logic_parse_string.Error istead."]
diff --git a/src/plugins/eva/legacy/logic_inout.ml b/src/plugins/eva/legacy/logic_inout.ml
index 7ae89d1e63344cad129208aff8220dfd5ef1e1da..34ed60bad552a00cac80bb75364e007797e383dc 100644
--- a/src/plugins/eva/legacy/logic_inout.ml
+++ b/src/plugins/eva/legacy/logic_inout.ml
@@ -43,7 +43,7 @@ let compute_term_deps stmt t =
   let state = Results.(before stmt |> get_cvalue_model) in
   term_deps state t
 
-let () = Logic_interp.To_zone.compute_term_deps := compute_term_deps
+let () = Logic_deps.compute_term_deps := compute_term_deps
 
 let valid_behaviors kf state =
   let funspec = Annotations.funspec kf in