(** This file is part of the Coquelicot formalization of real analysis in Coq: http://coquelicot.saclay.inria.fr/  Copyright (C) 2011-2015 Sylvie Boldo #<br /># Copyright (C) 2011-2015 Catherine Lelay #<br /># Copyright (C) 2011-2015 Guillaume Melquiond  This library 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 3 of the License, or (at your option) any later version.  This library 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 COPYING file for more details. *)
(** * Reflective tactic for solving goals of the form [derivable_pt_lim] *)
Fixpoint Rn n T :=
match n with
| O => T
| S n => R -> Rn n T
end.
Inductive bop :=
| Eplus
| Emult.
Inductive uop :=
| Eopp
| Einv
| Efct : forall (f f' : R -> R), (forall x, is_derive f x (f' x)) -> uop
| Efct' : forall (f f' : R -> R) (df : R -> Prop), (forall x, df x -> is_derive f x (f' x)) -> uop.
Inductive expr :=
| Var : nat -> expr
| AppExt : forall k, Rn k R -> seq expr -> expr
| AppExtD : forall k, Rn k R -> nat -> seq expr -> expr
| App : expr -> expr -> expr
| Subst : expr -> expr -> expr
| Cst : R -> expr
| Binary : bop -> expr -> expr -> expr
| Unary : uop -> expr -> expr
| Int : expr -> expr -> expr -> expr.
Section ExprInduction.
Hypothesis P : expr -> Prop.
Hypothesis P_Var : forall n, P (Var n).
Hypothesis P_AppExt : forall k f le, foldr (fun e acc  => P e /\ acc) True le -> P (AppExt k f le).
Hypothesis P_AppExtD : forall k f n le, foldr (fun e acc  => P e /\ acc) True le -> P (AppExtD k f n le).
Hypothesis P_App : forall e1 e2, P e1 -> P e2 -> P (App e1 e2).
Hypothesis P_Subst : forall e1 e2, P e1 -> P e2 -> P (Subst e1 e2).
Hypothesis P_Cst : forall r, P (Cst r).
Hypothesis P_Binary : forall o e1 e2, P e1 -> P e2 -> P (Binary o e1 e2).
Hypothesis P_Unary : forall o e, P e -> P (Unary o e).
Hypothesis P_Int : forall f e1 e2, P f -> P e1 -> P e2 -> P (Int f e1 e2).
Fixpoint expr_ind' (e : expr) : P e :=
match e return P e with
| Var n => P_Var n
| AppExt k f le => P_AppExt k f le
((fix expr_ind'' (le : seq expr) : foldr (fun e acc => P e /\ acc) True le :=
match le return foldr (fun e acc => P e /\ acc) True le with
| nil => I
| cons h q => conj (expr_ind' h) (expr_ind'' q)
end) le)
| AppExtD k f n le => P_AppExtD k f n le
((fix expr_ind'' (le : seq expr) : foldr (fun e acc => P e /\ acc) True le :=
match le return foldr (fun e acc => P e /\ acc) True le with
| nil => I
| cons h q => conj (expr_ind' h) (expr_ind'' q)
end) le)
| App e1 e2 => P_App e1 e2 (expr_ind' e1) (expr_ind' e2)
| Subst e1 e2 => P_Subst e1 e2 (expr_ind' e1) (expr_ind' e2)
| Cst r => P_Cst r
| Binary o e1 e2 => P_Binary o e1 e2 (expr_ind' e1) (expr_ind' e2)
| Unary o e => P_Unary o e (expr_ind' e)
| Int f e1 e2 => P_Int f e1 e2 (expr_ind' f) (expr_ind' e1) (expr_ind' e2)
end.
End ExprInduction.
Fixpoint apply {T} p : Rn p T -> (nat -> R) -> T :=
match p return Rn p T -> _ -> T with
| O => fun (x : T) _ => x
| S p => fun (f : Rn (S p) T) g => apply p (f (g p)) g
end.

(* Specifications: *)
Lemma apply_ext :
forall T k (f : Rn k T) g1 g2,
(forall n, (n < k)%nat -> g1 n = g2 n) ->
apply k f g1 = apply k f g2.