Section CLOSURES.
Variable genv: Type.
Variable state: Type.
(** A one-step transition relation has the following signature. It is parameterized by a global environment, which does not change during the transition.  It relates the initial state of the transition with its final state.  The [trace] parameter captures the observable events possibly generated during the transition. *)
Variable step: genv -> state -> trace -> state -> Prop.
(** No transitions: stuck state *)
Definition nostep (ge: genv) (s: state) : Prop :=
forall t s', ~(step ge s t s').
(** Zero, one or several transitions.  Also known as Kleene closure, or reflexive transitive closure. *)
Inductive star (ge: genv): state -> trace -> state -> Prop :=
| star_refl: forall s,
star ge s E0 s
| star_step: forall s1 t1 s2 t2 s3 t,
step ge s1 t1 s2 -> star ge s2 t2 s3 -> t = t1 ** t2 ->
star ge s1 t s3.
Proof star_step.
(** One or several transitions.  Also known as the transitive closure. *)
Inductive plus (ge: genv): state -> trace -> state -> Prop :=
| plus_left: forall s1 t1 s2 t2 s3 t,
step ge s1 t1 s2 -> star ge s2 t2 s3 -> t = t1 ** t2 ->
plus ge s1 t s3.
(** Counted sequences of transitions *)
Inductive starN (ge: genv): nat -> state -> trace -> state -> Prop :=
| starN_refl: forall s,
starN ge O s E0 s
| starN_step: forall n s t t1 s' t2 s'',
step ge s t1 s' -> starN ge n s' t2 s'' -> t = t1 ** t2 ->
starN ge (S n) s t s''.
Remark starN_star:
forall ge n s t s', starN ge n s t s' -> star ge s t s'.
Remark star_starN:
forall ge s t s', star ge s t s' -> exists n, starN ge n s t s'.
(** Infinitely many transitions *)
CoInductive forever (ge: genv): state -> traceinf -> Prop :=
| forever_intro: forall s1 t s2 T,
step ge s1 t s2 -> forever ge s2 T ->
forever ge s1 (t *** T).

Lemma star_forever:
forall ge s1 t s2, star ge s1 t s2 ->
forall T, forever ge s2 T ->
forever ge s1 (t *** T).