let make_tau tr = let memo = ref [] in (fun x op y -> try match find_assign memo tr x, find_assign memo tr y with | Single tx, Single ty -> Atom.Comp (tx, op, ty) | Single tx, Branch ls -> List.fold_right (fun (ci, ti) f -> Atom.Ite(ci, Atom.Comp(tx, op, ti), f)) ls Atom.True | Branch ls, Single tx -> List.fold_right (fun (ci, ti) f -> Atom.Ite(ci, Atom.Comp(ti, op, tx), f)) ls Atom.True | Branch ls1, Branch ls2 -> List.fold_right (fun (ci, ti) f -> List.fold_right (fun (cj, tj) f -> Atom.Ite(SAtom.union ci cj, Atom.Comp(ti, op, tj), f)) ls2 f) ls1 Atom.True with Remove_lit_var _ -> Atom.True), (fun () -> memo := [])