let get_lval_assertion (lv : lval) =
  (* one has to build assertions for:
     - pointer dereferencing: only if lval host is of the form (Mem expr)
     - array access: several may occur, one for each offset of the form (Index
     _,_) 
  *)

  (* so we :
     A. compute all assertions for array accesses by
       1. transforming the offset recursive structure
          in an ad hoc list (offsets_as_list)
       2. keeping offsets which are array accesses (all_array_offsets)
       3. rebuilding Cil offsets from these (final_array_offsets)
       4. building lvals and terms from these
          (final_array_lvals, final_array_terms)
     B. add an assertion for a potential pointer dereferencing
        (lval lv's host is a Mem expr), unless it is a function pointer
        dereferencing (in which case we emit a warning))
  *)

  let (lhost, init_offset) = lv in
  let rec fetch_all_offsets acc off =
    match off with
    | NoOffset -> acc
    | Field (fi, next_off) -> fetch_all_offsets ((MyField fi) :: acc) next_off
    | Index (e, next_off) -> fetch_all_offsets ((MyIndex e) :: acc) next_off
  in
  let offsets_as_list = List.rev (fetch_all_offsets [] init_offset) in
  let all_array_offsets, _ =
    List.fold_left
      (fun (acc_off,acc_prefix) moff ->
        match moff with
        | MyIndex _ ->
          ((moff :: acc_prefix) :: acc_off, moff :: acc_prefix)
        | _ -> (acc_off, moff :: acc_prefix)) 
      ([],[]) 
      offsets_as_list
  in
  let rec build_offset_from_list off_list =
    match off_list with
      | [] -> NoOffset
      | (MyField fi) :: tl -> Field (fi, build_offset_from_list tl)
      | (MyIndex e) :: tl -> Index (e, build_offset_from_list tl)
  in
  let final_array_offsets =
    List.map
      (fun off_list ->
         build_offset_from_list (List.rev off_list)
      ) all_array_offsets
(*
  in let () =
    debug "Final list of offsets is\n" ;
    List.iter (fun off  -> debug "%a\n" d_offset off) final_array_offsets
*)

  in
  let final_array_lvals = 
    List.map (fun off -> (lhost,off)) final_array_offsets in
  let final_array_terms =
    List.fold_left
      (fun acc lv ->
        if isFunctionType (typeOfLval lv) then begin
          rte_warn fmt_warn_no_valid_fptr_deref
            Cil.d_lval lv;
          acc
        end else
          translate_C_expr_to_term ~cast:false
             (mkAddrOf ~loc:(CurrentLoc.get())lv)
          :: acc)
        []
        final_array_lvals
  in 
  let final_terms =
    match lv with
    | Mem exp, _ ->
      if isFunctionType (typeOfLval lv) then begin
        rte_warn fmt_warn_no_valid_fptr_deref
          Cil.d_lval lv;
        final_array_terms
      end else
        translate_C_expr_to_term ~cast:false exp :: final_array_terms
    | Var _, _ -> final_array_terms
  in
  List.map
    (fun t -> (Logic_const.pvalid t, None)) 
    final_terms