Definition map_fold_index'
   (A B:Type)
   (f:positive -> A -> B)
   (c:B -> B -> B) :
   B -> (positive -> positive) -> (map A) -> B :=

   fix fold (z:B) (g:positive -> positive) (M:map A) { struct M } : B :=

  match M with
  | Leaf => z
  | Node l None r =>
     fold (fold z (fun x => g (xI x)) r) (fun x => g (xO x)) l
  | Node l (Some x) r =>
     fold (c (f (g xH) x) (fold z (fun x => g (xI x)) r)) (fun x => g (xO x)) l
  end.Definition map_fold_index
   (A B:Type)
   (f:positive -> A -> B)
   (c:B -> B -> B)
   (z:B) (M:map A) : B :=
  map_fold_index' A B f c z (fun x => x) M.

(* Specifications: *)
Lemma map_fold_index_lift_z : forall (m:map A) (g:positive -> positive) (z:B), map_fold_index' A B f c z g m = c (map_fold_index' A B f c u g m) z.
Lemma map_fold_index_lookup' : forall (m:map A) (g:positive -> positive) (z:B) v x, m#v = Some x -> exists l, exists r, map_fold_index' A B f c z g m = c l (c (f (g v) x) r).
Lemma map_fold_index_lookup : forall (m:map A) (z:B) v x, m#v = Some x -> exists l, exists r, map_fold_index A B f c z m = c l (c (f v x) r).
Lemma map_fold_index_lift_z : forall (m:map A) (g:positive -> positive) (z:B), map_fold_index' A B f c z g m = c (map_fold_index' A B f c u g m) z.
Lemma map_fold_index_lookup' : forall (m:map A) (g:positive -> positive) (z:B) v x, m#v = Some x -> exists l, exists r, map_fold_index' A B f c z g m = c l (c (f (g v) x) r).
Lemma map_fold_index_lookup : forall (m:map A) (z:B) v x, m#v = Some x -> exists l, exists r, map_fold_index A B f c z m = c l (c (f v x) r).
Lemma map_fold_index_lift_z : forall (m:map A) (g:positive -> positive) (z:B), map_fold_index' A B f c z g m = c (map_fold_index' A B f c u g m) z.
Lemma map_fold_index_lookup' : forall (m:map A) (g:positive -> positive) (z:B) v x, m#v = Some x -> exists l, exists r, map_fold_index' A B f c z g m = c l (c (f (g v) x) r).
Lemma map_fold_index_lookup : forall (m:map A) (z:B) v x, m#v = Some x -> exists l, exists r, map_fold_index A B f c z m = c l (c (f v x) r).