(* subtract is purely functional version of domeqO/domeqX *)
Section Subtract.
Variables (K : ordType) (T : Type) (U : union_map_class K T).
Implicit Types (i : ctx U) (ts : seq (term T)).
(* We need a subterm lemma that returns the uncancelled stuff from *)
(* both sides. xs accumulates uncancelled part of ts1, starting as nil *)
Fixpoint subtract ts1 ts2 xs :=
match ts1 with
Pts n v :: tsx1 =>
if has (key n) ts2 then subtract tsx1 (kfree n ts2) xs
else subtract tsx1 ts2 (Pts n v :: xs)
| Var n :: tsx1 =>
if has (var n) ts2 then subtract tsx1 (vfree n ts2) xs
else subtract tsx1 ts2 (Var T n :: xs)
| [::] => (xs, ts2)
end.

(* Specifications: *)
(* below, the existentially quantified u is the cancelled part *)
Lemma subtract_sound i ts1 ts2 rs1 rs2 xs :
all (wf i) ts1 -> all (wf i) ts2 ->
subtract ts1 ts2 xs = (rs1, rs2) ->
exists u, dom_eq (interp i ts1 \+ interp i xs) (interp i rs1 \+ u) /\
dom_eq (interp i ts2) (interp i rs2 \+ u).