Section Dom.
Variables A B : Type.
Fixpoint MapDomRestrTo (m:Map A) : Map B -> Map A :=
match m with
| M0 => fun _:Map B => M0 A
| M1 a y =>
fun m':Map B => match MapGet B m' a with
| None => M0 A
| _ => m
end
| M2 m1 m2 =>
fun m':Map B =>
match m' with
| M0 => M0 A
| M1 a' y' =>
match MapGet A m a' with
| None => M0 A
| Some y => M1 A a' y
end
| M2 m'1 m'2 =>
makeM2 A (MapDomRestrTo m1 m'1) (MapDomRestrTo m2 m'2)
end
end.
Fixpoint MapDomRestrBy (m:Map A) : Map B -> Map A :=
match m with
| M0 => fun _:Map B => M0 A
| M1 a y =>
fun m':Map B => match MapGet B m' a with
| None => m
| _ => M0 A
end
| M2 m1 m2 =>
fun m':Map B =>
match m' with
| M0 => m
| M1 a' y' => MapRemove A m a'
| M2 m'1 m'2 =>
makeM2 A (MapDomRestrBy m1 m'1) (MapDomRestrBy m2 m'2)
end
end.

Lemma MapDomRestrBy_semantics :
forall (m:Map A) (m':Map B),
eqm A (MapGet A (MapDomRestrBy m m'))
(fun a0:ad =>
match MapGet B m' a0 with
| None => MapGet A m a0
| _ => None
end).