Module ShareMap.
Section SM.
Variable A:Type.
Variable EqDec_A : EqDec A.
Variable B:Type.
Variable JB: Join B.
Variable paB : Perm_alg B.
Variable saB : Sep_alg B.
Definition map := fpm A (lifted Share.Join_ba * B).
Instance Join_map : Join map := Join_fpm _.
Instance pa_map : Perm_alg map := Perm_fpm _ _.
Instance sa_map : Sep_alg map := Sep_fpm _ _.
Instance ca_map {CA: Canc_alg B} : Canc_alg map := Canc_fpm _.
Instance da_map {DA: Disj_alg B} : Disj_alg map := @Disj_fpm _ _ _ _ _ _.
Definition map_share (a:A) (m:map) : share :=
match lookup_fpm m a with
| Some (sh,_) => lifted_obj sh
| None => Share.bot
end.
Definition map_val (a:A) (m:map) : option B :=
match lookup_fpm m a with
| Some (_,b) => Some b
| None => None
end.
Definition empty_map : map := empty_fpm _ _.
Definition map_upd (a:A) (b:B) (m:map) : option map :=
match lookup_fpm m a with
| Some (sh,_) =>
if eq_dec (lifted_obj sh) fullshare
then Some (insert_fpm _ a (sh,b) m)
else None
| None => None
end.

(* Specifications: *)
Lemma join_lifted {t} {J: Join t}:
forall (a b c: lifted J), join a b c -> join (lifted_obj a) (lifted_obj b) (lifted_obj c).
Lemma map_join_char : forall m1 m2 m3,
join m1 m2 m3 <->
(forall a,
join (map_share a m1) (map_share a m2) (map_share a m3) /\
join (map_val a m1) (map_val a m2) (map_val a m3)).