Fixpoint MapPut1 (a:ad) (y:A) (a':ad) (y':A) (p:positive) {struct p} :
   Map :=
    match p with
    | xO p' =>
        let m := MapPut1 (Ndiv2 a) y (Ndiv2 a') y' p' in
        match Nbit0 a with
        | false => M2 m M0
        | true => M2 M0 m
        end
    | _ =>
        match Nbit0 a with
        | false => M2 (M1 (Ndiv2 a) y) (M1 (Ndiv2 a') y')
        | true => M2 (M1 (Ndiv2 a') y') (M1 (Ndiv2 a) y)
        end
    end.

(* Specifications: *)
Lemma MapGet_if_commute : forall (b:bool) (m m':Map) (a:ad), MapGet (if b then m else m') a = (if b then MapGet m a else MapGet m' a).
Lemma MapGet_if_same : forall (m:Map) (b:bool) (a:ad), MapGet (if b then m else m) a = MapGet m a.
Lemma MapGet_M2_bit_0_2 : forall (m m' m'':Map) (a:ad), MapGet (if Nbit0 a then M2 m m' else M2 m' m'') a = MapGet m' (Ndiv2 a).
Lemma MapPut1_semantics_1 : forall (p:positive) (a a':ad) (y y':A), Nxor a a' = Npos p -> MapGet (MapPut1 a y a' y' p) a = Some y.
Lemma MapPut1_semantics_2 : forall (p:positive) (a a':ad) (y y':A), Nxor a a' = Npos p -> MapGet (MapPut1 a y a' y' p) a' = Some y'.
Lemma MapGet_M2_both_None : forall (m m':Map) (a:ad), MapGet m (Ndiv2 a) = None -> MapGet m' (Ndiv2 a) = None -> MapGet (M2 m m') a = None.
Lemma MapPut1_semantics_3 : forall (p:positive) (a a' a0:ad) (y y':A), Nxor a a' = Npos p -> Neqb a a0 = false -> Neqb a' a0 = false -> MapGet (MapPut1 a y a' y' p) a0 = None.
Lemma MapPut1_semantics : forall (p:positive) (a a':ad) (y y':A), Nxor a a' = Npos p -> eqm (MapGet (MapPut1 a y a' y' p)) (fun a0:ad => if Neqb a a0 then Some y else if Neqb a' a0 then Some y' else None).
Lemma MapPut1_semantics' : forall (p:positive) (a a':ad) (y y':A), Nxor a a' = Npos p -> eqm (MapGet (MapPut1 a y a' y' p)) (fun a0:ad => if Neqb a' a0 then Some y' else if Neqb a a0 then Some y else None).