(* SUBSTITUTION *)

(* Specifications: *)
Lemma closed'_S : forall n e,
closed' n e ->
closed' (S n) e.
Lemma closed'_le : forall m n,
m <= n ->
forall e,
closed' m e ->
closed' n e.
Lemma closed'_subst: forall m e x v,
closed' m e ->
subst (x + m) v e = e.
Lemma closed_closed_subst: forall x v e,
closed e ->
closed (subst x v e).
Lemma closed_Lam_subst: forall e x v,
closed (Lam e) ->
subst x v (Lam e) = Lam e.
Lemma subst_env'_Nat: forall rho m n,
subst_env' m rho (Nat n) = Nat n.
Lemma subst_env'_Loc: forall rho m l,
subst_env' m rho (Loc l) = Loc l.
Lemma subst_env'_Var': forall n m rho,
subst_env' (S (n + m)) rho (Var n) = Var n.
Lemma subst_env'_Var: forall rho n v m,
nth_error rho n = Some v ->
subst_env' m rho (Var (n + m)) = val_to_exp v.
Lemma subst_env'_New: forall rho m e,
subst_env' m rho (New e) = New (subst_env' m rho e).
Lemma subst_env'_Deref: forall rho m e,
subst_env' m rho (Deref e) = Deref (subst_env' m rho e).
Lemma subst_env'_Update: forall rho m e1 e2 e3,
subst_env' m rho (Update e1 e2 e3) =
Update (subst_env' m rho e1) (subst_env' m rho e2) (subst_env' m rho e3).
Lemma subst_env_New: forall rho e,
subst_env rho (New e) = New (subst_env rho e).
Lemma subst_env_Deref: forall rho e,
subst_env rho (Deref e) = Deref (subst_env rho e).
Lemma subst_env_Update: forall rho e1 e2 e3,
subst_env rho (Update e1 e2 e3) =
Update (subst_env rho e1) (subst_env rho e2) (subst_env rho e3).
Lemma subst_env_App : forall env e1 e2,
subst_env env (App e1 e2) = App (subst_env env e1) (subst_env env e2).
Lemma subst_env_Prim : forall env f e,
subst_env env (Prim f e) = Prim f (subst_env env e).
Lemma subst_subst_neq : forall e n m v1 v2,
n <> m ->
subst n v1 (subst m v2 e) =
subst m v2 (subst n v1 e).
Lemma subst_env_split : forall env1 env2 n e,
subst_env' n (env1 ++ env2) e =
subst_env' n env1 (subst_env' (length env1 + n) env2 e).
Lemma subst_subst_env_lt : forall env n m v e,
n < m ->
subst n v (subst_env' m env e) =
subst_env' m env (subst n v e).