Section CompileOneThread.
Context (hb: nat).
(*Instantiate definitions in Concur with the current hybridbound*)
Notation concur_match:= (concur_match hb).
Notation match_thread:= (match_thread hb).
Notation match_thread_source:= (match_thread_source hb).
Notation match_thread_target:= (match_thread_target hb).
Notation memcompat2:= (memcompat2 hb).
Notation memcompat1:= (memcompat1 hb).
Notation contains12:= (contains12 hb).
Notation mtch_target:= (mtch_target hb).
Notation mtch_compiled:= (mtch_compiled hb).
Notation mtch_source:= (mtch_source hb).
Notation thread_perms st i cnt:= (fst (@getThreadR _ _ st i cnt)).
Notation lock_perms st i cnt:= (snd (@getThreadR  _ _ st i cnt)).
Definition cast_t {Sem}:
@OrdinalPool.t _ Sem -> @ThreadPool.t _ Sem (@OrdinalThreadPool dryResources _):=
fun X => X.
(* Where to move this:*)
(* ConcurMatch used to be here. *)
(* The following tactics are also in permissions.v but for some reason that one doesn't work... *)
Ltac unfold_getCurPerm:=
repeat rewrite getCurPerm_correct in *;
unfold permission_at in *.
Ltac unfold_getMaxPerm:=
repeat rewrite getMaxPerm_correct in *;
unfold permission_at in *.
Ltac unfold_getPerm:=
try unfold_getMaxPerm; try unfold_getMaxPerm.
(** *Tactics These tactics are here becasue they must be outside a section. they also must be after concur_match definition. *)
(*Do I have to reppeat the LTAC from the section? *)
Inductive opt_rel' {A} (ord: A -> A -> Prop): option A -> option A -> Prop:=
| Some_ord:
forall x y, ord x y -> opt_rel' ord (Some x) (Some y).
(*This lemma is used when the compiled thread steps*)
Ltac exploit_match tac:=
unfold match_thread_target,match_thread_source in *;
repeat match goal with
| [ H: ThreadPool.getThreadC ?i = _ ?c |- _] => simpl in H
end;
match goal with
| [ H: getThreadC ?i = _ ?c,
H0: context[match_thread] |- _ ] =>
match type of H0 with
| forall (_: ?Hlt1Type) (_: ?Hlt2Type), _ =>
assert (Hlt1:Hlt1Type); [
first [eassumption | tac | idtac]|
assert (Hlt2:Hlt2Type); [
first [eassumption | tac | idtac]|
specialize (H0 Hlt1 Hlt2);
rewrite H in H0; inversion H0; subst; simpl in *; clear H0
]]
end
| [ H: getThreadC ?i = _ ?c,
H0: context[match_thread_compiled] |- _ ] =>
match type of H0 with
| forall (_: ?Hlt1Type) (_: ?Hlt2Type), _ =>
assert (Hlt1:Hlt1Type); [
first [eassumption | tac | idtac]|
assert (Hlt2:Hlt2Type); [
first [eassumption | tac | idtac]|
specialize (H0 Hlt1 Hlt2);
rewrite H in H0; inversion H0; subst; simpl in *; clear H0
]]
end
end;
fold match_thread_target in *;
fold match_thread_source in *.
(* Build the concur_match *)
Ltac destroy_ev_step_sum:=
match goal with
| [ H: ev_step_sum _ _ _ _ _ _ _ |- _ ] => inversion H; clear H
end.
(* This in principle is not provable. We should get it somehow from the simulation. Possibly, by showing that the (internal) Clight step has no traces and allo external function calls have traces, so the "matching" Asm execution must be all internal steps (because otherwise the traces wouldn't match). *)

(* When a thread takes an internal step (i.e. not changing the schedule) *)
Lemma internal_step_diagram:
forall (m : option mem) (sge tge : HybridMachineSig.G) (U : list nat) tr1
(st1 : ThreadPool (Some hb)) m1 (st1' : ThreadPool (Some hb)) m1',
machine_semantics.thread_step (HybConcSem (Some hb) m) sge U st1 m1 st1' m1' ->
forall cd tr2 (st2 : ThreadPool (Some (S hb))) mu m2,
concur_match cd mu st1 m1 st2 m2 ->
forall (Hmatch_event : List.Forall2 (inject_mevent mu) tr1 tr2),
exists (st2' : ThreadPool (Some (S hb))) m2' cd' mu',
concur_match cd' mu' st1' m1' st2' m2' /\
List.Forall2 (inject_mevent mu') tr1 tr2 /\
(machine_semantics_lemmas.thread_step_plus
(HybConcSem (Some (S hb)) m) tge U st2 m2 st2' m2' \/
machine_semantics_lemmas.thread_step_star
(HybConcSem (Some (S hb)) m) tge U st2 m2 st2' m2' /\
opt_rel' (InjorderX compiler_sim) cd' cd).