let rec data_has_var xs = function
  | D1null -> false
  | D1base d | D1indir d -> data_has_var xs d
  | D1addr _ -> false
  | D1var (_,x) -> List.exists (Fol.Var.equal x) xs
  | D1depl(d,e) | D1proj(d,e) -> data_has_var xs d || path_has_var xs e
  | D1shift(d,t) | D1muIrange(d,t) -> 
      data_has_var xs d || term_has_var xs t
  | D1muI(d,None,t) ->
      data_has_var xs d || term_opt_has_var xs t
  | D1muI(d,Some i,t) -> 
      data_has_var xs d || term_has_var xs i || term_opt_has_var xs t
  | D1mu(d,e,t) -> 
      data_has_var xs d || path_has_var xs e || term_opt_has_var xs t
  | D1muRange(d,t) -> data_has_var xs d || term_has_var xs t

and path_has_var xs = function
  | Pfield _ -> false
  | Pidx t -> term_has_var xs t

and term_has_var xs =
  Fol.e_has_var data_has_var xs

and term_opt_has_var xs t = match t with None -> false
      | Some t -> term_has_var xs t