let rec do_exp_in_data do_exp d =
  let do_path ch = do_path do_exp ch in
  let do_exp_opt e = match e with None -> None 
    | Some e -> Some (do_exp e)
  in
  let do_data d = data_of_term (do_exp_in_data do_exp d) in
    match d with
      | D1null | D1addr _ -> Fol.e_data d
      | D1base p ->  Fol.e_data (D1base (do_data p))
      | D1var (_,v) ->
          let e = Fol.e_var v in
          let e' = do_exp e in
            if eq_term e e' then Fol.e_data d else e'
      | D1indir (e) -> indir_here (do_data e)
      | D1proj (e, ch) -> proj (do_data e) (do_path ch)
      | D1depl (e, Pfield f) -> Fol.e_data (shift_field (do_data e) f)
      | D1depl (e, Pidx i) -> Fol.e_data (shift_index (do_data e) (do_exp i))
      | D1shift (e, i) -> Fol.e_data (shift_pointer (do_data e)(do_exp i))
      | D1mu (e, ch, x) -> 
          Fol.e_data (D1mu (do_data e, do_path ch, do_exp_opt x))
      | D1muRange (e, x) -> Fol.e_data (D1muRange (do_data e, do_exp x))
      | D1muI (e, None, x) -> 
          Fol.e_data (D1muI (do_data e, None, do_exp_opt x))
      | D1muI (e, Some i, x) -> 
          Fol.e_data (D1muI (do_data e, Some (do_exp i), do_exp_opt x))
      | D1muIrange (e, x) -> Fol.e_data (D1muIrange  (do_data e, do_exp x))