Section Elt3.
Variable elt elt' elt'' : Type.
Notation oee' := (option elt * option elt')%type.
Definition combine_l (m:t elt)(m':t elt') : t oee' :=
mapi (fun k e => (Some e, find k m')) m.
Definition combine_r (m:t elt)(m':t elt') : t oee' :=
mapi (fun k e' => (find k m, Some e')) m'.
Definition fold_right_pair (A B C:Type)(f:A->B->C->C) :=
List.fold_right (fun p => f (fst p) (snd p)).
Definition combine (m:t elt)(m':t elt') : t oee' :=
let l := combine_l m m' in
let r := combine_r m m' in
fold_right_pair (add (elt:=oee')) r l.
Hint Resolve fold_right_pair_NoDup : core.
Definition at_least_left (o:option elt)(o':option elt') :=
match o with
| None => None
| _  => Some (o,o')
end.
Definition at_least_right (o:option elt)(o':option elt') :=
match o' with
| None => None
| _  => Some (o,o')
end.
Definition at_least_one (o:option elt)(o':option elt') :=
match o, o' with
| None, None => None
| _, _  => Some (o,o')
end.

Lemma combine_1 :
forall m (Hm:NoDupA (@eqk elt) m) m' (Hm':NoDupA (@eqk elt') m')(x:key),
find x (combine m m') = at_least_one (find x m) (find x m').