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.
intro m1; induction m1; intro m2; destruct m2; simpl; intuition.
rewrite IHm1_1.
rewrite IHm1_2.
auto.
Qed.

Lemma map_forall2_correct:
forall m1 m2 i x,
map_forall2 m1 m2 = true ->
m1#i = Some x -> pred x m2#i = true.