Section SimProofs.
Context {asmSem : Semantics}
{semAxioms : SemAxioms}
{semDet : SemDet}
{CI: CoreInj}
{initU : seq nat}.
Existing Instance OrdinalPool.OrdinalThreadPool.
Existing Instance DryHybridMachine.DryHybridMachineSig.
Existing Instance dryFineMach.
Existing Instance FineDilMem.
Existing Instance dryCoarseMach.
Existing Instance HybridFineMachine.scheduler.
Existing Instance HybridCoarseMachine.scheduler.
Existing Instance FineDilMem.
Existing Instance HybridCoarseMachine.DilMem.
Notation csafe := (HybridCoarseMachine.csafe).
Notation sim_fail_def := (@sim_fail_def _ _ initU).
Notation threadStep := (HybridMachineSig.threadStep).
Notation cmachine_step := ((corestep (AsmContext.coarse_semantics initU))).
Notation fmachine_step := ((corestep (AsmContext.fine_semantics initU))).
Notation "cnt '$' m '@'  'I'" := (getStepType cnt m Internal) (at level 80).
Notation "cnt '$' m '@'  'E'" := (getStepType cnt m Concurrent) (at level 80).
Notation "cnt '$' m '@'  'S'" := (getStepType cnt m Suspend) (at level 80).
Notation internal_step := (internal_step).
Notation internal_execution := (internal_execution).
Notation fyield := (@yield HybridFineMachine.scheduler).
Notation fdiluteMem := (@diluteMem FineDilMem).
Notation sim_internal_def := (@sim_internal_def _ _ initU).
Notation sim_suspend_def := (@sim_suspend_def _ _ initU).
Notation sim_external_def := (@sim_external_def _ _ initU).
(** NOTE: this is only needed to find out if a block is in the codomain of f, which is decidable *)
Hypothesis em : excluded_middle.
(** Function that projects the angel through a memory injection to compute a new angel *)
Definition projectAngel (f : memren) (deltaMap : delta_map) : delta_map :=
Maps.PTree.fold (fun acc b bperm =>
match f b with
| Some b' =>
Maps.PTree.set b' bperm acc
| None =>
acc end)
deltaMap (Maps.PTree.empty _).

Lemma computeMap_projection_3 :
forall  (f : memren) (virtue : delta_map) b1 b2
(Hf: f b1 = Some b2)
(Hinjective : forall b1 b1' b2 : block,
f b1 = Some b2 -> f b1' = Some b2 -> b1 = b1'),
(computeMap empty_map (projectAngel f virtue)) # b2 =
(computeMap empty_map virtue) # b1.