let compute_using_declaration kf with_formals =
  Kf_state.mark_as_called kf;
  let stateset = Eval_logic.check_fct_preconditions kf with_formals in
  (* TODO: This is a hack. Use a function that checks preconditions without
   multiplying the states instead -- or compute_using_prototype several times *)

  let active_behaviors = Eval_logic.ActiveBehaviors.create stateset kf in
  let state_with_formals = State_set.join stateset in
  let retres_vi, result_state, thing =
    compute_using_prototype kf ~active_behaviors ~state_with_formals in
  let result_state =
    Eval_logic.check_fct_postconditions ~result:retres_vi kf ~active_behaviors
      ~init_state:(State_set.singleton state_with_formals)
      ~post_state:(State_set.singleton result_state)
      Normal
  in
  let result_state = State_set.join result_state in
  let result, result_state = match retres_vi with
    | None -> None, result_state
    | Some vi ->
      if not (Cvalue.Model.is_reachable result_state) then 
        (* This test prevents the call to Model.find_base that would
           raise Not_found in this case. *)

        None, result_state
      else
        let value_state = result_state in
        let retres_base = Base.create_varinfo vi in
        (Some (Cvalue.Model.find_base retres_base value_state)) ,
        Cvalue.Model.remove_base retres_base result_state
  in
  let formals = Kernel_function.get_formals kf in
  let result_state =
    List.fold_left
      (fun acc vi ->
        Cvalue.Model.remove_base
          (Base.create_varinfo vi)
          acc)
      result_state
      formals
  in
  result, result_state, thing