Section FORALL2.
Variables A B: Type.
Variable pred: A -> option B -> bool.
Definition pred_opt (x: option A) (y: option B) :=
match x with
| None => true
| Some z => pred z y
end.
Fixpoint map_forall2 (m1: map A) (m2: map B) {struct m1}: bool :=
match m1, m2 with
| Leaf, _ => true
| Node l1 o1 r1, Leaf =>
map_forall2 l1 (Leaf B) && pred_opt o1 None && map_forall2 r1 (Leaf B)
| Node l1 o1 r1, Node l2 o2 r2 =>
map_forall2 l1 l2 && pred_opt o1 o2 && map_forall2 r1 r2
end.
Fixpoint map_forall2' (m1: map A) (m2: map B) {struct m2}: bool :=
match m1, m2 with
| Leaf, _ => true
| Node l1 o1 r1, Leaf =>
map_forall2 l1 (Leaf B) && pred_opt o1 None && map_forall2 r1 (Leaf B)
| Node l1 o1 r1, Node l2 o2 r2 =>
map_forall2' l1 l2 && pred_opt o1 o2 && map_forall2' r1 r2
end.

Lemma map_forall2_eq : forall (m1:map A) (m2:map B),
map_forall2 m1 m2 = map_forall2' m1 m2.