(*IM using proof irrelevance!*)
(* The concurrent machinery*)
Require Export VST.concurrency.common.threadPool.
(*Semantics*)
Module THE_JUICY_MACHINE.
Module JuicyMachine := HybridMachineSig.
Export JuicyMachine.
Section THE_JUICY_MACHINE.
Context {ge : Clight.genv}.
Instance JSem : Semantics := Clight_newSem ge.
Definition JMachineSem := MachineSemantics(HybridMachine := HybridCoarseMachine.HybridCoarseMachine(machineSig:=JuicyMachineShell)).
Definition jstate := ThreadPool.t(resources := LocksAndResources)(ThreadPool := OrdinalPool.OrdinalThreadPool).
Definition jmachine_state := MachState(resources := LocksAndResources)(ThreadPool := OrdinalPool.OrdinalThreadPool).
(* safety with ghost updates *)
Definition tp_update (tp : jstate) phi tp' phi' :=
level phi' = level phi /\ resource_at phi' = resource_at phi /\
join_all tp' phi' /\
exists (Hiff : forall t, containsThread tp' t <-> containsThread tp t),
(forall t (cnt : containsThread tp t), getThreadC cnt = getThreadC (proj2 (Hiff _) cnt) /\
level (getThreadR cnt) = level (getThreadR (proj2 (Hiff _) cnt)) /\
resource_at (getThreadR cnt) = resource_at (getThreadR (proj2 (Hiff _) cnt))) /\
lockGuts tp' = lockGuts tp /\ lockSet tp' = lockSet tp /\
lockRes tp' = lockRes tp /\ latestThread tp'= latestThread tp.

Lemma tp_update_refl : forall tp phi, join_all tp phi -> tp_update tp phi tp phi.
Definition tp_bupd P (tp : jstate) :=
(exists phi, join_all tp phi /\ joins (ghost_of phi) (Some (ghost_PCM.ext_ref tt, NoneP) :: nil)) /\
forall phi, join_all tp phi ->
forall c : ghost, join_sub (Some (ghost_PCM.ext_ref tt, NoneP) :: nil) c ->
joins (ghost_of phi) (ghost_fmap (approx (level phi)) (approx (level phi)) c) ->
exists b : ghost,
joins b (ghost_fmap (approx (level phi)) (approx (level phi)) c) /\
exists phi' tp', tp_update tp phi tp' phi' /\ ghost_of phi' = b /\ P tp'.