(* Syntax erasure *)
Inductive stmt_erase : @stmt W -> @stmt S' -> Prop :=
| erase_SPrimcom: forall v u,
     VU v u
     -> stmt_erase (Sprimcom v) (Sprimcom u)
| erase_SSkip: stmt_erase Sskip Sskip
| erase_SSeq: forall c1 c1' c2 c2',
     stmt_erase c1 c1'
     -> stmt_erase c2 c2'
     -> stmt_erase (Sseq c1 c2) (Sseq c1' c2')
| erase_SIfte: forall e e' c1 c2 c1' c2',
     expr_erase GF e e'
     -> stmt_erase c1 c1'
     -> stmt_erase c2 c2'
     -> stmt_erase (Sifte e c1 c2) (Sifte e' c1' c2')
| erase_SWhile: forall e e' c c',
     expr_erase GF e e'
     -> stmt_erase c c'
     -> stmt_erase (Swhile e c) (Swhile e' c').(* Syntax erasure *)
Inductive stmt_erase : @stmt W -> @stmt S' -> Prop :=
| erase_SPrimcom: forall v u,
     VU v u
     -> stmt_erase (Sprimcom v) (Sprimcom u)
| erase_SSkip: stmt_erase Sskip Sskip
| erase_SSeq: forall c1 c1' c2 c2',
     stmt_erase c1 c1'
     -> stmt_erase c2 c2'
     -> stmt_erase (Sseq c1 c2) (Sseq c1' c2')
| erase_SIfte: forall e e' c1 c2 c1' c2',
     expr_erase GF e e'
     -> stmt_erase c1 c1'
     -> stmt_erase c2 c2'
     -> stmt_erase (Sifte e c1 c2) (Sifte e' c1' c2')
| erase_SWhile: forall e e' c c',
     expr_erase GF e e'
     -> stmt_erase c c'
     -> stmt_erase (Swhile e c) (Swhile e' c').(* Syntax erasure *)
Inductive stmt_erase : @stmt W -> @stmt S' -> Prop :=
| erase_SPrimcom: forall v u,
     VU v u
     -> stmt_erase (Sprimcom v) (Sprimcom u)
| erase_SSkip: stmt_erase Sskip Sskip
| erase_SSeq: forall c1 c1' c2 c2',
     stmt_erase c1 c1'
     -> stmt_erase c2 c2'
     -> stmt_erase (Sseq c1 c2) (Sseq c1' c2')
| erase_SIfte: forall e e' c1 c2 c1' c2',
     expr_erase GF e e'
     -> stmt_erase c1 c1'
     -> stmt_erase c2 c2'
     -> stmt_erase (Sifte e c1 c2) (Sifte e' c1' c2')
| erase_SWhile: forall e e' c c',
     expr_erase GF e e'
     -> stmt_erase c c'
     -> stmt_erase (Swhile e c) (Swhile e' c').(* Syntax erasure *)
Inductive stmt_erase : @stmt W -> @stmt S' -> Prop :=
| erase_SPrimcom: forall v u,
     VU v u
     -> stmt_erase (Sprimcom v) (Sprimcom u)
| erase_SSkip: stmt_erase Sskip Sskip
| erase_SSeq: forall c1 c1' c2 c2',
     stmt_erase c1 c1'
     -> stmt_erase c2 c2'
     -> stmt_erase (Sseq c1 c2) (Sseq c1' c2')
| erase_SIfte: forall e e' c1 c2 c1' c2',
     expr_erase GF e e'
     -> stmt_erase c1 c1'
     -> stmt_erase c2 c2'
     -> stmt_erase (Sifte e c1 c2) (Sifte e' c1' c2')
| erase_SWhile: forall e e' c c',
     expr_erase GF e e'
     -> stmt_erase c c'
     -> stmt_erase (Swhile e c) (Swhile e' c').(* Syntax erasure *)
Inductive stmt_erase : @stmt W -> @stmt S' -> Prop :=
| erase_SPrimcom: forall v u,
     VU v u
     -> stmt_erase (Sprimcom v) (Sprimcom u)
| erase_SSkip: stmt_erase Sskip Sskip
| erase_SSeq: forall c1 c1' c2 c2',
     stmt_erase c1 c1'
     -> stmt_erase c2 c2'
     -> stmt_erase (Sseq c1 c2) (Sseq c1' c2')
| erase_SIfte: forall e e' c1 c2 c1' c2',
     expr_erase GF e e'
     -> stmt_erase c1 c1'
     -> stmt_erase c2 c2'
     -> stmt_erase (Sifte e c1 c2) (Sifte e' c1' c2')
| erase_SWhile: forall e e' c c',
     expr_erase GF e e'
     -> stmt_erase c c'
     -> stmt_erase (Swhile e c) (Swhile e' c').(* Syntax erasure *)
Inductive stmt_erase : @stmt W -> @stmt S' -> Prop :=
| erase_SPrimcom: forall v u,
     VU v u
     -> stmt_erase (Sprimcom v) (Sprimcom u)
| erase_SSkip: stmt_erase Sskip Sskip
| erase_SSeq: forall c1 c1' c2 c2',
     stmt_erase c1 c1'
     -> stmt_erase c2 c2'
     -> stmt_erase (Sseq c1 c2) (Sseq c1' c2')
| erase_SIfte: forall e e' c1 c2 c1' c2',
     expr_erase GF e e'
     -> stmt_erase c1 c1'
     -> stmt_erase c2 c2'
     -> stmt_erase (Sifte e c1 c2) (Sifte e' c1' c2')
| erase_SWhile: forall e e' c c',
     expr_erase GF e e'
     -> stmt_erase c c'
     -> stmt_erase (Swhile e c) (Swhile e' c').Inductive ctl_erase : @ctl W -> @ctl S' -> Prop :=
| erase_KStop: ctl_erase Kstop Kstop
| erase_KSeq: forall c c' k k',
     stmt_erase c c'
     -> ctl_erase k k'
     -> ctl_erase (Kseq c k) (Kseq c' k').Inductive ctl_erase : @ctl W -> @ctl S' -> Prop :=
| erase_KStop: ctl_erase Kstop Kstop
| erase_KSeq: forall c c' k k',
     stmt_erase c c'
     -> ctl_erase k k'
     -> ctl_erase (Kseq c k) (Kseq c' k').Inductive ctl_erase : @ctl W -> @ctl S' -> Prop :=
| erase_KStop: ctl_erase Kstop Kstop
| erase_KSeq: forall c c' k k',
     stmt_erase c c'
     -> ctl_erase k k'
     -> ctl_erase (Kseq c k) (Kseq c' k').

(* Specifications: *)
Lemma stratified_expr_erasure : forall e e' w b1 b2, expr_erase GF e e' -> exprEval G e w b1 -> exprEval F e' (world_erase w) b2 -> b1=b2.
Lemma stratified_expr_safety : forall e e' w b1, expr_erase GF e e' -> exprEval G e w b1 -> exists b2, exprEval F e' (world_erase w) b2.
Lemma step_erasure : forall (w w': W) (s s': S') k_w k_w' k_s k_s', world_erase w = s -> ctl_erase k_w k_s -> @step _ V G w k_w w' k_w' -> @step _ U F s k_s s' k_s' -> world_erase w' = s' /\ ctl_erase k_w' k_s'.
Lemma step_safety : forall w w' s k_w k_w' k_s, world_erase w = s -> ctl_erase k_w k_s -> @step _ V G w k_w w' k_w' -> exists s', exists k_s', @step _ U F s k_s s' k_s'.
Lemma step_star_erasure : forall w w' s k_w k_w' k_s, world_erase w = s -> ctl_erase k_w k_s -> @step_star _ V G w k_w w' k_w' -> exists s', exists k_s', @step_star _ U F s k_s s' k_s' /\ world_erase w' = s' /\ ctl_erase k_w' k_s'.