Section BOOLEAN_EQUALITY.
Variable A: Type.
Variable beqA: A -> A -> bool.
Fixpoint bempty (m: t A) : bool :=
match m with
| Leaf => true
| Node l None r => bempty l && bempty r
| Node l (Some _) r => false
end.
Fixpoint beq (m1 m2: t A) {struct m1} : bool :=
match m1, m2 with
| Leaf, _ => bempty m2
| _, Leaf => bempty m1
| Node l1 o1 r1, Node l2 o2 r2 =>
match o1, o2 with
| None, None => true
| Some y1, Some y2 => beqA y1 y2
| _, _ => false
end
&& beq l1 l2 && beq r1 r2
end.
End BOOLEAN_EQUALITY.
Fixpoint prev_append (i j: positive) {struct i} : positive :=
match i with
| xH => j
| xI i' => prev_append i' (xI j)
| xO i' => prev_append i' (xO j)
end.
Definition prev (i: positive) : positive :=
prev_append i xH.
Proof (prev_append_prev i xH).
Fixpoint xmap (A B : Type) (f : positive -> A -> B) (m : t A) (i : positive)
{struct m} : t B :=
match m with
| Leaf => Leaf
| Node l o r => Node (xmap f l (xO i))
(match o with None => None | Some x => Some (f (prev i) x) end)
(xmap f r (xI i))
end.
Definition map (A B : Type) (f : positive -> A -> B) m := xmap f m xH.
Fixpoint map1 (A B: Type) (f: A -> B) (m: t A) {struct m} : t B :=
match m with
| Leaf => Leaf
| Node l o r => Node (map1 f l) (option_map f o) (map1 f r)
end.
Definition Node' (A: Type) (l: t A) (x: option A) (r: t A): t A :=
match l, x, r with
| Leaf, None, Leaf => Leaf
| _, _, _ => Node l x r
end.
Fixpoint filter1 (A: Type) (pred: A -> bool) (m: t A) {struct m} : t A :=
match m with
| Leaf => Leaf
| Node l o r =>
let o' := match o with None => None | Some x => if pred x then o else None end in
Node' (filter1 pred l) o' (filter1 pred r)
end.

Theorem gfilter1:
forall (A: Type) (pred: A -> bool) (i: elt) (m: t A),
get i (filter1 pred m) =
match get i m with None => None | Some x => if pred x then Some x else None end.