let rec eq_data l1 l2 = match l1, l2 with
| D1null, D1null -> true
| D1base l1, D1base l2 -> eq_data l1 l2
| D1addr (v1,_), D1addr (v2,_) -> v1.vid = v2.vid
| D1var (_,v1), D1var (_,v2) -> Fol.Var.equal v1 v2
| D1indir (l1), D1indir (l2) -> eq_data l1 l2
| D1depl (l1, ch1), D1depl (l2, ch2)
| D1proj (l1, ch1), D1proj (l2, ch2)
-> eq_epath ch1 ch2 && eq_data l1 l2
| D1shift (l1, t1), D1shift (l2, t2) ->
eq_data l1 l2 && eq_term t1 t2
| D1mu (l1, ch1, t1), D1mu (l2, ch2, t2) ->
eq_data l1 l2 && eq_epath ch1 ch2 && eq_term_opt t1 t2
| D1muRange (l1, ch1), D1muRange (l2, ch2) ->
eq_data l1 l2 && eq_term ch1 ch2
| D1muI (l1, None, t1), D1muI (l2, None, t2) ->
eq_data l1 l2 && eq_term_opt t1 t2
| D1muI (l1, Some i1, t1), D1muI (l2, Some i2, t2) ->
eq_data l1 l2 && eq_term i1 i2 && eq_term_opt t1 t2
| D1muIrange (l1, i1), D1muIrange (l2, i2) ->
eq_data l1 l2 && eq_term i1 i2
| _ -> false
and eq_epath e1 e2 = match e1, e2 with
| Pfield f1, Pfield f2 ->
f1.fcomp.ckey = f2.fcomp.ckey && f1.fname = f2.fname
| Pidx i1, Pidx i2 -> eq_term i1 i2
| _ -> false
and eq_term_opt t1 t2 = match t1, t2 with
| None, None -> true
| Some t1, Some t2 -> eq_term t1 t2
| _, _ -> false
and eq_term t1 t2 = Fol.eq_terms eq_data t1 t2