Fixpoint MapPut (m:Map) : ad -> A -> Map :=
match m with
| M0 => M1
| M1 a y =>
fun (a':ad) (y':A) =>
match Nxor a a' with
| N0 => M1 a' y'
| Npos p => MapPut1 a y a' y' p
end
| M2 m1 m2 =>
fun (a:ad) (y:A) =>
match a with
| N0 => M2 (MapPut m1 N0 y) m2
| Npos xH => M2 m1 (MapPut m2 N0 y)
| Npos (xO p) => M2 (MapPut m1 (Npos p) y) m2
| Npos (xI p) => M2 m1 (MapPut m2 (Npos p) y)
end
end.

(* Specifications: *)
Lemma MapPut_semantics_1 :
forall (a:ad) (y:A) (a0:ad),
MapGet (MapPut M0 a y) a0 = MapGet (M1 a y) a0.
Lemma MapPut_semantics_2_1 :
forall (a:ad) (y y':A) (a0:ad),
MapGet (MapPut (M1 a y) a y') a0 =
(if Neqb a a0 then Some y' else None).
Lemma MapPut_semantics_2_2 :
forall (a a':ad) (y y':A) (a0 a'':ad),
Nxor a a' = a'' ->
MapGet (MapPut (M1 a y) a' y') a0 =
(if Neqb a' a0 then Some y' else if Neqb a a0 then Some y else None).
Lemma MapPut_semantics_2 :
forall (a a':ad) (y y':A) (a0:ad),
MapGet (MapPut (M1 a y) a' y') a0 =
(if Neqb a' a0 then Some y' else if Neqb a a0 then Some y else None).
Lemma MapPut_semantics_3_1 :
forall (m m':Map) (a:ad) (y:A),
MapPut (M2 m m') a y =
(if Nbit0 a
then M2 m (MapPut m' (Ndiv2 a) y)
else M2 (MapPut m (Ndiv2 a) y) m').
Lemma MapPut_semantics :
forall (m:Map) (a:ad) (y:A),
eqm (MapGet (MapPut m a y))
(fun a':ad => if Neqb a a' then Some y else MapGet m a').