(* A version of juicy_machine that keeps track of lock invariants. *)
From mathcomp.ssreflect Require Import ssreflect ssrbool ssrnat ssrfun eqtype seq fintype finfun.
Set Implicit Arguments.
(*NOTE: because of redefinition of [val], these imports must appear after Ssreflect eqtype.*)
(*From msl get the juice! *)
Set Bullet Behavior "Strict Subproofs".
(*  This shoul be replaced by global: Require Import VST.concurrency.lksize.  *)
(* There are some overlaping definition conflicting. Here we fix that. But this is obviously ugly and the conflicts should be removed by renaming!     *)
Notation "x <= y" := (x <= y)%nat.
Notation "x < y" := (x < y)%nat.
Instance LockInvsAndResources : Resources := { res := rmap; lock_info := mpred * option rmap }.
Module ThreadPool.
Section ThreadPool.
Context {Sem: Semantics}.
(** The Lock Resources Set *)
Definition is_lock t:= fun loc => AMap.mem loc (lset t).
End ThreadPool.
End ThreadPool.
Module InvMachine.
(** Semantics of the coarse-grained juicy concurrent machine*)
Section InvMachineShell.
Context {Sem: Semantics}.
Notation C:= (semC).
Notation G:= (semG).
Notation tid:= nat.
Notation lockMap:= (AMap.t lock_info).
(** Memories*)
Definition richMem: Type:= juicy_mem.
Definition dryMem: richMem -> mem:= m_dry.
(** Environment and Threadwise semantics *)
(* This all comes from the SEM. *)
(*Parameter G : Type. Parameter Sem : CoreSemantics G code mem.*)
Notation the_sem := (csem (event_semantics.msem semSem)).
(*thread pool*)
Existing Instance OrdinalThreadPool.
Notation thread_pool := (@ThreadPool.t _ _ OrdinalThreadPool).
(** Machine Variables*)
Definition lp_id : tid:= (0)%nat. (*lock pool thread id*)
(** Invariants*)
(** The state respects the memory*)
Definition access_cohere' m phi:= forall loc,
Mem.perm_order'' (max_access_at m loc) (perm_of_res (phi @ loc)).
(* This is similar to the coherence of juicy memories, * * but for entire machines. It is slighly weaker in one way: * - acc_coh is looser and only talks about maxcoh. * - alse acc_coh  might me redundant with max_coh IDK... x*)
Record mem_cohere' m phi :=
{ cont_coh: contents_cohere m phi;
(*acc_coh: access_cohere m phi;*)
(*acc_coh: access_cohere' m phi;*)
max_coh: max_access_cohere m phi;
all_coh: alloc_cohere m phi
}.
Definition mem_thcohere (tp : thread_pool) m :=
forall {tid} (cnt: containsThread tp tid), mem_cohere' m (getThreadR cnt).
Definition mem_lock_cohere (ls:lockMap) m:=
forall loc R rm, AMap.find loc ls = Some (R, Some rm) -> mem_cohere' m rm.

(* Specifications: *)
Lemma length_enum_from n m pr : List.length (@enums_equality.enum_from n m pr) = n.
Lemma length_enum n : List.length (enums_equality.enum n) = n.
Definition getThreadsR (tp : thread_pool):=
map (perm_maps tp) (enums_equality.enum (num_threads tp)).