Definition Derive_Rn n (f : Rn n R) p g :=
Derive (fun x => apply n f (fun i => if ssrnat.eqn i p then x else g i)) (g p).
Definition ex_derive_Rn n (f : Rn n R) p g :=
ex_derive (fun x => apply n f (fun i => if ssrnat.eqn i p then x else g i)) (g p).
Fixpoint interp (l : seq R) (e : expr) : R :=
match e with
| Var n => nth R0 l n
| AppExt k f le => apply k f (nth 0 (map (interp l) le))
| AppExtD k f n le => Derive_Rn k f n (nth 0 (map (interp l) le))
| App e1 e2 => interp ((interp l e2) :: l) e1
| Subst e1 e2 => interp (set_nth R0 l 0 (interp l e2)) e1
| Cst c => c
| Binary o e1 e2 => match o with Eplus => Rplus | Emult => Rmult end (interp l e1) (interp l e2)
| Unary o e => match o with Eopp => Ropp | Einv => Rinv | Efct f f' H => f | Efct' f f' df H => f end (interp l e)
| Int e1 e2 e3 => RInt (fun x => interp (x :: l) e1) (interp l e2) (interp l e3)
end.
Inductive domain :=
| Never : domain
| Always : domain
| Partial : (R -> Prop) -> expr -> domain
| Derivable : nat -> forall k, Rn k R -> seq expr -> domain
| Derivable2 : nat -> nat -> forall k, Rn k R -> seq expr -> domain
| Continuous : nat -> expr -> domain
| Continuous2 : nat -> nat -> expr -> domain
| Integrable : expr -> expr -> expr -> domain
| ParamIntegrable : nat -> expr -> expr -> expr -> domain
| LocallyParamIntegrable : nat -> expr -> expr -> domain
| And : seq domain -> domain
| Forall : expr -> expr -> domain -> domain
| Forone : expr -> domain -> domain
| Locally : nat -> domain -> domain
| Locally2 : nat -> nat -> domain -> domain
| ForallWide : nat -> expr -> expr -> domain -> domain.
Section DomainInduction.
Hypothesis P : domain -> Prop.
Hypothesis P_Never : P Never.
Hypothesis P_Always : P Always.
Hypothesis P_Partial : forall p e, P (Partial p e).
Hypothesis P_Derivable : forall n k f le, P (Derivable n k f le).
Hypothesis P_Derivable2 : forall m n k f le, P (Derivable2 m n k f le).
Hypothesis P_Continuous : forall n e, P (Continuous n e).
Hypothesis P_Continuous2 : forall m n e, P (Continuous2 m n e).
Hypothesis P_Integrable : forall f e1 e2, P (Integrable f e1 e2).
Hypothesis P_ParamIntegrable : forall n f e1 e2, P (ParamIntegrable n f e1 e2).
Hypothesis P_LocallyParamIntegrable : forall n f e, P (LocallyParamIntegrable n f e).
Hypothesis P_And : forall ld, foldr (fun d acc  => P d /\ acc) True ld -> P (And ld).
Hypothesis P_Forall : forall e1 e2 d, P d -> P (Forall e1 e2 d).
Hypothesis P_Forone : forall e d, P d -> P (Forone e d).
Hypothesis P_Locally : forall n d, P d -> P (Locally n d).
Hypothesis P_Locally2 : forall m n d, P d -> P (Locally2 m n d).
Hypothesis P_ForallWide : forall n e1 e2 d, P d -> P (ForallWide n e1 e2 d).
Fixpoint domain_ind' (d : domain) : P d :=
match d return P d with
| Never => P_Never
| Always => P_Always
| Partial d e => P_Partial d e
| Derivable n k f le => P_Derivable n k f le
| Derivable2 m n k f le => P_Derivable2 m n k f le
| Continuous n e => P_Continuous n e
| Continuous2 m n e => P_Continuous2 m n e
| Integrable f e1 e2 => P_Integrable f e1 e2
| ParamIntegrable n f e1 e2 => P_ParamIntegrable n f e1 e2
| LocallyParamIntegrable n f e => P_LocallyParamIntegrable n f e
| And ld => P_And ld
((fix domain_ind'' (ld : seq domain) : foldr (fun d acc => P d /\ acc) True ld :=
match ld return foldr (fun d acc => P d /\ acc) True ld with
| nil => I
| cons h q => conj (domain_ind' h) (domain_ind'' q)
end) ld)
| Forall e1 e2 d => P_Forall e1 e2 d (domain_ind' d)
| Forone e d => P_Forone e d (domain_ind' d)
| Locally n d => P_Locally n d (domain_ind' d)
| Locally2 m n d => P_Locally2 m n d (domain_ind' d)
| ForallWide n e1 e2 d => P_ForallWide n e1 e2 d (domain_ind' d)
end.
End DomainInduction.

(* Specifications: *)
Lemma foldr_prop_nth :
forall {T} {P: T -> Prop} d l n,
foldr (fun d acc => P d /\ acc) True l ->
P d ->
P (nth d l n).