Hint Resolve self_completable : init.
Section Discrete.
Program Instance discrete_PCM (A : Type) : Ghost := { valid a := True;
Join_G := Join_equiv A }.
Next Obligation.
auto.
Defined.
End Discrete.
Section GVar.
Context {A : Type}.
Definition ghost_var (sh : share) (v : A) g :=
own(RA := @pos_PCM (discrete_PCM A)) g (Some (sh, v)) NoneP.

(* Specifications: *)
Lemma ghost_var_share_join : forall sh1 sh2 sh v p, sepalg.join sh1 sh2 sh ->
sh1 <> Share.bot -> sh2 <> Share.bot ->
ghost_var sh1 v p * ghost_var sh2 v p = ghost_var sh v p.
Lemma ghost_var_share_join_gen : forall sh1 sh2 v1 v2 p,
ghost_var sh1 v1 p * ghost_var sh2 v2 p = EX sh : _,
!!(v1 = v2 /\ sh1 <> Share.bot /\ sh2 <> Share.bot /\ sepalg.join sh1 sh2 sh) && ghost_var sh v1 p.
Lemma ghost_var_inj : forall sh1 sh2 v1 v2 p, sh1 <> Share.bot -> sh2 <> Share.bot ->
ghost_var sh1 v1 p * ghost_var sh2 v2 p |-- !!(v1 = v2).
Lemma ghost_var_share_join' : forall sh1 sh2 sh v1 v2 p, sh1 <> Share.bot -> sh2 <> Share.bot ->
sepalg.join sh1 sh2 sh ->
ghost_var sh1 v1 p * ghost_var sh2 v2 p = !!(v1 = v2) && ghost_var sh v2 p.
Lemma ghost_var_update : forall v p v', ghost_var Tsh v p |-- |==> ghost_var Tsh v' p.
Global Program Instance nat_PCM: Ghost := { valid a := True; Join_G a b c := c = Nat.max a b }.