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.
Inductive strict_evolution_diagram cd mu code1 m1 m1' code2 m2':=
| build_stric_diagram:
forall lev1 lev2 j m2
(Hcomp_match : compiler_match cd j code1 m1 code2 m2)
(Hstrict_evolution : strict_injection_evolution j mu lev1 lev2)
(Hinterference1 : mem_interference m1 lev1 m1')
(Hinterference2 : mem_interference m2 lev2 m2'),
strict_evolution_diagram cd mu code1 m1 m1' code2 m2'.
Inductive interference_diagram_atx i code1 code2 m1 f' m1' m2' :=
| build_inter_diagram_atx:
forall f FUN m2 args1 args2  lev1 lev2
(Hinj: Mem.inject f m1 m2)
(Hinj': Mem.inject f' m1' m2')
(Hstrict_evolution: strict_injection_evolution f f' lev1 lev2)
(Hmatch_states: compiler_match i f code1 m1 code2 m2)
(*Hmatch_states': compiler_match i f' code1 m1' code2 m2'*)
(* Probably can also add this, but seems like I don't need it*)
(Hinterference1 : mem_interference m1 lev1 m1')
(Hinterference2 : mem_interference m2 lev2 m2')
(Hat_external1: Clight.at_external (Clight.set_mem code1 m1) =
Some (FUN, args1))
(Hat_external1': Clight.at_external (Clight.set_mem code1 m1') =
Some (FUN, args1))
(Hat_external2: Asm.at_external Asm_g (Asm.set_mem code2 m2) =
Some (FUN, args2))
(Hat_external2': Asm.at_external Asm_g (Asm.set_mem code2 m2') =
Some (FUN, args2))
(Hinj_args: Val.inject_list f args1 args2)
, interference_diagram_atx i code1 code2 m1 f' m1' m2'.
Inductive strict_evolution_diagram' cd mu code1 m1 m1' code2 m2':=
| build_stric_diagram':
forall lev1 lev2 j m2
(Hcomp_match : compiler_match cd j code1 m1 code2 m2)
(Hstrict_evolution : strict_injection_evolution j mu lev1 lev2)
(Hinterference1 : mem_interference m1 lev1 m1')
(Hinterference2 : mem_interference m2 lev2 m2'),
strict_evolution_diagram' cd mu code1 m1 m1' code2 m2'.

Lemma retroactive_int_diagram_atx:
forall  i code1 code2 m1 f' m1' m2' FUN
(Hstrict: strict_evolution_diagram i f' code1 m1 m1' code2 m2')
(Hinj': Mem.inject f' m1' m2')
args1
(Hat_external1': Clight.at_external (Clight.set_mem code1 m1') =
Some (FUN, args1)),
interference_diagram_atx i code1 code2 m1 f' m1' m2'.