Ltac exec_induction base_case :=
intros;
match goal with
| [xs : list _, i : nat, Hexec: internal_execution _ ?Tp ?M _ _ |- _] =>
generalize dependent Tp; generalize dependent M;
induction xs as [| x xs' IHxs]; intros;
[ match goal with
| [Hexec: internal_execution _ _ _ _ _ |- _] =>
try (inversion Hexec; subst;
by Tactics.pf_cleanup)
end
| match goal with
| [Hexec: internal_execution _ _ _ _ _ |- _] =>
simpl in Hexec;
destruct (x == i) eqn:Heq;
move/eqP:Heq=>Heq;
try eauto;
subst;
try (inversion Hexec as [|? ? ? ? ? ? ? ? ? ?
HschedN HschedS Hcomp ? Htrans]; subst;
simpl in Htrans;
simpl in HschedN; inversion HschedN; subst;
Tactics.pf_cleanup;
specialize (IHxs _ _  Htrans);
rewrite <- IHxs;
erewrite base_case; eauto)
end
]
end.

(* Specifications: *)
(** [containsThread] is preserved by [internal_step]*)
Lemma containsThread_internal_step :
forall tp m tp' m' tid0 tid
(Hcnt0: containsThread tp tid0)
(Hcomp: mem_compatible tp m)
(Hstep: internal_step Hcnt0 Hcomp tp' m')
(Hcnt: containsThread tp tid),
containsThread tp' tid.
(** [containsThread] is preserved by [internal_execution]*)
Lemma containsThread_internal_execution :
forall U tp m tp' m' i
(Hexec: internal_execution U tp m tp' m'),
containsThread tp i -> containsThread tp' i.
(** The other direction: if a thread is in the threadpool after an [internal_step] then it must have been there before the step *)
Lemma containsThread_internal_step' :
forall tp m tp' m' i j
(Hcnt0: containsThread tp j)
(Hcomp: mem_compatible tp m)
(Hstep: internal_step Hcnt0 Hcomp tp' m')
(Hcnt: containsThread tp' i),
containsThread tp i.
Lemma containsThread_internal_execution' :
forall U tp m tp' m' i
(Hexec: internal_execution U tp m tp' m')
(Hcnt: containsThread tp' i),
containsThread tp i.
(** [mem_compatible] is preserved by [dry_step]*)
Lemma dry_step_compatible :
forall (tp tp' : t) m m' (i : nat) ev (pf : containsThread tp i)
(Hcompatible: mem_compatible tp m)
(Hdry: dry_step pf Hcompatible tp' m' ev),
mem_compatible tp' m'.
(** [mem_compatible] is preserved by [resume_thread]*)
Corollary resume_compatible :
forall (tp tp' : t) m (i : nat) (pf : containsThread tp i)
(Hcompatible: mem_compatible tp m)
(Hresume: resume_thread m pf tp'),
mem_compatible tp' m.
(** [mem_compatible] is preserved by [start_thread]*)
Corollary start_compatible :
forall (tp tp' : t) m m' (i : nat) (pf : containsThread tp i)
(Hcompatible: mem_compatible tp m)
(Hstart: start_thread m pf tp' m'),
mem_compatible tp' m'.
(** [mem_compatible] is preserved by [internal_step]*)
Corollary internal_step_compatible :
forall (tp tp' : t) m m' (i : nat) (pf : containsThread tp i)
(Hcompatible: mem_compatible tp m)
(Hstep: internal_step pf Hcompatible tp' m'),
mem_compatible tp' m'.
(** [invariant] is preserved by [internal_step]*)
Lemma internal_step_invariant:
forall (tp tp' : t) m m' (i : nat) (pf : containsThread tp i)
(Hcompatible: mem_compatible tp m)
(Hstep: internal_step pf Hcompatible tp' m'),
invariant tp'.
Lemma internal_execution_compatible :
forall (tp tp' : t) m m' xs
(Hcompatible: mem_compatible tp m)
(Hstep: internal_execution xs tp m tp' m'),
mem_compatible tp' m'.
Lemma internal_execution_invariant :
forall (tp tp' : t) m m' xs
(Hcompatible: mem_compatible tp m)
(Hinv: invariant tp)
(Hstep: internal_execution xs tp m tp' m'),
invariant tp'.
Lemma gsoThreadC_step:
forall tp tp' m m' i j (pfi: containsThread tp i)
(pfj: containsThread tp j)
(pfj': containsThread tp' j)
(Hcomp: mem_compatible tp m)
(Hstep: internal_step pfi Hcomp tp' m')
(Hneq: i <> j),
getThreadC pfj = getThreadC pfj'.
Lemma gsoThreadC_exec:
forall tp m tp' m' i j xs
(pfj: containsThread tp j)
(pfj': containsThread tp' j)
(Hstep: internal_execution [seq x <- xs | x == i] tp m tp' m')
(Hneq: i <> j),
getThreadC pfj = getThreadC pfj'.
(** Other thread permissions do not change by [internal_step]*)
Lemma gsoThreadR_step:
forall tp tp' m m' i j (pfi: containsThread tp i)
(pfj: containsThread tp j)
(pfj': containsThread tp' j)
(Hcomp: mem_compatible tp m)
(Hstep: internal_step pfi Hcomp tp' m')
(Hneq: i <> j),
getThreadR pfj = getThreadR pfj'.
Corollary permission_at_step:
forall tp tp' m m' i j
(Hneq: i <> j)
(pfi: containsThread tp i)
(pfj: containsThread tp j)
(pfj': containsThread tp' j)
(Hcomp: mem_compatible tp m)
(Hcomp': mem_compatible tp' m')
(Hstep: internal_step pfi Hcomp tp' m') b ofs,
permission_at (restrPermMap ((compat_th _ _ Hcomp) pfj).1) b ofs Cur =
permission_at (restrPermMap ((compat_th _ _ Hcomp') pfj').1) b ofs Cur /\
permission_at (restrPermMap ((compat_th _ _ Hcomp) pfj).2) b ofs Cur =
permission_at (restrPermMap ((compat_th _ _ Hcomp') pfj').2) b ofs Cur.
Lemma gsoThreadR_execution:
forall tp m tp' m' i j xs
(pfj: containsThread tp j)
(pfj': containsThread tp' j)
(Hneq: i <> j)
(Hstep: internal_execution [seq x <- xs | x == i] tp m tp' m'),
getThreadR pfj = getThreadR pfj'.
(** The [lockRes] is preserved by [internal_step]*)
Lemma gsoLockPool_step:
forall tp tp' m m' i (pfi: containsThread tp i)
(Hcomp: mem_compatible tp m)
(Hstep: internal_step pfi Hcomp tp' m') addr,
lockRes tp addr = lockRes tp' addr.
(** The [lockRes] is preserved by [internal_execution]*)
Lemma gsoLockPool_execution :
forall (tp : t) (m : mem) (tp' : t)
(m' : mem) (i : nat) (xs : seq nat_eqType)
(Hexec: internal_execution [seq x <- xs | x == i] tp m tp' m')
addr,
lockRes tp addr = lockRes tp' addr.
(** Lock resources of the threads are preserved by [internal_step] *)
Lemma internal_step_locks_eq:
forall tp m tp' m' i (cnti: containsThread tp i)
(Hcomp: mem_compatible tp m)
(Hstep: internal_step cnti Hcomp tp' m'),
forall j (cntj: containsThread tp j) (cntj': containsThread tp' j),
(getThreadR cntj).2 = (getThreadR cntj').2.
(** Lock resources of the threads are preserved by [internal_execution] *)
Lemma internal_execution_locks_eq:
forall tp m tp' m' xs
(Hexec: internal_execution xs tp m tp' m'),
forall j (cntj: containsThread tp j) (cntj': containsThread tp' j),
(getThreadR cntj).2 = (getThreadR cntj').2.
Lemma permission_at_execution:
forall tp m tp' m' i j xs
(pfi: containsThread tp i)
(pfj: containsThread tp j)
(pfj': containsThread tp' j)
(Hneq: i <> j)
(Hcomp: mem_compatible tp m)
(Hcomp': mem_compatible tp' m')
(Hstep: internal_execution [seq x <- xs | x == i] tp m tp' m'),
forall b ofs,
permission_at (restrPermMap ((compat_th _ _ Hcomp) pfj).1) b ofs Cur =
permission_at (restrPermMap ((compat_th _ _ Hcomp') pfj').1) b ofs Cur /\
permission_at (restrPermMap ((compat_th _ _ Hcomp) pfj).2) b ofs Cur =
permission_at (restrPermMap ((compat_th _ _ Hcomp') pfj').2) b ofs Cur.
(** Lifting [corestep_disjoint_val] to [internal_step]*)
Lemma internal_step_disjoint_val :
forall tp tp' m m' i j
(Hneq: i <> j)
(pfi: containsThread tp i)
(pfj: containsThread tp j)
(Hcomp: mem_compatible tp m)
(Hcomp': mem_compatible tp' m')
(Hstep: internal_step pfi Hcomp tp' m') b ofs
(Hreadable:
Mem.perm (restrPermMap ((compat_th _ _ Hcomp) pfj).1)b ofs Cur Readable \/
Mem.perm (restrPermMap ((compat_th _ _ Hcomp) pfj).2) b ofs Cur Readable),
Maps.ZMap.get ofs (Mem.mem_contents m) # b =
Maps.ZMap.get ofs (Mem.mem_contents m') # b.
Lemma internal_exec_disjoint_val :
forall tp tp' m m' i j xs
(Hneq: i <> j)
(pfi: containsThread tp i)
(pfj: containsThread tp j)
(Hcomp: mem_compatible tp m)
(Hstep: internal_execution [seq x <- xs | x == i] tp m tp' m') b ofs
(Hreadable:
Mem.perm (restrPermMap ((compat_th _ _ Hcomp) pfj).1) b ofs Cur Readable \/
Mem.perm (restrPermMap ((compat_th _ _ Hcomp) pfj).2) b ofs Cur Readable),
Maps.ZMap.get ofs (Mem.mem_contents m) # b =
Maps.ZMap.get ofs (Mem.mem_contents m') # b.
(** Locks resources are always disjoint from data resources (even for the same thread)*)
Lemma internal_step_disjoint_locks :
forall tp tp' m m' i j
(pfi: containsThread tp i)
(pfj: containsThread tp j)
(Hcomp: mem_compatible tp m)
(Hcomp': mem_compatible tp' m')
(Hstep: internal_step pfi Hcomp tp' m') b ofs
(Hreadable:
Mem.perm (restrPermMap ((compat_th _ _ Hcomp) pfj).2) b ofs Cur Readable),
Maps.ZMap.get ofs (Mem.mem_contents m) # b =
Maps.ZMap.get ofs (Mem.mem_contents m') # b.
Lemma internal_exec_disjoint_locks:
forall tp tp' m m' i j xs
(pfi: containsThread tp i)
(pfj: containsThread tp j)
(Hcomp: mem_compatible tp m)
(Hstep: internal_execution [seq x <- xs | x == i] tp m tp' m') b ofs
(Hreadable: Mem.perm (restrPermMap ((compat_th _ _ Hcomp) pfj).2) b ofs Cur Readable),
Maps.ZMap.get ofs (Mem.mem_contents m) # b =
Maps.ZMap.get ofs (Mem.mem_contents m') # b.
Lemma internal_step_stable :
forall tp tp' m m' i
(pfi: containsThread tp i)
(Hcomp: mem_compatible tp m)
(Hstep: internal_step pfi Hcomp tp' m')
b ofs
(Hvalid: Mem.valid_block m b)
(Hstable: ~ Mem.perm (restrPermMap ((compat_th _ _ Hcomp) pfi).1) b ofs Cur Writable),
Maps.ZMap.get ofs (Mem.mem_contents m) # b =
Maps.ZMap.get ofs (Mem.mem_contents m') # b.
(** Data resources of a thread that took an internal step are related by [decay]*)
Lemma internal_step_decay:
forall tp m tp' m' i (cnt: containsThread tp i)
(cnt': containsThread tp' i)
(Hcomp: mem_compatible tp m)
(Hcomp': mem_compatible tp' m')
(Hstep: internal_step cnt Hcomp tp' m'),
decay (restrPermMap ((compat_th _ _ Hcomp) cnt).1)
(restrPermMap ((compat_th _ _ Hcomp') cnt').1).
(** [Mem.valid_block] is preserved by [internal_step]*)
Lemma internal_step_valid:
forall tp m tp' m' i (cnt: containsThread tp i)
(Hcomp: mem_compatible tp m)
(Hstep: internal_step cnt Hcomp tp' m') b
(Hvalid: Mem.valid_block m b),
Mem.valid_block m' b.
Lemma internal_execution_valid :
forall tp m tp' m' xs
(Hexec: internal_execution xs tp m tp' m') b
(Hvalid: Mem.valid_block m b),
Mem.valid_block m' b.
Lemma internal_exec_stable:
forall tp tp' m m' i xs
(pfi: containsThread tp i)
(Hcomp: mem_compatible tp m)
(Hstep: internal_execution [seq x <- xs | x == i] tp m tp' m')
b ofs
(Hvalid: Mem.valid_block m b)
(Hstable:  ~ Mem.perm (restrPermMap ((compat_th _ _ Hcomp) pfi).1) b ofs Cur Writable),
Maps.ZMap.get ofs (Mem.mem_contents m) # b =
Maps.ZMap.get ofs (Mem.mem_contents m') # b.
Lemma internal_execution_decay:
forall tp m tp' m' xs i (cnt: containsThread tp i)
(cnt': containsThread tp' i)
(Hcomp: mem_compatible tp m)
(Hcomp': mem_compatible tp' m')
(Hexec: internal_execution [seq x <- xs | x == i] tp m tp' m'),
decay (restrPermMap ((compat_th _ _ Hcomp) cnt).1)
(restrPermMap ((compat_th _ _ Hcomp') cnt').1).
Lemma internal_step_disjoint_val_lockPool :
forall tp tp' m m' i bl ofsl pmap
(pfi: containsThread tp i)
(Hcomp: mem_compatible tp m)
(Hcomp': mem_compatible tp' m')
(Hstep: internal_step pfi Hcomp tp' m') b ofs
(Hl: lockRes tp (bl,ofsl) = Some pmap)
(Hreadable: Mem.perm (restrPermMap ((compat_lp _ _ Hcomp) _ _ Hl).1)
b ofs Cur Readable \/
Mem.perm (restrPermMap ((compat_lp _ _ Hcomp) _ _ Hl).2)
b ofs Cur Readable),
Maps.ZMap.get ofs (Mem.mem_contents m) # b =
Maps.ZMap.get ofs (Mem.mem_contents m') # b.
Lemma internal_exec_disjoint_val_lockPool:
forall (tp tp' : t) (m m' : mem) (i : nat) xs bl ofsl pmap
(Hcomp : mem_compatible tp m)
(Hexec: internal_execution [seq x <- xs | x == i] tp m tp' m')
(Hl: lockRes tp (bl,ofsl) = Some pmap)
b ofs
(Hreadable: Mem.perm (restrPermMap ((compat_lp _ _ Hcomp) _ _ Hl).1)
b ofs Cur Readable \/
Mem.perm (restrPermMap ((compat_lp _ _ Hcomp) _ _ Hl).2)
b ofs Cur Readable),
Maps.ZMap.get ofs (Mem.mem_contents m) # b =
Maps.ZMap.get ofs (Mem.mem_contents m') # b.