Definition injclosed (P : Event.t -> Prop) :=
  forall vals1 vals2 orv1 orv2 m1 m2 m1' m2' j j',
  P (Event.mk m1 m1' vals1 orv1) ->
  Mem.inject (as_inj j) m1 m2 ->
  val_list_inject (as_inj j) vals1 vals2 ->
  Mem.inject (as_inj j') m1' m2' ->
  oval_inject (as_inj j') orv1 orv2 ->
  P (Event.mk m2 m2' vals2 orv2).Definition tracepred := list (Event.t -> Prop).Fixpoint tracepred_injclosed (Ps : tracepred) :=
  match Ps with
    | nil => True
    | P :: Ps' => injclosed P /\ tracepred_injclosed Ps'
  end.Fixpoint app_tracepred (Ps : tracepred) (tr : list Event.t) :=
  match Ps, tr with
    | P :: Ps', ev :: tr' => P ev /\ app_tracepred Ps' tr'
    | _, _ => True
  end.

(* Specifications: *)
Lemma app_match_trace (Ps : tracepred) tr tr' : tracepred_injclosed Ps -> match_trace tr tr' -> app_tracepred Ps tr -> app_tracepred Ps tr'.
Lemma corollary c d m tm cd j Ps z : (* trace semantics source configuration <z,nil,c> is safe *) (forall n, safeN tr_source geS n (z,nil,c) m) -> (* matching configurations: <c,m> ~j <d,tm> *) match_state cd j c m d tm -> (* P closed under ~EVENT *) tracepred_injclosed Ps -> (* <c,m> --tr-->* <c',m'> /\ tr |- Ps *) (forall c' m' z' tr, corestep_star tr_source geS (z,nil,c) m (z',tr,c') m' -> app_tracepred Ps tr) -> (* \forall d' tm' tr'. <d,tm> --tr'-->* <d',tm'> ==> tr' |- Ps *) forall d' tm' z' tr', corestep_star tr_target geT (z,nil,d) tm (z',tr',d') tm' -> app_tracepred Ps tr'.