(* This program is free software; you can redistribute it and/or      *)
(* modify it under the terms of the GNU Lesser General Public License *)
(* as published by the Free Software Foundation; either version 2.1   *)
(* of the License, or (at your option) any later version.             *)
(*                                                                    *)
(* This program is distributed in the hope that it will be useful,    *)
(* but WITHOUT ANY WARRANTY; without even the implied warranty of     *)
(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      *)
(* GNU General Public License for more details.                       *)
(*                                                                    *)
(* You should have received a copy of the GNU Lesser General Public   *)
(* License along with this program; if not, write to the Free         *)
(* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *)
(* 02110-1301 USA                                                     *)
(* Contribution to the Coq Library   V6.3 (July 1999)                    *)
(****************************************************************************)
(*                 The Calculus of Inductive Constructions                  *)
(*                                                                          *)
(*                                Projet Coq                                *)
(*                                                                          *)
(*                     INRIA                        ENS-CNRS                *)
(*              Rocquencourt                        Lyon                    *)
(*                                                                          *)
(*                                Coq V5.10                                 *)
(*                              Nov 25th 1994                               *)
(*                                                                          *)
(****************************************************************************)
(****************************************************************************)
(*                              Substitution.v                              *)
(*                                                                          *)
(*                                Gerard Huet                               *)
(*                                                                          *)
(****************************************************************************)
(* Developed in V5.8  January 1993                                          *)
(* Ported    to V5.10 January 1995                                          *)
(****************************************************************************)
(****************************)
(*  Substitution of redexes *)
(****************************)
(* Similar to lift_rec of Terms *)
Fixpoint lift_rec_r (L : redexes) : nat -> nat -> redexes :=
fun k n : nat =>
match L with
| Var i => Var (relocate i k n)
| Fun M => Fun (lift_rec_r M (S k) n)
| Ap b M N => Ap b (lift_rec_r M k n) (lift_rec_r N k n)
end.
Definition lift_r (n : nat) (N : redexes) := lift_rec_r N 0 n.
Definition insert_Var (N : redexes) (i k : nat) :=
match compare k i with
(* k<i *) | inleft (left _) => Var (pred i) (* k=i *) | inleft _ => lift_r k N (* k>i *) | _ => Var i end.  (* Similar to subst_rec of Terms *)
Fixpoint subst_rec_r (L : redexes) : redexes -> nat -> redexes :=
fun (N : redexes) (k : nat) =>
match L with
| Var i => insert_Var N i k
| Fun M => Fun (subst_rec_r M N (S k))
| Ap b M M' => Ap b (subst_rec_r M N k) (subst_rec_r M' N k)
end.
Definition subst_r (N M : redexes) := subst_rec_r M N 0.
(* Lifting lemmas *)
(* The three cases of substitution of U for (Var n) *)
(* Substitution lemma *)

Lemma subst_rec_lift_rec :
forall (U V : redexes) (p q n : nat),
q <= p + n ->
n <= q -> subst_rec_r (lift_rec_r U n (S p)) V q = lift_rec_r U n p.