Fixpoint domain_equal (A B : Set) (m0 : Map A) (m1 : Map B) {struct m1} :
 Prop :=
  match m0, m1 with
  | M0, M0 => True
  | M0, M1 _ _ => False
  | M0, M2 _ _ => False
  | M1 _ _, M0 => False
  | M1 a _, M1 b _ => a = b
  | M1 _ _, M2 _ _ => False
  | M2 _ _, M0 => False
  | M2 _ _, M1 _ _ => False
  | M2 a b, M2 c d => domain_equal A B a c /\ domain_equal A B b d
  end.

(* Specifications: *)
Lemma domain_equal_mapget : forall (A B : Set) (m0 : Map A) (m1 : Map B) (a : ad) (x : A), domain_equal A B m0 m1 -> MapGet A m0 a = Some x -> exists y : B, MapGet B m1 a = Some y.
Lemma domain_equal_reflexive : forall (A : Set) (m : Map A), domain_equal A A m m.
Lemma domain_equal_symmetric : forall (A B : Set) (m0 : Map A) (m1 : Map B), domain_equal A B m0 m1 -> domain_equal B A m1 m0.
Lemma domain_equal_transitive : forall (A0 A1 A2 : Set) (m0 : Map A0) (m1 : Map A1) (m2 : Map A2), domain_equal A0 A1 m0 m1 -> domain_equal A1 A2 m1 m2 -> domain_equal A0 A2 m0 m2.
Lemma map_sum : forall (A : Set) (m : Map A), m = M0 A \/ (exists a : ad, (exists x : A, m = M1 A a x)) \/ (exists x : Map A, (exists y : Map A, m = M2 A x y)).