Proof using.
pose proof decomposition_invariant.
find_apply_lem_hyp inductive_invariant_true_in_reachable.
unfold true_in_reachable in *.
intros.
apply locks_correct_implies_mutex.
match goal with
| [ H : _ |- _ ] => apply H
end.
auto.
Qed.
Fixpoint last_holder' (holder : option Client_index) (trace : list (name * (input + list output))) : option Client_index :=
match trace with
| [] => holder
| (Client n, inl Unlock) :: tr => match holder with
| None => last_holder' holder tr
| Some m => if fin_eq_dec _ n m
then last_holder' None tr
else last_holder' holder tr
end
| (Client n, inr [Locked]) :: tr => last_holder' (Some n) tr
| (n, _) :: tr => last_holder' holder tr
end.
Fixpoint trace_mutual_exclusion' (holder : option Client_index) (trace : list (name * (input + list output))) : Prop :=
match trace with
| [] => True
| (Client n, (inl Unlock)) :: tr' => match holder with
| Some m => if fin_eq_dec _ n m
then trace_mutual_exclusion' None tr'
else trace_mutual_exclusion' holder tr'
| _ => trace_mutual_exclusion' holder tr'
end
| (n, (inl _)) :: tr' => trace_mutual_exclusion' holder tr'
| (Client n, (inr [Locked])) :: tr' => match holder with
| None => trace_mutual_exclusion' (Some n) tr'
| Some _ => False
end
| (_, (inr [])) :: tr' => trace_mutual_exclusion' holder tr'
| (_, (inr _)) :: tr' => False
end.
Definition trace_mutual_exclusion (trace : list (name * (input + list output))) : Prop :=
trace_mutual_exclusion' None trace.
Definition last_holder (trace : list (name * (input + list output))) : option Client_index :=
last_holder' None trace.

Lemma cross_relation :
forall (P : network -> list (name * (input + list output)) -> Prop),
P step_async_init [] ->
(forall st st' tr ev,
step_async_star step_async_init st tr ->
P st tr ->
step_async st st' ev ->
P st' (tr ++ ev)) ->
forall st tr,
step_async_star step_async_init st tr ->
P st tr.