Section Maps.
Context {A B : Type} {A_eq : EqDec A}.
Implicit Types (k : A) (v : B) (m : A -> option B).
Definition map_upd m k v k' := if eq_dec k' k then Some v else m k'.
Fixpoint map_upd_list m l :=
match l with
| [] => m
| (k, v) :: rest => map_upd_list (map_upd m k v) rest
end.
Definition map_add m1 m2 k := match m1 k with Some v' => Some v' | None => m2 k end.
Definition empty_map k : option B := None.
Global Instance Inhabitant_map : Inhabitant (A -> option B) := empty_map.
Definition singleton k v k1 := if eq_dec k1 k then Some v else None.
Definition map_incl m1 m2 := forall k v, m1 k = Some v -> m2 k = Some v.
Global Instance map_incl_refl : Reflexive map_incl.
Global Instance map_incl_antisym : Antisymmetric _ _ map_incl.
Global Instance map_incl_trans : Transitive map_incl.
Definition compatible m1 m2 := forall k v1 v2, m1 k = Some v1 -> m2 k = Some v2 -> v1 = v2.
Global Instance compatible_refl : Reflexive compatible.
Global Instance compatible_comm : Symmetric compatible.
Global Instance map_join : Join (A -> option B) :=
fun a b c => forall k v, c k = Some v <-> a k = Some v \/ b k = Some v.

Lemma map_join_spec : forall m1 m2 m3, join m1 m2 m3 <-> compatible m1 m2 /\ m3 = map_add m1 m2.