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}.

Lemma map_compose:
forall {A B C} (f1: _ -> B -> C) (f2: _ -> A -> B) t,
PTree.map f1 (PTree.map f2 t) =
PTree.map (fun ofs a => f1 ofs (f2 ofs a)) t.