Fixpoint MapDomRestrTo_DomBy (m : Map A) : Map B -> Map A * Map unit :=
match m with
| M0 => fun _ : Map B => (M0 A, M0 unit)
| M1 a y =>
fun m' : Map B =>
match MapGet B m' a with
| None => (M0 A, M1 unit a tt)
| _ => (m, M0 unit)
end
| M2 m1 m2 =>
fun m' : Map B =>
match m' with
| M0 => (M0 A, MapDom A m)
| M1 a' y' =>
(match MapGet A m a' with
| None => M0 A
| Some y => M1 A a' y
end, MapDom A (MapRemove A m a'))
| M2 m'1 m'2 =>
match MapDomRestrTo_DomBy m1 m'1 with
| (x1, y1) =>
match MapDomRestrTo_DomBy m2 m'2 with
| (x2, y2) => (makeM2 A x1 x2, makeM2 unit y1 y2)
end
end
end
end.

(* Specifications: *)
Lemma MapDomRestrTo_DomBy_lemma_1 :
forall (m : Map A) (m' : Map B),
fst (MapDomRestrTo_DomBy m m') = MapDomRestrTo A B m m'.
Lemma MapDomRestrTo_DomBy_lemma_2 :
forall (m : Map A) (m' : Map B),
snd (MapDomRestrTo_DomBy m m') = MapDom A (MapDomRestrBy A B m m').