Require VST.veric.NullExtension.
(*Require Import VST.veric.Clight_sim.*)
Definition ignores_juice Z (J: external_specification juicy_mem external_function Z) : Prop :=
(forall e t b tl vl x jm jm',
m_dry jm = m_dry jm' ->
ext_spec_pre J e t b tl vl x jm ->
ext_spec_pre J e t b tl vl x jm') /\
(forall ef t b ot v x jm jm',
m_dry jm = m_dry jm' ->
ext_spec_post J ef t b ot v x jm ->
ext_spec_post J ef t b ot v x jm') /\
(forall v x jm jm',
m_dry jm = m_dry jm' ->
ext_spec_exit J v x jm ->
ext_spec_exit J v x jm').
Definition mem_evolve (m m': mem) : Prop :=
(* dry version of resource_decay *)
forall loc,
match access_at m loc Cur, access_at m' loc Cur with
| None, None => True
| None, Some Freeable => True
| Some Freeable, None => True
| Some Writable, Some p' => p' = Writable
| Some p, Some p' => p=p' /\ access_at m loc Max = access_at m' loc Max
| _, _ => False
end.
Instance mem_evolve_refl : RelationClasses.Reflexive mem_evolve.
Definition ext_spec_mem_evolve (Z: Type)
(D: external_specification mem external_function Z) :=
forall ef w b tl vl ot v z m z' m',
ext_spec_pre D ef w b tl vl z m ->
ext_spec_post D ef w b ot v z' m' ->
mem_evolve m m'.
Definition juicy_dry_ext_spec (Z: Type)
(J: external_specification juicy_mem external_function Z)
(D: external_specification mem external_function Z)
(dessicate: forall ef jm, ext_spec_type J ef -> ext_spec_type D ef) :=
(forall e t t' b tl vl x jm,
dessicate e jm t = t' ->
(ext_spec_pre J e t b tl vl x jm ->
ext_spec_pre D e t' b tl vl x (m_dry jm))) /\
(forall ef t t' b ot v x jm0 jm,
(exists tl vl x0, dessicate ef jm0 t = t' /\ ext_spec_pre J ef t b tl vl x0 jm0) ->
(level jm <= level jm0)%nat ->
resource_at (m_phi jm) = resource_fmap (approx (level jm)) (approx (level jm)) oo juicy_mem_lemmas.rebuild_juicy_mem_fmap jm0 (m_dry jm) ->
ghost_of (m_phi jm) = Some (ghost_PCM.ext_ghost x, compcert_rmaps.RML.R.NoneP) :: ghost_fmap (approx (level jm)) (approx (level jm)) (tl (ghost_of (m_phi jm0))) ->
(ext_spec_post D ef t' b ot v x (m_dry jm) ->
ext_spec_post J ef t b ot v x jm)) /\
(forall v x jm,
ext_spec_exit J v x jm <->
ext_spec_exit D v x (m_dry jm)).
Definition juicy_dry_ext_spec_make (Z: Type)
(J: external_specification juicy_mem external_function Z) :
external_specification mem external_function Z.
destruct J.
apply Build_external_specification with ext_spec_type.
intros e t b tl vl x m.
apply (forall jm, m_dry jm = m -> (* external ghost matches x -> *) ext_spec_pre e t b tl vl x jm).
intros e t b ot v x m.
apply (forall jm, m_dry jm = m -> ext_spec_post e t b ot v x jm).
intros v x m.
apply (forall jm, m_dry jm = m -> ext_spec_exit v x jm).
Defined.
Definition dessicate_id Z
(J: external_specification juicy_mem external_function Z) :
forall ef (jm : juicy_mem), ext_spec_type J ef ->
ext_spec_type (juicy_dry_ext_spec_make Z J) ef.
intros.
destruct J; simpl in *. apply X.
Defined.
Definition mem_rmap_cohere m phi :=
contents_cohere m phi /\
access_cohere m phi /\
max_access_cohere m phi /\ alloc_cohere m phi.

Lemma whole_program_sequential_safety_ext:
forall {CS: compspecs} {Espec: OracleKind} (initial_oracle: OK_ty)
(EXIT: semax_prog.postcondition_allows_exit Espec tint)
(dryspec: ext_spec OK_ty)
(dessicate : forall (ef : external_function) jm,
ext_spec_type OK_spec ef ->
ext_spec_type dryspec ef)
(JDE: juicy_dry_ext_spec _ (@JE_spec OK_ty OK_spec) dryspec dessicate)
(DME: ext_spec_mem_evolve _ dryspec)
prog V G m,
@semax_prog Espec (*NullExtension.Espec*) CS prog initial_oracle V G ->
Genv.init_mem prog = Some m ->
exists b, exists q, exists m',
Genv.find_symbol (Genv.globalenv prog) (prog_main prog) = Some b /\
initial_core  (cl_core_sem (globalenv prog))
0 m q m' (Vptr b Ptrofs.zero) nil /\
forall n,
@dry_safeN _ _ _ OK_ty (semax.genv_symb_injective)
(cl_core_sem (globalenv prog))