Section GenericSemanticsElaboration.
Context {W V G} `{GS : GenericSemantics W V G}.
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 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'.
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.
Definition safe w k := forall w'' k'', step_star w k w'' k'' -> immed_safe w'' k''.
Definition config_det w k := forall w' k' w'' k'',
step w k w' k' -> step w k w'' k'' -> w'=w'' /\ k'=k''.

Lemma safe_seq_assoc: forall w k c1 c2,
safe w (Kseq c1 (Kseq c2 k)) -> safe w (Kseq (Sseq c1 c2) k).