End juicy.
(*+ Final instantiation *)
Record CSL_proof := {
CSL_prog : Clight.program;
CSL_CS: compspecs;
CSL_V : varspecs;
CSL_G : funspecs;
CSL_ext_link : string -> ident;
CSL_ext_link_inj : forall s1 s2, CSL_ext_link s1 = CSL_ext_link s2 -> s1 = s2;
CSL_all_safe : semax_prog.semax_prog (Concurrent_Espec unit CSL_CS CSL_ext_link)
CSL_prog CSL_V CSL_G;
CSL_init_mem_not_none : Genv.init_mem CSL_prog <> None;
}.
Section Safety.
Variable CPROOF: CSL_proof.
Definition CS :=   CPROOF.(CSL_CS).
Definition V :=   CPROOF.(CSL_V).
Definition G :=   CPROOF.(CSL_G).
Definition ext_link :=   CPROOF.(CSL_ext_link).
Definition ext_link_inj :=   CPROOF.(CSL_ext_link_inj).
Definition prog :=   CPROOF.(CSL_prog).
Definition all_safe :=   CPROOF.(CSL_all_safe).
Definition init_mem_not_none :=   CPROOF.(CSL_init_mem_not_none).
Definition Jspec' := (@OK_spec (Concurrent_Espec unit CS ext_link)).
(* another, looser invariant to have more standard preservation statement *)
Definition inv Gamma n state :=
exists m, (n <= m)%nat /\ state_invariant(ge := globalenv prog) Jspec' Gamma m state.

(* Specifications: *)
Lemma inv_sch_irr Gamma n m i tr sch sch' tp :
inv Gamma n (m, (tr, i :: sch, tp)) ->
inv Gamma n (m, (tr, i :: sch', tp)).
Lemma no_Krun_inv Gamma n m tr sch sch' tp :
(1 < pos.n (num_threads tp) -> no_Krun tp)%nat ->
inv Gamma n (m, (tr, sch, tp)) ->
inv Gamma n (m, (tr, sch', tp)).
Lemma blocked_at_external_dec state ef : {blocked_at_external state ef} + {~blocked_at_external(ge := globalenv prog) state ef}.
Lemma safety_bupd : forall state n Gamma, (exists state', state_step state state' /\
(state_invariant Jspec' Gamma n state' \/ state_invariant Jspec' Gamma (S n) state')) ->
exists state',
state_step(ge := globalenv prog) state state' /\
(state_bupd (state_invariant Jspec' Gamma n) state' \/
state_bupd (state_invariant Jspec' Gamma (S n)) state').
Theorem safety_induction Gamma n state :
state_invariant Jspec' Gamma (S n) state ->
exists state',
state_step(ge := globalenv prog) state state' /\
(state_bupd (state_invariant Jspec' Gamma n) state' \/
state_bupd (state_invariant Jspec' Gamma (S n)) state').
Lemma tp_bupd_mono : forall (P Q : jstate (globalenv prog) -> Prop) tp,
(forall phi tp' phi', tp_update tp phi tp' phi' ->
P tp' -> Q tp') ->
tp_bupd P tp -> tp_bupd Q tp.
Lemma inv_step Gamma n state :
inv Gamma (S n) state ->
exists state',
state_step state state' /\
state_bupd (inv Gamma n) state'.
Lemma num_tp_update : forall tp tp' phi phi', tp_update(ge := globalenv prog) tp phi tp' phi' ->
num_threads tp' = num_threads tp.
Lemma no_Krun_stable_update tp tp' phi phi' : no_Krun tp -> tp_update tp phi tp' phi' ->
no_Krun(ge := globalenv prog) tp'.
Lemma invariant_safe Gamma n state :
inv Gamma n state -> jmsafe (globalenv prog) n state.