Opaque OrdinalPool.containsThread.
(** *** Safety and simulation lemmas *)

Lemma mem_obs_eq_execution:
forall tp1 tp2 tp1' m1 m2 m1' j xs f fg
(pf1j: containsThread tp1 j)
(pf1j': containsThread tp1' j)
(Hcomp1: mem_compatible tp1 m1)
(Hcomp1': mem_compatible tp1' m1')
(Hinv: invariant tp1')
(Hfg: forall b1 b2, fg b1 = Some b2 -> b1 = b2)
(Hge_wd: ge_wd fg the_ge)
(Hge_incr: ren_incr fg f)
(Hvalid_mem: valid_mem m1)
(Htp_wd: tp_wd f tp1)
(Hcode_eq: ctl_inj f (getThreadC pf1j) (getThreadC pf1j'))
(Hmem_obs_eq: mem_obs_eq f (restrPermMap (compat_th _ _ Hcomp1 pf1j).1)
(restrPermMap (compat_th _ _ Hcomp1' pf1j').1))
(Hexec: internal_execution [seq x <- xs | x == j] tp1 m1 tp2 m2),
exists tp2' m2' f',
internal_execution [seq x <- xs | x == j] tp1' m1' tp2' m2' /\
ren_incr f f' /\
ren_separated f f' m1 m1' /\
((exists p, ((Mem.nextblock m2 = Mem.nextblock m1 + p)%positive /\
(Mem.nextblock m2' = Mem.nextblock m1' + p)%positive))
\/ ((Mem.nextblock m2 = Mem.nextblock m1) /\
(Mem.nextblock m2' = Mem.nextblock m1'))) /\
(forall b,
Mem.valid_block m2' b ->
~ Mem.valid_block m1' b ->
let bz := ((Zpos b) - ((Zpos (Mem.nextblock m1')) -
(Zpos (Mem.nextblock m1))))%Z in
f' (Z.to_pos bz) = Some b /\
f (Z.to_pos bz) = None) /\
(exists (pf2j: containsThread tp2 j)
(pf2j': containsThread tp2' j)
(Hcomp2: mem_compatible tp2 m2)
(Hcomp2': mem_compatible tp2' m2'),
ctl_inj f' (getThreadC pf2j) (getThreadC pf2j') /\
mem_obs_eq f' (restrPermMap (compat_th _ _ Hcomp2 pf2j).1)
(restrPermMap (compat_th _ _ Hcomp2' pf2j').1)) /\
(Mem.nextblock m1 = Mem.nextblock m1' ->
(forall b1 b2 : block, f b1 = Some b2 -> b1 = b2) ->
forall b1 b2 : block, f' b1 = Some b2 -> b1 = b2).