(* to make the proof faster, we avoid unfolding of those definitions *)
Definition Jspec'_juicy_mem_equiv_def CS ext_link :=
ext_spec_stable juicy_mem_equiv (JE_spec _ ( @OK_spec (Concurrent_Espec unit CS ext_link))).
Definition Jspec'_hered_def CS ext_link :=
ext_spec_stable age (JE_spec _ ( @OK_spec (Concurrent_Espec unit CS ext_link))).

Lemma preservation_acquire
(lockSet_Writable_updLockSet_updThread
: forall ge (m m' : Memory.mem) (i : nat) (tp : jstate ge),
forall (cnti : containsThread tp i) (b : block) (ofs : ptrofs) (ophi : option rmap)
(ophi' : lock_info) (c' : ctl) (phi' : res)
(z : int) (Hcmpt : mem_compatible tp m)
(Hcmpt : mem_compatible tp m)
(His_unlocked : AMap.find (elt:=option rmap) (b, Ptrofs.intval ofs) (lset tp) = Some ophi)
(Hlt' : permMapLt
(setPermBlock (Some Writable) b (Ptrofs.intval ofs) (juice2Perm_locks (getThreadR i tp cnti) m)
LKSIZE_nat) (getMaxPerm m))
(Hstore : Mem.store Mint32 (restrPermMap Hlt') b (Ptrofs.intval ofs) (Vint z) = Some m'),
lockSet_Writable (lset (updLockSet (updThread i tp cnti c' phi') (b, Ptrofs.intval ofs) ophi')) m')
(mem_cohere'_store : forall ge m (tp : jstate ge) m' b ofs j i Phi (cnti : containsThread tp i)
(Hcmpt : mem_compatible tp m)
(lock : lockRes tp (b, Ptrofs.intval ofs) <> None)
(Hlt' : permMapLt
(setPermBlock (Some Writable) b (Ptrofs.intval ofs) (juice2Perm_locks (getThreadR i tp cnti) m)
LKSIZE_nat) (getMaxPerm m))
(Hstore : Mem.store Mint32 (restrPermMap Hlt') b (Ptrofs.intval ofs) (Vint j) = Some m'),
mem_compatible_with tp m Phi ->
(exists phi, join_sub phi Phi /\ exists sh R, LKspec LKSIZE sh R (b, Ptrofs.intval ofs) phi) ->
mem_cohere' m' Phi)
(personal_mem_equiv_spec
: forall (m m' : Mem.mem') (phi : rmap) (pr : mem_cohere' m phi) (pr' : mem_cohere' m' phi),
Mem.nextblock m = Mem.nextblock m' ->
(forall loc : address, max_access_at m loc = max_access_at m' loc) ->
(forall loc : AV.address, isVAL (phi @ loc) -> contents_at m loc = contents_at m' loc) ->
mem_equiv (m_dry (personal_mem m phi pr)) (m_dry (personal_mem m' phi pr')))
(CS : compspecs)
(ext_link : string -> ident)
(ext_link_inj : forall s1 s2, ext_link s1 = ext_link s2 -> s1 = s2)
(Jspec' := @OK_spec (Concurrent_Espec unit CS ext_link))
(Jspec'_juicy_mem_equiv : Jspec'_juicy_mem_equiv_def CS ext_link)
(Jspec'_hered : Jspec'_hered_def CS ext_link)
(Gamma : funspecs)
(n : nat)
(ge : genv)
(m m' : Memory.mem)
(tr : event_trace)
(i : nat)
(sch : list nat)
(tp : jstate ge)
(INV : state_invariant Jspec' Gamma (S n) (m, (tr, i :: sch, tp)))
(Phi : rmap)
(compat : mem_compatible_with tp m Phi)
(lev : level Phi = S n)
(envcoh : env_coherence Jspec' ge Gamma Phi)
(extcompat : joins (ghost_of Phi) (Some (ext_ref tt, NoneP) :: nil))
(sparse : lock_sparsity (lset tp))
(lock_coh : lock_coherence' tp Phi m compat)
(safety : threads_safety Jspec' m tp Phi compat (S n))
(wellformed : threads_wellformed tp)
(unique : unique_Krun tp (i :: sch))
(Ei cnti : containsThread tp i)
(ci : semC)
(Eci : getThreadC i tp cnti = Kblocked ci)
(Hcmpt : mem_compatible tp m)
(El : (level (getThreadR i tp cnti) - 1 = n)%nat)
(compat_aged : mem_compatible_with (age_tp_to n tp) m (age_to n Phi))
(c : semC)
(b : block)
(ofs : ptrofs)
(d_phi : rmap)
(phi' : rmap)
(sh : Share.t)
(psh : shares.readable_share sh)
(R : pred rmap)
(Hthread : getThreadC i tp cnti = Kblocked c)
(Hat_external : at_external (ClightSemanticsForMachines.CLN_evsem ge) c m = Some (LOCK, Vptr b ofs :: nil))
(His_unlocked : lockRes tp (b, Ptrofs.intval ofs) = Some (Some d_phi))
(Hload : Mem.load Mint32 (juicyRestrict_locks (mem_compat_thread_max_cohere Hcmpt cnti))
b (Ptrofs.intval ofs) =
Some (Vint Int.one))
(Hlt' : permMapLt
(setPermBlock (Some Writable) b (Ptrofs.intval ofs) (juice2Perm_locks (getThreadR i tp cnti) m)
LKSIZE_nat) (getMaxPerm m))
(Hstore : Mem.store Mint32 (restrPermMap Hlt') b (Ptrofs.intval ofs) (Vint Int.zero) = Some m')
(Hadd_lock_res : join (getThreadR i tp cnti) d_phi phi')
(jmstep : @JuicyMachine.machine_step _ (ClightSemanticsForMachines.Clight_newSem ge) _ HybridCoarseMachine.DilMem JuicyMachineShell HybridMachineSig.HybridCoarseMachine.scheduler (i :: sch) tr tp m sch (seq.cat tr (external i (acquire (b, Ptrofs.intval ofs) None) :: nil))
(age_tp_to n
(updLockSet (updThread i tp cnti (Kresume c Vundef) phi') (b, Ptrofs.intval ofs) None)) m')
(Htstep : @syncStep (ClightSemanticsForMachines.Clight_newSem ge) true _ _ _ cnti Hcmpt
(age_tp_to n
(updLockSet (updThread i tp cnti (Kresume c Vundef) phi') (b, Ptrofs.intval ofs) None)) m'
(Events.acquire (b, Ptrofs.intval ofs) None)) :
state_invariant Jspec' Gamma n (m', (seq.cat tr (external i (acquire (b, Ptrofs.intval ofs) None) :: nil), sch, age_tp_to n
(updLockSet (updThread i tp cnti (Kresume c Vundef) phi') (b, Ptrofs.intval ofs) None) : jstate ge)).