let map f =
  let rec loop a =
    match d_interp a with
      | Some(Sym.Const(_), []) ->
          a
      | Some(Sym.Sub(n,i,j), [x]) -> 
          let x' = loop x in
            if x == x' then a else mk_sub n i j x'
      | Some(Sym.Conc(n,m), [x;y]) -> 
          let x' = loop x and y' = loop y in
            if x == x' && y == y' then a else mk_conc n m x' y'
      | Some(Sym.Bitwise(n), [x;y;z]) -> 
          let x' = loop x and y' = loop y and z' = loop z in
            if x == x' && y == y' && z == z' then a else
              mk_bitwise n x' y' z'
      | None -> 
          f a
      | Some _ -> 
          assert false
  in
  loop