let fol p =
  let rec do_data d = match d with
    | E2addr v -> Fol.Tvar (WpFol.addr_lvar ~create:true v)
    | E2depl (o, WpFol.Pfield x) -> WpFol.fol_field_shift (fol_exp o) x
    | E2depl (o, WpFol.Pidx x) -> Why_ops.index_shift (fol_exp o) (fol_exp x)
    | E2proj (o, WpFol.Pfield x) ->  WpFol.fol_field_access (fol_exp o) x
    | E2proj (o, WpFol.Pidx x) -> 
          Why_ops.array_access (fol_exp o) (fol_exp x)
    | E2shift (o, x) -> Why_ops.shift_pointer (fol_exp o) (fol_exp x)
    | E2load (m, p) -> Why_ops.M2.mem_access (fol_exp m) (fol_exp p)
    | E2store (m, p, v) ->
        Why_ops.M2.mem_update (fol_exp m) (fol_exp p) (fol_exp v)
  and fol_exp e = Fol.translate_data_in_term do_data e
  in
    Fol.translate_data_in_pred do_data p