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