(* The initial machine has to be redefined. Right now its build by default with empty maps, but it should be built with the correct juice, corresponding to global variables, arguments and function specs. *)
(*Lemma onePos: (0<1)%coq_nat. auto. Qed.*)
Definition initial_machine rmap c:=
mk
(mkPos (le_n 1))
(fun _ => (Krun c))
(fun _ => rmap)
(AMap.empty (option res)).
Definition init_mach rmap (m:mem) (tp:thread_pool) (m':mem) (v:val) (args:list val) : Prop :=
exists c, initial_core the_sem 0 m c m' v args /\
match rmap with Some rmap => tp = initial_machine rmap c | None => False end.
Section JuicyMachineLemmas.

(* Specifications: *)
Lemma compat_lockLT': forall js m,
mem_compatible js m ->
forall l r,
ThreadPool.lockRes js l = Some (Some r) ->
forall b ofs,
Mem.perm_order'' ((getMaxPerm m) !! b ofs) (perm_of_res' (r @ (b, ofs))).
Lemma compat_lockLT: forall js m,
mem_compatible js m ->
forall l r,
ThreadPool.lockRes js l = Some (Some r) ->
forall b ofs,
Mem.perm_order'' ((getMaxPerm m) !! b ofs) (perm_of_res (r @ (b, ofs))).
Lemma access_cohere_sub': forall phi1 phi2 m,
access_cohere' m phi1 ->
join_sub phi2 phi1 ->
access_cohere' m phi2.
Lemma mem_cohere'_juicy_mem jm : mem_cohere' (m_dry jm) (m_phi jm).
Lemma compatible_threadRes_join:
forall js m,
mem_compatible js m ->
forall i (cnti: containsThread js i) j (cntj: containsThread js j),
i <> j ->
sepalg.joins (getThreadR cnti) (getThreadR cntj).
Lemma compatible_threadRes_lockRes_join:
forall js m,
mem_compatible js m ->
forall i (cnti: containsThread js i) l phi,
ThreadPool.lockRes js l = Some (Some phi) ->
sepalg.joins (getThreadR cnti) phi.
Lemma compatible_lockRes_cohere: forall js m l phi,
lockRes js l = Some (Some phi) ->
mem_compatible js m ->
mem_cohere' m phi .
Lemma compatible_threadRes_cohere:
forall js m i (cnt:containsThread js i),
mem_compatible js m ->
mem_cohere' m (getThreadR cnt) .
(** *Lemmas about aging*)
Lemma cnt_age_iff {js i n} :
containsThread js i <->
containsThread (age_tp_to n js) i.
Lemma gtc_age : forall js i n,
forall (cnt: containsThread js i)
(cnt': containsThread (age_tp_to n js) i),
getThreadC cnt = getThreadC cnt'.
Lemma getThreadR_age: forall js i age,
forall (cnt: containsThread js i)
(cnt': containsThread (age_tp_to age js) i),
age_to age (getThreadR cnt) = getThreadR cnt'.
Lemma LockRes_age: forall js age a,
isSome (lockRes (age_tp_to age js) a) = isSome(lockRes js a).
Lemma LockRes_age_content1: forall js age a,
lockRes (age_tp_to age js) a = Some None ->
lockRes js a = Some None.