Definition blocked_at_external (state : cm_state) (ef : external_function) :=
  match state with
    (m, (tr, sch, tp)) =>
    exists j cntj sch' c args,
      sch = j :: sch' /\
      @getThreadC _ _ _ j tp cntj = Kblocked c /\
      cl_at_external c = Some (ef, args)
  end.Definition state_bupd P (state : cm_state) := let '(m, (tr, sch, tp)) := state in
  tp_bupd (fun tp' => P (m, (tr, sch, tp'))) tp.

Lemma state_inv_upd : forall Gamma (n : nat) (m : mem) (tr : event_trace) (sch : schedule) (tp : jstate ge) (PHI : rmap) (lev : level PHI = n) (envcoh : env_coherence Jspec ge Gamma PHI) (mcompat : mem_compatible_with tp m PHI) (extcompat : joins (ghost_of PHI) (Some (ext_ref tt, NoneP) :: nil)) (lock_sparse : lock_sparsity (lset tp)) (lock_coh : lock_coherence' tp PHI m mcompat) (safety : forall C, join_sub (Some (ext_ref tt, NoneP) :: nil) C -> joins (ghost_of PHI) (ghost_fmap (approx (level PHI)) (approx (level PHI)) C) -> exists tp' PHI' (Hupd : tp_update tp PHI tp' PHI'), joins (ghost_of PHI') (ghost_fmap (approx (level PHI)) (approx (level PHI)) C) /\ threads_safety m tp' PHI' (mem_compatible_upd _ _ _ _ _ mcompat Hupd) n) (wellformed : threads_wellformed tp) (uniqkrun : unique_Krun tp sch), state_bupd (state_invariant Gamma n) (m, (tr, sch, tp)).