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.

Lemma asm_after_external_when_external_step:
forall (ge:Asm.genv) c2 m ev c2' args FUN name sig
(HeqFUN: FUN = (AST.EF_external name sig))
(HnoReturn : AST.sig_res sig = None)
(Hno_return: doesnt_return FUN)
(Hstep: Asm.step ge (Asm.set_mem c2 m) (ev::nil) c2')
(Hat_x: Asm.at_external ge (Asm.set_mem c2 m) = Some (FUN, args)),
Asm.after_external ge None c2 (Asm.get_mem c2') = Some c2'.