Inductive expr_erase : expr W -> expr S' -> Prop :=
| erase_EVal : forall v,
     expr_erase (EVal _ v) (EVal _ v)
| erase_EUnop : forall op e e',
     expr_erase e e'
     -> expr_erase (EUnop op e) (EUnop op e')
| erase_EBinop : forall op e1 e2 e1' e2',
     expr_erase e1 e1'
     -> expr_erase e2 e2'
     -> expr_erase (EBinop op e1 e2) (EBinop op e1' e2')
| erase_EPrim : forall g f,
     GF g f
     -> expr_erase (EPrim g) (EPrim f).Inductive expr_erase : expr W -> expr S' -> Prop :=
| erase_EVal : forall v,
     expr_erase (EVal _ v) (EVal _ v)
| erase_EUnop : forall op e e',
     expr_erase e e'
     -> expr_erase (EUnop op e) (EUnop op e')
| erase_EBinop : forall op e1 e2 e1' e2',
     expr_erase e1 e1'
     -> expr_erase e2 e2'
     -> expr_erase (EBinop op e1 e2) (EBinop op e1' e2')
| erase_EPrim : forall g f,
     GF g f
     -> expr_erase (EPrim g) (EPrim f).Inductive expr_erase : expr W -> expr S' -> Prop :=
| erase_EVal : forall v,
     expr_erase (EVal _ v) (EVal _ v)
| erase_EUnop : forall op e e',
     expr_erase e e'
     -> expr_erase (EUnop op e) (EUnop op e')
| erase_EBinop : forall op e1 e2 e1' e2',
     expr_erase e1 e1'
     -> expr_erase e2 e2'
     -> expr_erase (EBinop op e1 e2) (EBinop op e1' e2')
| erase_EPrim : forall g f,
     GF g f
     -> expr_erase (EPrim g) (EPrim f).Inductive expr_erase : expr W -> expr S' -> Prop :=
| erase_EVal : forall v,
     expr_erase (EVal _ v) (EVal _ v)
| erase_EUnop : forall op e e',
     expr_erase e e'
     -> expr_erase (EUnop op e) (EUnop op e')
| erase_EBinop : forall op e1 e2 e1' e2',
     expr_erase e1 e1'
     -> expr_erase e2 e2'
     -> expr_erase (EBinop op e1 e2) (EBinop op e1' e2')
| erase_EPrim : forall g f,
     GF g f
     -> expr_erase (EPrim g) (EPrim f).Inductive expr_erase : expr W -> expr S' -> Prop :=
| erase_EVal : forall v,
     expr_erase (EVal _ v) (EVal _ v)
| erase_EUnop : forall op e e',
     expr_erase e e'
     -> expr_erase (EUnop op e) (EUnop op e')
| erase_EBinop : forall op e1 e2 e1' e2',
     expr_erase e1 e1'
     -> expr_erase e2 e2'
     -> expr_erase (EBinop op e1 e2) (EBinop op e1' e2')
| erase_EPrim : forall g f,
     GF g f
     -> expr_erase (EPrim g) (EPrim f).

(* Specifications: *)
Lemma expr_erase_pure_expr : forall e e', expr_erase e e' -> pure_expr _ e -> pure_expr _ e'.
Lemma expr_erasure : forall e e' w b1 b2, expr_erase e e' -> exprEval G e w b1 -> exprEval F e' (world_erase w) b2 -> b1=b2.
Lemma expr_safety : forall e e' w b1, expr_erase e e' -> exprEval G e w b1 -> exists b2, exprEval F e' (world_erase w) b2.