(** [combine] **)
Definition Scombine {A B C : Type} (f : A -> B -> C) (g : A -> C) (h : B -> C) (m₁ : S.t A) (m₂ : S.t B) : S.t C :=
Dom.fold (fun x acc => match S.find x m₁, S.find x m₂ with
| Some v₁, Some v₂ => S.add x (f v₁ v₂) acc
| Some v, None => S.add x (g v) acc
| None, Some v => S.add x (h v) acc
| None, None => acc
end)
(Dom.union (S.fold (fun x _ acc => Dom.add x acc) m₁ Dom.empty)
(S.fold (fun x _ acc => Dom.add x acc) m₂ Dom.empty)) (S.empty C).

Theorem Scombine_spec : forall A B C (f : A -> B -> C) g h x v m₁ m₂,
S.find x (Scombine f g h m₁ m₂) = Some v <->
(exists v₁ v₂, S.find x m₁ = Some v₁ ∧ S.find x m₂ = Some v₂ ∧ v = f v₁ v₂)
∨ (exists v₁, S.find x m₁ = Some v₁ ∧ S.find x m₂ = None ∧ v = g v₁)
∨ (exists v₂, S.find x m₁ = None ∧ S.find x m₂ = Some v₂ ∧ v = h v₂).