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.