Section ENVSEC.
Context {key: Type}{A: Type}.
Instance JA: Join A := Join_equiv A.
Definition env := fpm key (pshare * A).
Definition env_get (rho: env) (id: key) : option (pshare * A) := lookup_fpm rho id.
Definition env_set_sh {KE: EqDec key} (id: key) (v: option (pshare * A)) (rho: env) : env :=
insert'_fpm _ id v rho.
Definition env_set {KE: EqDec key} (id: key) (v: A) (rho: env) : env :=
insert_fpm _ id (pfullshare,v) rho.
Definition finite_idfun (f: key -> option (pshare * A)) :=
(exists l, forall a, ~In a l -> f a = None).
Definition mk_env_aux: forall f, finite_idfun f -> finMap f.
Definition mk_env (f: key -> option (pshare * A))  (FIN: finite_idfun f):  env :=
exist _ _ (mk_env_aux _ FIN).
intros.
destruct rho.
unfold finite_idfun, finMap in *.
generalize f; intros [l ?].
exists l; simpl in *.
intros; unfold compose in *.
apply e; auto.
Qed.
Definition empty_env : env := mk_env _ finite_idfun_empty.
Instance Join_env: Join env :=
fun (rho1 rho2 rho3: env) => join (env_get rho1) (env_get rho2) (env_get rho3).
Instance Perm_env {PA: Perm_alg A}: @Perm_alg env Join_env.
Instance Sep_env {SA: Sep_alg A}: @Sep_alg env Join_env.
refine (mkSep Join_env (fun _ => empty_env) _ _).
repeat intro; rewrite env_get_empty; constructor.
auto.
Defined.
Instance Sing_env {SA: Sep_alg A}: @Sing_alg env Join_env Sep_env.
refine (mkSing empty_env _). reflexivity.
Defined.
Instance Canc_env {PA: Perm_alg A}{CA: Canc_alg A}: @Canc_alg env Join_env.
Instance Disj_env {PA: Perm_alg A}{DA: Disj_alg A}: @Disj_alg env Join_env.
Instance Cross_env: Cross_alg env.
Definition _env_mapsto {KE: EqDec key} (id: key) (sh: Share.t) (v: A) : pred env :=
fun rho => exists p,
forall id', env_get rho id' = if eq_dec id id' then Some (exist _ sh p,v) else None.

Lemma _env_mapsto_splittable {KE: EqDec key}: forall id v (sh sh1 sh2: pshare) rho,
join (proj1_sig sh1) (proj1_sig sh2) (proj1_sig sh)
-> (_env_mapsto id (pshare_sh sh) v rho
<-> (_env_mapsto id (pshare_sh sh1) v * _env_mapsto id (pshare_sh sh2)  v)%pred rho).