Section Map2_opt.
Variable elt elt' elt'' : Type.
Variable f0 : key -> option elt -> option elt' -> option elt''.
Variable f : key -> elt -> option elt' -> option elt''.
Variable mapl : t elt -> t elt''.
Variable mapr : t elt' -> t elt''.
Hypothesis f0_f : forall x d o, f x d o = f0 x (Some d) o.
Hypothesis mapl_bst : forall m, bst m -> bst (mapl m).
Hypothesis mapr_bst : forall m', bst m' -> bst (mapr m').
Hypothesis mapl_f0 : forall x m, bst m ->
find x (mapl m) =
match find x m with Some d => f0 x (Some d) None | None => None end.
Hypothesis mapr_f0 : forall x m', bst m' ->
find x (mapr m') =
match find x m' with Some d' => f0 x None (Some d') | None => None end.
Hypothesis f0_compat : forall x x' o o', X.eq x x' -> f0 x o o' = f0 x' o o'.
Notation map2_opt := (map2_opt f mapl mapr).
Hint Resolve map2_opt_bst : core.
Ltac map2_aux :=
match goal with
| H : In ?x _ \/ In ?x ?m,
H' : find ?x ?m = find ?x ?m', B:bst ?m, B':bst ?m' |- _ =>
destruct H; [ intuition_in; order |
rewrite <-(find_in_equiv B B' H'); auto ]
end.
Ltac nonify t :=
match t with (find ?y (map2_opt ?m ?m')) =>
replace t with (@None elt'');
[ | symmetry; rewrite not_find_iff; auto; intro;
destruct (@map2_opt_2 m m' y); auto; order ]
end.

Lemma map2_opt_1 : forall m m' y, bst m -> bst m' ->
In y m \/ In y m' ->
find y (map2_opt m m') = f0 y (find y m) (find y m').