Require Export Ensembles.
Set Bullet Behavior "Strict Subproofs".
(* Thoughts on invariants and the two-level structure: I expect that our version of the operational semantics will keep nonatomic locations as is, so that the points-to assertions won't need view parameters (and in fact will be objective?). The question then is: do we need the two-level structure in which iGPS-style assertions are functions from view to mpred, or can even protocol assertions simply be mpreds? We might be able to use something like the external state construction to use ghost state to remember per-thread timestamps, so that we don't need to include timestamps in the rmap (or as an extra argument to assertions). In this model, there would be no objectivity requirement at all: instead, protocol assertions from other threads would be incompatible with the current thread because they refer to a different location for their timestamp ghost state. On the other hand, if we do need the two-level structure, we should still define invariants without objectivity here (as Iris-level invariants), and define iGPS-level invariants elsewhere. *)
(* We will still, of course, have to choose between SC and RA atomics in any given proof/program, since there's no soundness proof (or operational model) for a language with both. And invariants must still be accessible only via atomics. Does this make the fancy-update style useless, since we can't insert it into the definition of semax? Well, iGPS still uses it in the RA atomic rules, so maybe it's still useful. *)
Section atomics.
Context {CS : compspecs} {inv_names : invG}.
Section atomicity.

(* Specifications: *)
(* up *)
Lemma approx_mono: forall n P Q, (P >=> Q) (Nat.pred n) -> approx n P |-- approx n Q.
(* up *)
Lemma subp_wand: forall (G : Triv) (P P' Q Q' : mpred), G |-- P' >=> P -> G |-- Q >=> Q' ->
G |-- ((P -* Q) >=> (P' -* Q'))%pred.
Lemma eqp_wand: forall (G : Triv) (P P' Q Q' : mpred), G |-- P <=> P' -> G |-- Q <=> Q' ->
G |-- ((P -* Q) <=> (P' -* Q')).
Lemma subp_fupd: forall (G : Triv) E1 E2 (P P' : mpred), G |-- P >=> P' ->
G |-- ((|={E1,E2}=> P) >=> |={E1,E2}=> P').
Lemma eqp_fupd: forall (G : Triv) E1 E2 (P P' : mpred), G |-- P <=> P' ->
G |-- ((|={E1,E2}=> P) <=> |={E1,E2}=> P').
Lemma eqp_imp: forall (G : Triv) (P P' Q Q' : mpred),
G |-- P <=> P' -> G |-- Q <=> Q' -> G |-- (P --> Q) <=> P' --> Q'.
Lemma fview_shift_nonexpansive: forall E1 E2 P Q n,
approx n (P -* |={E1,E2}=> Q) = approx n (approx n P -* |={E1,E2}=> (approx n Q)).
(*Lemma apply_fview_shift: forall E1 E2 P Q, (weak_fview_shift E1 E2 P Q && emp) * P |-- |={E1, E2}=> Q.  Lemma apply_fview_shift' : forall E1 E2 P Q P', P' |-- |==> P -> weak_fview_shift E1 E2 P Q && emp * P' |-- |={E1,E2}=> Q.  (* up *)
Lemma emp_dup: forall P, P && emp = (P && emp) * (P && emp).
Definition atomic_shift {A B} (a : A -> mpred) Ei Eo (b : A -> B -> mpred) (Q : B -> mpred) :=
EX P : mpred, |> P * ((|> P -* |={Eo,Ei}=> (EX x : A, a x *
((a x -* |={Ei,Eo}=> |> P) &&
ALL y : B, b x y -* |={Ei,Eo}=> Q y))) && cored).