(** [MapInter], [MapRngRestrTo], [MapRngRestrBy], [MapInverse] 
      not implemented: need a decidable equality on [A]. *)

  Fixpoint MapDelta (m:Map) : Map -> Map :=
    match m with
    | M0 => fun m':Map => m'
    | M1 a y =>
        fun m':Map =>
          match MapGet m' a with
          | None => MapPut m' a y
          | _ => MapRemove m' a
          end
    | M2 m1 m2 =>
        fun m':Map =>
          match m' with
          | M0 => m
          | M1 a' y' =>
              match MapGet m a' with
              | None => MapPut m a' y'
              | _ => MapRemove m a'
              end
          | M2 m'1 m'2 => makeM2 (MapDelta m1 m'1) (MapDelta m2 m'2)
          end
    end.

(* Specifications: *)
Lemma MapDelta_semantics_comm : forall m m':Map, eqm (MapGet (MapDelta m m')) (MapGet (MapDelta m' m)).
Lemma MapDelta_semantics_1_1 : forall (a:ad) (y:A) (m':Map) (a0:ad), MapGet (M1 a y) a0 = None -> MapGet m' a0 = None -> MapGet (MapDelta (M1 a y) m') a0 = None.
Lemma MapDelta_semantics_1 : forall (m m':Map) (a:ad), MapGet m a = None -> MapGet m' a = None -> MapGet (MapDelta m m') a = None.
Lemma MapDelta_semantics_2_1 : forall (a:ad) (y:A) (m':Map) (a0:ad) (y0:A), MapGet (M1 a y) a0 = None -> MapGet m' a0 = Some y0 -> MapGet (MapDelta (M1 a y) m') a0 = Some y0.
Lemma MapDelta_semantics_2_2 : forall (a:ad) (y:A) (m':Map) (a0:ad) (y0:A), MapGet (M1 a y) a0 = Some y0 -> MapGet m' a0 = None -> MapGet (MapDelta (M1 a y) m') a0 = Some y0.
Lemma MapDelta_semantics_2 : forall (m m':Map) (a:ad) (y:A), MapGet m a = None -> MapGet m' a = Some y -> MapGet (MapDelta m m') a = Some y.
Lemma MapDelta_semantics_3_1 : forall (a0:ad) (y0:A) (m':Map) (a:ad) (y y':A), MapGet (M1 a0 y0) a = Some y -> MapGet m' a = Some y' -> MapGet (MapDelta (M1 a0 y0) m') a = None.
Lemma MapDelta_semantics_3 : forall (m m':Map) (a:ad) (y y':A), MapGet m a = Some y -> MapGet m' a = Some y' -> MapGet (MapDelta m m') a = None.
Lemma MapDelta_semantics : forall m m':Map, eqm (MapGet (MapDelta m m')) (fun a0:ad => match MapGet m a0, MapGet m' a0 with | None, Some y' => Some y' | Some y, None => Some y | _, _ => None end).