Module MySimulationTactics:= SimulationTactics CC_correct Args.
Notation thread_perms st i cnt:= (fst (@getThreadR _ _ st i cnt)).
Notation lock_perms st i cnt:= (snd (@getThreadR  _ _ st i cnt)).
(* *)
Instance Asm_get_extcall_arg:
Proper (Logic.eq ==> mem_equiv ==> Logic.eq ==> Logic.eq)
Asm.get_extcall_arg.
Instance Asm_get_extcall_arguments:
Proper (Logic.eq ==> mem_equiv ==> Logic.eq ==> Logic.eq)
Asm.get_extcall_arguments.
Instance  Asm_at_external_proper Asm_g:
Proper (Logic.eq ==> mem_equiv ==> Logic.eq)
(semantics.at_external (Asm_core.Asm_core_sem Asm_g)).
Instance C_at_external_proper Clight_g:
Proper (Logic.eq ==> mem_equiv ==> Logic.eq)
(semantics.at_external (Clight_core.cl_core_sem Clight_g)).
Instance Sum_at_external_proper':
forall hb,
Proper (Logic.eq ==> mem_equiv ==> Logic.eq)
(semantics.at_external (sem_coresem (HybridSem (Some hb)))).
Definition doesnt_return FUN:=
forall (res : val) (ge : Senv.t) (args : list val) (m : mem)
(ev : Events.trace) (m' : mem),
Events.external_call FUN ge args m ev res m' -> res = Vundef.
(*Lemmas about the calls: *)
Notation vone:= (Vint Int.one).
Notation vzero:= (Vint Int.zero).
Definition build_release_event addr dmap m:=
Events.release addr (Some (build_delta_content dmap m)).
Definition build_acquire_event addr dmap m:=
Events.acquire addr (Some (build_delta_content dmap m)).
(*TODO: Check if these guys are used/useful*)
Inductive release: val -> mem -> delta_map ->  mem -> Prop  :=
| ReleaseAngel:
forall b ofs m dpm m' m_release
(* change the permission to be able to lock *)
lock_perms Hlt,
Mem.store AST.Mint32 (@restrPermMap lock_perms m Hlt)
b (unsigned ofs) vone = Some m_release ->
(* return to the new, transfered permissions*)
forall new_perms Hlt',
(* Need to relate new_perms and dpm *)
new_perms = computeMap (getCurPerm m) dpm ->
m' = @restrPermMap new_perms m_release Hlt' ->
release (Vptr b ofs) m dpm m'.
Inductive acquire: val -> mem -> delta_map ->  mem -> Prop  :=
| AcquireAngel:
forall b ofs m dpm m' m_release
(* change the permission to be able to lock *)
lock_perms Hlt,
Mem.store AST.Mint32 (@restrPermMap lock_perms m Hlt)
b (unsigned ofs) vzero = Some m_release ->
(* return to the new, transfered permissions*)
forall new_perms Hlt',
(* Need to relate new_perms and dpm *)
new_perms = computeMap (getCurPerm m) dpm ->
m' = @restrPermMap new_perms m_release Hlt' ->
acquire (Vptr b ofs) m dpm m'.
Inductive extcall_release: Events.extcall_sem:=
| ExtCallRelease:
forall ge m m' m'' m''' b ofs e dpm e',
mem_interference m e m' ->
release (Vptr b ofs) m' dpm m'' ->
mem_interference m'' e' m''' ->
extcall_release ge (Vptr b ofs :: nil) m
(Events.Event_acq_rel e dpm e' :: nil)
Vundef m'''.
Inductive extcall_acquire: Events.extcall_sem:=
| ExtCallAcquire:
forall ge m m' m'' m''' b ofs e dpm e',
mem_interference m e m' ->
acquire (Vptr b ofs) m' dpm m'' ->
mem_interference m'' e' m''' ->
extcall_acquire ge (Vptr b ofs :: nil) m
(Events.Event_acq_rel e dpm e' :: nil)
Vundef m'''.
(** * Lemmas for relase diagram*)
(** * The following lemmas prove the injection of memories unfer setPermBlock. *)
Inductive coerce_state_type  {a b T}: forall t, @state_sum a b -> t -> T -> T -> T ->  Prop:=
| SourceCoerce_T: forall t1 t2 c, coerce_state_type a (@SState _ _ c) c t1 t2 t1
| TargetCoerce_T: forall t1 t2 c, coerce_state_type b (@TState _ _ c) c t1 t2 t2.
Definition mach_state n:= ThreadPool (Some n).
Admitted.
Admitted.
Admitted.
(* ASM LEMMAS *)
(** * End of Lemmas for relase diagram*)
Infix "++":= seq.cat.
Definition all_threads_inject_perm
(f:meminj) {n m} (st1: ThreadPool n) (st2: ThreadPool m) m1 m2:=
forall (i : nat) (cnt1 : containsThread st1 i) (cnt2 : containsThread st2 i)
(Hlt1 : permMapLt (thread_perms  _ _ cnt1) (getMaxPerm m1))
(Hlt2 : permMapLt (thread_perms  _ _ cnt2) (getMaxPerm m2)),
Mem.inject f (restrPermMap Hlt1) (restrPermMap Hlt2).
Definition all_threads_lock_perm_surj
(f:meminj) {n m} (st1: ThreadPool n) (st2: ThreadPool m):=
forall (i : nat) (cnt1 : containsThread st1 i) (cnt2 : containsThread st2 i),
perm_surj f (lock_perms  _ _ cnt1) (lock_perms  _ _ cnt2).

Lemma load_inject':
forall (f : meminj) (m1 m2 : mem) (chunk : AST.memory_chunk)
(b1 : block) (ofs : Z) (b2 : block) (delta : Z)
(v1 v2 : val),
Mem.inject f m1 m2 ->
Mem.load chunk m1 b1 ofs = Some v1 ->
f b1 = Some (b2, delta) ->
Val.inject f v1 v2 ->
v1 <> Vundef ->
Mem.load chunk m2 b2 (ofs + delta) = Some v2.