Definition map_fmap (A B:Type) (f:A->B) : map A -> map B :=
  fix map_fmap (m:map A) : map B :=
  match m with
  | Leaf => Leaf _
  | Node m1 o m2 =>
       let x := match o with
                | None => None
                | Some x => Some (f x)
                end in
       Node _ (map_fmap m1) x (map_fmap m2)
  end.

(* Specifications: *)
Lemma fmap_none : forall A B (m:map A) (f:A->B) x, m#x = None -> (map_fmap A B f m)#x = None.
Lemma fmap_none2 : forall A B (m:map A) (f:A->B) x, (map_fmap A B f m)#x = None -> m#x = None.
Lemma fmap_eqn : forall A B (m:map A) (f:A->B) x a, m#x = Some a -> (map_fmap A B f m)#x = Some (f a).
Lemma fmap_eqn2 : forall A B (m:map A) (f:A->B) x b, (map_fmap A B f m)#x = Some b -> exists a, m#x = Some a /\ f a = b.
Lemma fmap_update : forall A B (m:map A) (f:A->B) x a, (map_fmap A B f (m#x <- a)) = (map_fmap A B f m)#x <- (f a).
Lemma fmap_unset : forall A B (m:map A) (f:A->B) x, (map_fmap A B f (unset A m x)) = unset B (map_fmap A B f m) x.
Lemma fmap_none : forall A B (m:map A) (f:A->B) x, m#x = None -> (map_fmap A B f m)#x = None.
Lemma fmap_none2 : forall A B (m:map A) (f:A->B) x, (map_fmap A B f m)#x = None -> m#x = None.
Lemma fmap_eqn : forall A B (m:map A) (f:A->B) x a, m#x = Some a -> (map_fmap A B f m)#x = Some (f a).
Lemma fmap_eqn2 : forall A B (m:map A) (f:A->B) x b, (map_fmap A B f m)#x = Some b -> exists a, m#x = Some a /\ f a = b.
Lemma fmap_update : forall A B (m:map A) (f:A->B) x a, (map_fmap A B f (m#x <- a)) = (map_fmap A B f m)#x <- (f a).
Lemma fmap_unset : forall A B (m:map A) (f:A->B) x, (map_fmap A B f (unset A m x)) = unset B (map_fmap A B f m) x.
Lemma fmap_none : forall A B (m:map A) (f:A->B) x, m#x = None -> (map_fmap A B f m)#x = None.
Lemma fmap_none2 : forall A B (m:map A) (f:A->B) x, (map_fmap A B f m)#x = None -> m#x = None.
Lemma fmap_eqn : forall A B (m:map A) (f:A->B) x a, m#x = Some a -> (map_fmap A B f m)#x = Some (f a).
Lemma fmap_eqn2 : forall A B (m:map A) (f:A->B) x b, (map_fmap A B f m)#x = Some b -> exists a, m#x = Some a /\ f a = b.
Lemma fmap_update : forall A B (m:map A) (f:A->B) x a, (map_fmap A B f (m#x <- a)) = (map_fmap A B f m)#x <- (f a).
Lemma fmap_unset : forall A B (m:map A) (f:A->B) x, (map_fmap A B f (unset A m x)) = unset B (map_fmap A B f m) x.