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).
Inductive lock_update_mem_strict b ofs m m': val -> Prop :=
| Build_lock_update_mem_strict:
forall vstore
(Haccess: Mem.range_perm m b ofs (ofs + LKSIZE) Cur Writable)
(Hstore: Mem.store AST.Mint32 m b ofs vstore = Some m'),
lock_update_mem_strict b ofs m m' vstore.
Inductive lock_update_mem_strict_load b ofs lock_perm m m': val -> val -> Prop :=
| Build_lock_update_mem_strict_load:
forall lock_mem_lt vload vstore
(Hwritable_lock1 : writable_lock b ofs lock_perm m),
let lock_mem:= @restrPermMap lock_perm m lock_mem_lt in
let m_writable_lock_1:= restrPermMap Hwritable_lock1 in
forall (Haccess: Mem.range_perm lock_mem b ofs (ofs + LKSIZE) Cur Readable)
(Hload: Mem.load AST.Mint32 lock_mem b ofs = Some vload)
(Hstore: Mem.store AST.Mint32 m_writable_lock_1 b ofs vstore = Some m'),
lock_update_mem_strict_load b ofs lock_perm m m' vload vstore.
Definition fullThreadUpdate {sem} st i cnt th_st new_perms adr  :=
(updLockSet
(@updThread dryResources sem i st cnt th_st (fst new_perms)) adr (snd new_perms)).
Definition fullThUpd_comp {sem} st i cnt th_st (angel: virtue) adr  :=
@fullThreadUpdate
sem st i cnt th_st
(computeMap_pair (getThreadR cnt) (virtueThread angel), virtueLP angel) adr.

(** *TODO: all follwoing lemmas are about address arithmetic maybe move it to a section? *)
Lemma address_inj_store':
forall mu m1 m2' m1' b1 b2 ofs delt v,
mu b1 = Some (b2, delt) ->
Mem.inject mu m1' m2' ->
Mem.store AST.Mint32 m1 b1 (unsigned ofs) v = Some m1' ->
unsigned (add ofs (repr delt)) = unsigned ofs + delt.