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).

Lemma atx_injection Sem:
let CoreSem := sem_coresem Sem in
forall (SelfSim: (self_simulation semC CoreSem))
mu b1 b2 delt th_state1 th_state2 m1 m2 FUN ofs,
mu b1 = Some (b2, delt) ->
match_self (code_inject semC CoreSem SelfSim) mu th_state1 m1 th_state2 m2 ->
semantics.at_external CoreSem th_state1 m1 =
Some (FUN, (Vptr b1 ofs) :: nil) ->
semantics.at_external CoreSem th_state2 m2 =
Some (FUN, Vptr b2 (add ofs (repr delt)) :: nil).