Inductive stmt : Type :=
| Sprimcom: forall (u: relation W), stmt
| Sskip
| Sseq: forall (s1 s2: stmt), stmt
| Sifte: forall (e: expr W) (s1 s2: stmt), stmt
| Swhile: forall (e: expr W) (s: stmt), stmt.Inductive stmt : Type :=
| Sprimcom: forall (u: relation W), stmt
| Sskip
| Sseq: forall (s1 s2: stmt), stmt
| Sifte: forall (e: expr W) (s1 s2: stmt), stmt
| Swhile: forall (e: expr W) (s: stmt), stmt.Inductive stmt : Type :=
| Sprimcom: forall (u: relation W), stmt
| Sskip
| Sseq: forall (s1 s2: stmt), stmt
| Sifte: forall (e: expr W) (s1 s2: stmt), stmt
| Swhile: forall (e: expr W) (s: stmt), stmt.Inductive stmt : Type :=
| Sprimcom: forall (u: relation W), stmt
| Sskip
| Sseq: forall (s1 s2: stmt), stmt
| Sifte: forall (e: expr W) (s1 s2: stmt), stmt
| Swhile: forall (e: expr W) (s: stmt), stmt.Inductive stmt : Type :=
| Sprimcom: forall (u: relation W), stmt
| Sskip
| Sseq: forall (s1 s2: stmt), stmt
| Sifte: forall (e: expr W) (s1 s2: stmt), stmt
| Swhile: forall (e: expr W) (s: stmt), stmt.Inductive stmt : Type :=
| Sprimcom: forall (u: relation W), stmt
| Sskip
| Sseq: forall (s1 s2: stmt), stmt
| Sifte: forall (e: expr W) (s1 s2: stmt), stmt
| Swhile: forall (e: expr W) (s: stmt), stmt.Inductive ctl : Type := Kstop | Kseq: forall (s: stmt) (k: ctl), ctl.Inductive ctl : Type := Kstop | Kseq: forall (s: stmt) (k: ctl), ctl.Inductive ctl : Type := Kstop | Kseq: forall (s: stmt) (k: ctl), ctl.Inductive step : W -> ctl -> W -> ctl -> Prop :=
| step_Sprimcom: forall v (w w': W) (k: ctl),
     V v
     -> v w w'
     -> step w (Kseq (Sprimcom v) k) w' k
| step_Sskip: forall w (k: ctl),
     step w (Kseq Sskip k) w k
| step_Sseq: forall (s1 s2: stmt) w (k: ctl),
     step w (Kseq (Sseq s1 s2) k) w (Kseq s1 (Kseq s2 k))
| step_Sifte_true: forall (e: expr W) (v: val) (s1 s2: stmt) (w: W) (k: ctl),
     exprEval G e w v
     -> is_true v
     -> step w (Kseq (Sifte e s1 s2) k) w (Kseq s1 k)
| step_Sifte_false: forall (e: expr W) (v: val) (s1 s2: stmt) (w: W) (k: ctl),
     exprEval G e w v
     -> ~is_true v
     -> step w (Kseq (Sifte e s1 s2) k) w (Kseq s2 k)
| step_Swhile: forall (s: stmt) e w (k: ctl),
     step w (Kseq (Swhile e s) k)
          w (Kseq (Sifte e (Sseq s (Swhile e s)) Sskip) k).Inductive step : W -> ctl -> W -> ctl -> Prop :=
| step_Sprimcom: forall v (w w': W) (k: ctl),
     V v
     -> v w w'
     -> step w (Kseq (Sprimcom v) k) w' k
| step_Sskip: forall w (k: ctl),
     step w (Kseq Sskip k) w k
| step_Sseq: forall (s1 s2: stmt) w (k: ctl),
     step w (Kseq (Sseq s1 s2) k) w (Kseq s1 (Kseq s2 k))
| step_Sifte_true: forall (e: expr W) (v: val) (s1 s2: stmt) (w: W) (k: ctl),
     exprEval G e w v
     -> is_true v
     -> step w (Kseq (Sifte e s1 s2) k) w (Kseq s1 k)
| step_Sifte_false: forall (e: expr W) (v: val) (s1 s2: stmt) (w: W) (k: ctl),
     exprEval G e w v
     -> ~is_true v
     -> step w (Kseq (Sifte e s1 s2) k) w (Kseq s2 k)
| step_Swhile: forall (s: stmt) e w (k: ctl),
     step w (Kseq (Swhile e s) k)
          w (Kseq (Sifte e (Sseq s (Swhile e s)) Sskip) k).Inductive step : W -> ctl -> W -> ctl -> Prop :=
| step_Sprimcom: forall v (w w': W) (k: ctl),
     V v
     -> v w w'
     -> step w (Kseq (Sprimcom v) k) w' k
| step_Sskip: forall w (k: ctl),
     step w (Kseq Sskip k) w k
| step_Sseq: forall (s1 s2: stmt) w (k: ctl),
     step w (Kseq (Sseq s1 s2) k) w (Kseq s1 (Kseq s2 k))
| step_Sifte_true: forall (e: expr W) (v: val) (s1 s2: stmt) (w: W) (k: ctl),
     exprEval G e w v
     -> is_true v
     -> step w (Kseq (Sifte e s1 s2) k) w (Kseq s1 k)
| step_Sifte_false: forall (e: expr W) (v: val) (s1 s2: stmt) (w: W) (k: ctl),
     exprEval G e w v
     -> ~is_true v
     -> step w (Kseq (Sifte e s1 s2) k) w (Kseq s2 k)
| step_Swhile: forall (s: stmt) e w (k: ctl),
     step w (Kseq (Swhile e s) k)
          w (Kseq (Sifte e (Sseq s (Swhile e s)) Sskip) k).Inductive step : W -> ctl -> W -> ctl -> Prop :=
| step_Sprimcom: forall v (w w': W) (k: ctl),
     V v
     -> v w w'
     -> step w (Kseq (Sprimcom v) k) w' k
| step_Sskip: forall w (k: ctl),
     step w (Kseq Sskip k) w k
| step_Sseq: forall (s1 s2: stmt) w (k: ctl),
     step w (Kseq (Sseq s1 s2) k) w (Kseq s1 (Kseq s2 k))
| step_Sifte_true: forall (e: expr W) (v: val) (s1 s2: stmt) (w: W) (k: ctl),
     exprEval G e w v
     -> is_true v
     -> step w (Kseq (Sifte e s1 s2) k) w (Kseq s1 k)
| step_Sifte_false: forall (e: expr W) (v: val) (s1 s2: stmt) (w: W) (k: ctl),
     exprEval G e w v
     -> ~is_true v
     -> step w (Kseq (Sifte e s1 s2) k) w (Kseq s2 k)
| step_Swhile: forall (s: stmt) e w (k: ctl),
     step w (Kseq (Swhile e s) k)
          w (Kseq (Sifte e (Sseq s (Swhile e s)) Sskip) k).Inductive step : W -> ctl -> W -> ctl -> Prop :=
| step_Sprimcom: forall v (w w': W) (k: ctl),
     V v
     -> v w w'
     -> step w (Kseq (Sprimcom v) k) w' k
| step_Sskip: forall w (k: ctl),
     step w (Kseq Sskip k) w k
| step_Sseq: forall (s1 s2: stmt) w (k: ctl),
     step w (Kseq (Sseq s1 s2) k) w (Kseq s1 (Kseq s2 k))
| step_Sifte_true: forall (e: expr W) (v: val) (s1 s2: stmt) (w: W) (k: ctl),
     exprEval G e w v
     -> is_true v
     -> step w (Kseq (Sifte e s1 s2) k) w (Kseq s1 k)
| step_Sifte_false: forall (e: expr W) (v: val) (s1 s2: stmt) (w: W) (k: ctl),
     exprEval G e w v
     -> ~is_true v
     -> step w (Kseq (Sifte e s1 s2) k) w (Kseq s2 k)
| step_Swhile: forall (s: stmt) e w (k: ctl),
     step w (Kseq (Swhile e s) k)
          w (Kseq (Sifte e (Sseq s (Swhile e s)) Sskip) k).Inductive step : W -> ctl -> W -> ctl -> Prop :=
| step_Sprimcom: forall v (w w': W) (k: ctl),
     V v
     -> v w w'
     -> step w (Kseq (Sprimcom v) k) w' k
| step_Sskip: forall w (k: ctl),
     step w (Kseq Sskip k) w k
| step_Sseq: forall (s1 s2: stmt) w (k: ctl),
     step w (Kseq (Sseq s1 s2) k) w (Kseq s1 (Kseq s2 k))
| step_Sifte_true: forall (e: expr W) (v: val) (s1 s2: stmt) (w: W) (k: ctl),
     exprEval G e w v
     -> is_true v
     -> step w (Kseq (Sifte e s1 s2) k) w (Kseq s1 k)
| step_Sifte_false: forall (e: expr W) (v: val) (s1 s2: stmt) (w: W) (k: ctl),
     exprEval G e w v
     -> ~is_true v
     -> step w (Kseq (Sifte e s1 s2) k) w (Kseq s2 k)
| step_Swhile: forall (s: stmt) e w (k: ctl),
     step w (Kseq (Swhile e s) k)
          w (Kseq (Sifte e (Sseq s (Swhile e s)) Sskip) k).Inductive step : W -> ctl -> W -> ctl -> Prop :=
| step_Sprimcom: forall v (w w': W) (k: ctl),
     V v
     -> v w w'
     -> step w (Kseq (Sprimcom v) k) w' k
| step_Sskip: forall w (k: ctl),
     step w (Kseq Sskip k) w k
| step_Sseq: forall (s1 s2: stmt) w (k: ctl),
     step w (Kseq (Sseq s1 s2) k) w (Kseq s1 (Kseq s2 k))
| step_Sifte_true: forall (e: expr W) (v: val) (s1 s2: stmt) (w: W) (k: ctl),
     exprEval G e w v
     -> is_true v
     -> step w (Kseq (Sifte e s1 s2) k) w (Kseq s1 k)
| step_Sifte_false: forall (e: expr W) (v: val) (s1 s2: stmt) (w: W) (k: ctl),
     exprEval G e w v
     -> ~is_true v
     -> step w (Kseq (Sifte e s1 s2) k) w (Kseq s2 k)
| step_Swhile: forall (s: stmt) e w (k: ctl),
     step w (Kseq (Swhile e s) k)
          w (Kseq (Sifte e (Sseq s (Swhile e s)) Sskip) k).(* The usual closures and definition of safety *)
Inductive step_star : W -> ctl -> W -> ctl -> Prop :=
| step_star0: forall w k, step_star w k w k
| step_starN: forall w k w'' k'' w' k', step w k w'' k'' -> step_star w'' k'' w' k'
     -> step_star w k w' k'.(* The usual closures and definition of safety *)
Inductive step_star : W -> ctl -> W -> ctl -> Prop :=
| step_star0: forall w k, step_star w k w k
| step_starN: forall w k w'' k'' w' k', step w k w'' k'' -> step_star w'' k'' w' k'
     -> step_star w k w' k'.(* The usual closures and definition of safety *)
Inductive step_star : W -> ctl -> W -> ctl -> Prop :=
| step_star0: forall w k, step_star w k w k
| step_starN: forall w k w'' k'' w' k', step w k w'' k'' -> step_star w'' k'' w' k'
     -> step_star w k w' k'.Inductive stepN : nat -> W -> ctl -> W -> ctl -> Prop :=
| stepN_0: forall w k, stepN O w k w k
| stepN_S: forall n w k w' k' w'' k'',
     step w k w' k'
     -> stepN n w' k' w'' k''
     -> stepN (S n) w k w'' k''.Inductive stepN : nat -> W -> ctl -> W -> ctl -> Prop :=
| stepN_0: forall w k, stepN O w k w k
| stepN_S: forall n w k w' k' w'' k'',
     step w k w' k'
     -> stepN n w' k' w'' k''
     -> stepN (S n) w k w'' k''.Inductive stepN : nat -> W -> ctl -> W -> ctl -> Prop :=
| stepN_0: forall w k, stepN O w k w k
| stepN_S: forall n w k w' k' w'' k'',
     step w k w' k'
     -> stepN n w' k' w'' k''
     -> stepN (S n) w k w'' k''.Inductive immed_safe : W -> ctl -> Prop :=
| immed_safe0: forall w,
     immed_safe w Kstop
| immed_safe1: forall w k w' k',
     step w k w' k'
     -> immed_safe w k.Inductive immed_safe : W -> ctl -> Prop :=
| immed_safe0: forall w,
     immed_safe w Kstop
| immed_safe1: forall w k w' k',
     step w k w' k'
     -> immed_safe w k.Inductive immed_safe : W -> ctl -> Prop :=
| immed_safe0: forall w,
     immed_safe w Kstop
| immed_safe1: forall w k w' k',
     step w k w' k'
     -> immed_safe w k.Definition safe w k := forall w'' k'', step_star w k w'' k'' -> immed_safe w'' k''.

(* Specifications: *)
Lemma step_step_star : forall w k w' k', step w k w' k' -> step_star w k w' k'.
Lemma step_star_trans : forall w k w'' k'' w' k', step_star w k w'' k'' -> step_star w'' k'' w' k' -> step_star w k w' k'.
Lemma step_star_stepN : forall w k w'' k'', step_star w k w'' k'' <-> exists n, stepN n w k w'' k''.
Lemma step_nprimcom_det : forall w k w' k' w'' k'', (forall u k', k <> Kseq (Sprimcom u) k') -> step w k w' k' -> step w k w'' k'' -> w'=w'' /\ k'=k''.
Lemma step_safe : forall w k w' k', safe w k -> step w k w' k' -> safe w' k'.