(* *********************************************************************)
(*                                                                     *)
(*              The Compcert verified compiler                         *)
(*                                                                     *)
(*          Xavier Leroy, INRIA Paris-Rocquencourt                     *)
(*                                                                     *)
(*  Copyright Institut National de Recherche en Informatique et en     *)
(*  Automatique.  All rights reserved.  This file is distributed       *)
(*  under the terms of the GNU General Public License as published by  *)
(*  the Free Software Foundation, either version 2 of the License, or  *)
(*  (at your option) any later version.  This file is also distributed *)
(*  under the terms of the INRIA Non-Commercial License Agreement.     *)
(*                                                                     *)
(* *********************************************************************)
(** Tools for small-step operational semantics *)
(** This module defines generic operations and theorems over the one-step transition relations that are used to specify operational semantics in small-step style. *)
Set Implicit Arguments.
(** * Closures of transitions relations *)
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.

(* Specifications: *)
Lemma star_one:
forall ge s1 t s2, step ge s1 t s2 -> star ge s1 t s2.
Lemma star_two:
forall ge s1 t1 s2 t2 s3 t,
step ge s1 t1 s2 -> step ge s2 t2 s3 -> t = t1 ** t2 ->
star ge s1 t s3.
Lemma star_three:
forall ge s1 t1 s2 t2 s3 t3 s4 t,
step ge s1 t1 s2 -> step ge s2 t2 s3 -> step ge s3 t3 s4 -> t = t1 ** t2 ** t3 ->
star ge s1 t s4.
Lemma star_four:
forall ge s1 t1 s2 t2 s3 t3 s4 t4 s5 t,
step ge s1 t1 s2 -> step ge s2 t2 s3 ->
step ge s3 t3 s4 -> step ge s4 t4 s5 -> t = t1 ** t2 ** t3 ** t4 ->
star ge s1 t s5.
Lemma star_trans:
forall ge s1 t1 s2, star ge s1 t1 s2 ->
forall t2 s3 t, star ge s2 t2 s3 -> t = t1 ** t2 -> star ge s1 t s3.
Lemma star_left:
forall ge s1 t1 s2 t2 s3 t,
step ge s1 t1 s2 -> star ge s2 t2 s3 -> t = t1 ** t2 ->
star ge s1 t s3.