Section ConcurMatch. (* 360 *)
Record concur_match (ocd: option compiler_index)
(j:meminj) (cstate1: ThreadPool (Some hb)) (m1: Mem.mem) (cstate2: ThreadPool(Some (S hb))) (m2: mem):=
{ same_length: num_threads cstate1 = num_threads cstate2
; full_inj: Events.injection_full j m1 (* this is needed until we can prove
permission transfer is not deleted*)
; memcompat1: mem_compatible cstate1 m1
; memcompat2: mem_compatible cstate2 m2
(*; INJ: Mem.inject j m1 m2 *)
; lock_perm_preimage:
forall i (cnt1: ThreadPool.containsThread cstate1 i)
(cnt2: ThreadPool.containsThread cstate2 i),
perm_surj j (lock_perms _ _ cnt1) (lock_perms _ _  cnt2)
; INJ_threads:
forall i (cnt1: ThreadPool.containsThread cstate1 i)
(cnt2: ThreadPool.containsThread cstate2 i)
Hlt1 Hlt2,
Mem.inject j
(@restrPermMap (fst (ThreadPool.getThreadR cnt1)) m1 Hlt1)
(@restrPermMap (fst (ThreadPool.getThreadR cnt2)) m2 Hlt2)
; INJ_locks:
forall i (cnt1: ThreadPool.containsThread cstate1 i)
(cnt2: ThreadPool.containsThread cstate2 i)
Hlt1 Hlt2,
Mem.inject j
(@restrPermMap (snd (ThreadPool.getThreadR cnt1)) m1 Hlt1)
(@restrPermMap (snd (ThreadPool.getThreadR cnt2)) m2 Hlt2)
; INJ_lock_permissions:
forall b b' delt opt_rmap,
j b = Some (b', delt) ->
forall ofs, lockRes cstate1 (b, unsigned ofs) = opt_rmap ->
lockRes cstate2 (b', unsigned (add ofs (repr delt))) =
(option_map (virtueLP_inject m2 j) opt_rmap)
; INJ_lock_content:
forall b ofs rmap,
lockRes cstate1 (b, ofs) = Some rmap ->
inject_lock j b ofs m1 m2
; source_invariant: invariant cstate1
; target_invariant: invariant cstate2
; mtch_source:
forall (i:nat),
(i > hb)%nat ->
forall  (cnt1: ThreadPool.containsThread cstate1 i)
(cnt2: ThreadPool.containsThread cstate2 i)
Hlt1 Hlt2,
match_thread_source j
(getThreadC cnt1)
(@restrPermMap (fst (ThreadPool.getThreadR cnt1)) m1 Hlt1)
(getThreadC cnt2)
(@restrPermMap (fst (ThreadPool.getThreadR cnt2)) m2 Hlt2)
; mtch_target:
forall (i:nat),
(i < hb)%nat ->
forall (cnt1: ThreadPool.containsThread cstate1 i)
(cnt2: ThreadPool.containsThread cstate2 i)
Hlt1 Hlt2,
match_thread_target  j
(getThreadC cnt1)
(@restrPermMap (fst (ThreadPool.getThreadR cnt1)) m1 Hlt1)
(getThreadC cnt2)
(@restrPermMap (fst (ThreadPool.getThreadR cnt2)) m2 Hlt2)
; mtch_compiled:
forall (i:nat),
(i = hb)%nat ->
forall (cnt1: ThreadPool.containsThread cstate1 i)
(cnt2: ThreadPool.containsThread cstate2 i)
Hlt1 Hlt2,
match_thread_compiled ocd j
(getThreadC cnt1)
(@restrPermMap (fst (ThreadPool.getThreadR cnt1)) m1 Hlt1)
(getThreadC cnt2)
(@restrPermMap (fst (ThreadPool.getThreadR cnt2)) m2 Hlt2) }.
Arguments INJ_locks {ocd j cstate1 m1 cstate2 m2}.
Arguments memcompat1 {ocd j cstate1 m1 cstate2 m2}.
Arguments memcompat2 {ocd j cstate1 m1 cstate2 m2}.
Inductive state_indicator:=
| Krun_indi
| Kblocked_indi
| Kresume_indi
| Kinit_indi.
Definition get_indicator {T: Type} (st:@ctl T): state_indicator:=
match st with
| Krun _ => Krun_indi
| Kblocked _ => Kblocked_indi
| Kresume _ _ => Kresume_indi
| Kinit _ _ => Kinit_indi
end.
Definition thread_indicator {Res Sem} i st cnt:=
get_indicator (@getThreadC Res Sem i st cnt).

Lemma concur_match_same_running:
forall (m : option mem) (cd : option compiler_index) (mu : meminj)
(c1 : ThreadPool (Some hb)) (m1 : mem) (c2 : ThreadPool (Some (S hb)))
(m2 : mem),
concur_match cd mu c1 m1 c2 m2 ->
forall i : nat,
machine_semantics.running_thread (HybConcSem (Some hb) m) c1 i <->
machine_semantics.running_thread (HybConcSem (Some (S hb)) m) c2 i.