intro m; induction m; simpl; intros.
destruct v; simpl in H; discriminate.
destruct v; destruct o; simpl in H |- *.
rewrite map_fold_index_lift_z.
rewrite Hassoc.
destruct (IHm2 (fun x => g (xI x)) z v x) as [l' [r' ?]]; intuition.
rewrite <- Hassoc.
exists (c (c (map_fold_index' A B f c u (fun x => g (xO x)) m1) (f (g xH) a)) l').
exists r'.
rewrite H0.
rewrite <- Hassoc.
rewrite <- Hassoc.
auto.
rewrite map_fold_index_lift_z.
destruct (IHm2 (fun x => g (xI x)) z v x) as [l' [r' ?]]; intuition.
exists (c (map_fold_index' A B f c u (fun x => g (xO x)) m1) l').
exists r'.
rewrite H0.
rewrite <- Hassoc.
auto.
rewrite map_fold_index_lift_z.
destruct (IHm1 (fun x => g (xO x)) u v x) as [l' [r' ?]]; intuition.
exists l'.
rewrite H0.
rewrite <- Hassoc.
rewrite <- Hassoc.
exists (c r' (c (f (g xH) a) (map_fold_index' A B f c z (fun x => g (xI x)) m2))).
auto.
rewrite map_fold_index_lift_z.
destruct (IHm1 (fun x => g (xO x)) u v x) as [l' [r' ?]]; intuition.
exists l'.
rewrite H0.
rewrite <- Hassoc.
rewrite <- Hassoc.
exists (c r' (map_fold_index' A B f c z (fun x => g (xI x)) m2)).
auto.
replace a with x; [ | congruence ].
rewrite map_fold_index_lift_z.
exists (map_fold_index' A B f c u (fun x => g (xO x)) m1).
exists (map_fold_index' A B f c z (fun x => g (xI x)) m2).
auto.
discriminate.
Qed.

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).