Fixpoint xfold (A B: Type) (f: B -> positive -> A -> B)
(i: positive) (m: t A) (v: B) {struct m} : B :=
match m with
| Leaf => v
| Node l None r =>
let v1 := xfold f (xO i) l v in
xfold f (xI i) r v1
| Node l (Some x) r =>
let v1 := xfold f (xO i) l v in
let v2 := f v1 (prev i) x in
xfold f (xI i) r v2
end.
Definition fold (A B : Type) (f: B -> positive -> A -> B) (m: t A) (v: B) :=
xfold f xH m v.

(* Specifications: *)
Lemma xfold_xelements:
forall (A B: Type) (f: B -> positive -> A -> B) m i v l,
List.fold_left (fun a p => f a (fst p) (snd p)) l (xfold f i m v) =
List.fold_left (fun a p => f a (fst p) (snd p)) (xelements m i l) v.
Theorem fold_spec:
forall (A B: Type) (f: B -> positive -> A -> B) (v: B) (m: t A),
fold f m v =
List.fold_left (fun a p => f a (fst p) (snd p)) (elements m) v.
Lemma xfold_xelements:
forall (A B: Type) (f: B -> positive -> A -> B) m i v l,
List.fold_left (fun a p => f a (fst p) (snd p)) l (xfold f i m v) =
List.fold_left (fun a p => f a (fst p) (snd p)) (xelements m i l) v.
Theorem fold_spec:
forall (A B: Type) (f: B -> positive -> A -> B) (v: B) (m: t A),
fold f m v =
List.fold_left (fun a p => f a (fst p) (snd p)) (elements m) v.