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').