let map f =
  let rec loop a =
    try
      (match d_interp a with
         | Sym.Const(_), [] ->
             a
         | Sym.Sub(n,i,j), [x] -> 
             let x' = loop x in
               if x == x' then a else mk_sub n i j x'
         | 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'
         | _ -> 
             assert false)
    with
        Not_found -> f a
  in
  loop