intros m; induction m; intros;
destruct v; simpl; auto.
destruct v'; simpl; auto.
apply IHm2; congruence.
destruct v'; simpl; auto.
apply IHm1; congruence.
destruct v'; simpl; auto.
contradiction H; auto.
Qed.
End MAPS.
Notation "a # b" := (get _ a b) (at level 1).
Notation "a # b <- c" := (set _ a b c) (at level 1, b at next level).
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.

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