Next Obligation.
exists (fun _ => empty_map); auto; repeat intro.
simpl.
destruct (t k); auto.
Defined.
Next Obligation.
constructor.
- intros.
extensionality k.
specialize (H k); specialize (H0 k).
destruct (x k), (y k); try congruence; contradiction.
- intros.
rewrite map_disj_join_spec in *.
destruct H, H0; subst.
rewrite map_add_assoc.
eexists; rewrite !map_disj_join_spec; repeat split.
+ eapply disjoint_incl; eauto.
rewrite map_add_comm by (apply disjoint_compatible; auto); apply map_incl_add.
+ apply disjoint_add; auto.
eapply disjoint_incl; eauto.
apply map_incl_add.
- intros ???; rewrite !map_disj_join_spec; intros []; subst.
split; [symmetry | apply map_add_comm, disjoint_compatible]; auto.
- intros.
extensionality k; specialize (H k); specialize (H0 k).
destruct (a k), (b k); auto.
+ destruct (a' k); [contradiction | auto].
+ destruct (a' k); [contradiction | auto].
+ destruct (b' k); [contradiction | auto].
Defined.
Next Obligation.
auto.
Defined.

(* Specifications: *)
Lemma disj_join_sub : forall m1 m2, map_incl m1 m2 -> exists m3, join m1 m3 m2.
Definition all_disjoint (l : list (A -> option B)) := forall i j, 0 <= i < Zlength l -> 0 <= j < Zlength l ->
i <> j -> disjoint (Znth i l) (Znth j l).
Lemma all_disjoint_compatible : forall l, all_disjoint l -> all_compatible l.
Lemma all_disjoint_nil : all_disjoint [].
Lemma all_disjoint_cons : forall (m : A -> option B) l, all_disjoint (m :: l) <-> disjoint m (maps_add l) /\ all_disjoint l.
Lemma all_disjoint_rev1 : forall l, all_disjoint l -> all_disjoint (rev l).
Lemma all_disjoint_rev : forall l, all_disjoint l <-> all_disjoint (rev l).
Lemma maps_add_rev : forall l, all_compatible l -> maps_add (rev l) = maps_add l.
Lemma all_disjoint_snoc : forall m l, all_disjoint (l ++ [m]) <-> disjoint m (maps_add l) /\ all_disjoint l.
Lemma empty_map_disjoint : forall m, disjoint empty_map m.
Definition map_sub (m : A -> option B) k := fun x => if eq_dec x k then None else m x.
Lemma map_upd_sub : forall m (k : A) (v : B), m k = Some v -> map_upd (map_sub m k) k v = m.
Lemma map_sub_upd : forall m (k : A) (v : B), m k = None -> map_sub (map_upd m k v) k = m.
Lemma disjoint_sub : forall (m1 m2 : A -> option B) k, disjoint m1 m2 ->
disjoint (map_sub m1 k) m2.