Section map_fold_index.
Variables A B:Type.
Variable f:positive -> A -> B.
Variable c:B -> B -> B.
Variable u:B.
Hypothesis Hassoc : forall x y z:B,
c x (c y z) = c (c x y) z.
Hypothesis Hunit_left : forall x, c u x = x.
intro m; induction m; simpl; intros.
rewrite Hunit_left; auto.
destruct o; simpl.
symmetry.
rewrite IHm1.
rewrite <- Hassoc.
rewrite <- Hassoc.
symmetry.
rewrite IHm1.
rewrite IHm2.
auto.
symmetry.
rewrite IHm1.
rewrite <- Hassoc.
symmetry.
rewrite IHm1.
rewrite IHm2.
auto.
Qed.
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).