End ATOMIC.
(** * Additional results about infinite reduction sequences *)
(** We now show that any infinite sequence of reductions is either of the "reactive" kind or of the "silent" kind (after a finite number of non-silent transitions).  The proof necessitates the axiom of excluded middle.  This result is used below to relate the coinductive big-step semantics for divergence with the small-step notions of divergence. *)
Unset Implicit Arguments.
Section INF_SEQ_DECOMP.
Variable genv: Type.
Variable state: Type.
Variable step: genv -> state -> trace -> state -> Prop.
Variable ge: genv.
Inductive tstate: Type :=
ST: forall (s: state) (T: traceinf), forever step ge s T -> tstate.
Definition state_of_tstate (S: tstate): state :=
match S with ST s T F => s end.
Definition traceinf_of_tstate (S: tstate) : traceinf :=
match S with ST s T F => T end.
Inductive tstep: trace -> tstate -> tstate -> Prop :=
| tstep_intro: forall s1 t T s2 S F,
tstep t (ST s1 (t *** T) (@forever_intro genv state step ge s1 t s2 T S F))
(ST s2 T F).
Inductive tsteps: tstate -> tstate -> Prop :=
| tsteps_refl: forall S, tsteps S S
| tsteps_left: forall t S1 S2 S3, tstep t S1 S2 -> tsteps S2 S3 -> tsteps S1 S3.
Remark tsteps_trans:
forall S1 S2, tsteps S1 S2 -> forall S3, tsteps S2 S3 -> tsteps S1 S3.
Let treactive (S: tstate) : Prop :=
forall S1,
tsteps S S1 ->
exists S2, exists S3, exists t, tsteps S1 S2 /\ tstep t S2 S3 /\ t <> E0.
Let tsilent (S: tstate) : Prop :=
forall S1 t S2, tsteps S S1 -> tstep t S1 S2 -> t = E0.

(* Specifications: *)
Lemma treactive_or_tsilent:
forall S, treactive S \/ (exists S', tsteps S S' /\ tsilent S').
Lemma tsteps_star:
forall S1 S2, tsteps S1 S2 ->
exists t, star step ge (state_of_tstate S1) t (state_of_tstate S2)
/\ traceinf_of_tstate S1 = t *** traceinf_of_tstate S2.
Lemma tsilent_forever_silent:
forall S,
tsilent S -> forever_silent step ge (state_of_tstate S).
Lemma treactive_forever_reactive:
forall S,
treactive S -> forever_reactive step ge (state_of_tstate S) (traceinf_of_tstate S).
Theorem forever_silent_or_reactive:
forall s T,
forever step ge s T ->
forever_reactive step ge s T \/
exists t, exists s', exists T',
star step ge s t s' /\ forever_silent step ge s' /\ T = t *** T'.