Built with Alectryon, running Coq+SerAPI v8.10.0+0.7.0. Coq sources are in this panel; goals and messages will appear in the other. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus.
(************************************************************************)
(* * The Coq Proof Assistant / The Coq Development Team *)
(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)
(* <O___,, * (see CREDITS file for the list of authors) *)
(* \VV/ **************************************************************)
(* // * This file is distributed under the terms of the *)
(* * GNU Lesser General Public License Version 2.1 *)
(* * (see LICENSE file for the text of the license) *)
(************************************************************************)
Proofs of specification for functions defined over Vector
Author: Pierre Boutillier
Institution: PPS, INRIA 12/2010
Require Fin. Require Import VectorDef. Import VectorNotations. Definition cons_inj {A} {a1 a2} {n} {v1 v2 : t A n} (eq : a1 :: v1 = a2 :: v2) : a1 = a2 /\ v1 = v2 := match eq in _ = x return caseS _ (fun a2' _ v2' => fun v1' => a1 = a2' /\ v1' = v2') x v1 with | eq_refl => conj eq_refl eq_refl end.A:Typen:natv:t A (S n)v = hd v :: tl vintros; apply caseS with (v:=v); intros; reflexivity. Defined.A:Typen:natv:t A (S n)v = hd v :: tl v
Lemmas are done for functions that use Fin.t but thanks to Peano_dec.le_unique, all
is true for the one that use lt
A:Typen:natv1, v2:t A n(forall p1 p2 : Fin.t n, p1 = p2 -> v1[@p1] = v2[@p2]) <-> v1 = v2A:Typen:natv1, v2:t A n(forall p1 p2 : Fin.t n, p1 = p2 -> v1[@p1] = v2[@p2]) <-> v1 = v2A:Typen:natv1, v2:t A n(forall p1 p2 : Fin.t n, p1 = p2 -> v1[@p1] = v2[@p2]) -> v1 = v2A:Typen:natv1, v2:t A nv1 = v2 -> forall p1 p2 : Fin.t n, p1 = p2 -> v1[@p1] = v2[@p2]A:Typen:natv1, v2:t A n(forall p1 p2 : Fin.t n, p1 = p2 -> v1[@p1] = v2[@p2]) -> v1 = v2A:TypeH:forall p1 p2 : Fin.t 0, p1 = p2 -> match p1 in (Fin.t m') return (t A m' -> A) with | @Fin.F1 n => caseS (fun (n0 : nat) (_ : t A (S n0)) => A) (fun (h : A) (n0 : nat) (_ : t A n0) => h) | @Fin.FS n p' => fun v : t A (S n) => caseS (fun (n0 : nat) (_ : t A (S n0)) => Fin.t n0 -> A) (fun (_ : A) (n0 : nat) (t : t A n0) (p0 : Fin.t n0) => t[@p0]) v p' end [] = match p2 in (Fin.t m') return (t A m' -> A) with | @Fin.F1 n => caseS (fun (n0 : nat) (_ : t A (S n0)) => A) (fun (h : A) (n0 : nat) (_ : t A n0) => h) | @Fin.FS n p' => fun v : t A (S n) => caseS (fun (n0 : nat) (_ : t A (S n0)) => Fin.t n0 -> A) (fun (_ : A) (n0 : nat) (t : t A n0) (p0 : Fin.t n0) => t[@p0]) v p' end [][] = []A:Typen:natv1, v2:t A nH:(forall p1 p2 : Fin.t n, p1 = p2 -> v1[@p1] = v2[@p2]) -> v1 = v2a, b:AH0:forall p1 p2 : Fin.t (S n), p1 = p2 -> match p1 in (Fin.t m') return (t A m' -> A) with | @Fin.F1 n0 => caseS (fun (n1 : nat) (_ : t A (S n1)) => A) (fun (h : A) (n1 : nat) (_ : t A n1) => h) | @Fin.FS n0 p' => fun v : t A (S n0) => caseS (fun (n1 : nat) (_ : t A (S n1)) => Fin.t n1 -> A) (fun (_ : A) (n1 : nat) (t : t A n1) (p0 : Fin.t n1) => t[@p0]) v p' end (a :: v1) = match p2 in (Fin.t m') return (t A m' -> A) with | @Fin.F1 n0 => caseS (fun (n1 : nat) (_ : t A (S n1)) => A) (fun (h : A) (n1 : nat) (_ : t A n1) => h) | @Fin.FS n0 p' => fun v : t A (S n0) => caseS (fun (n1 : nat) (_ : t A (S n1)) => Fin.t n1 -> A) (fun (_ : A) (n1 : nat) (t : t A n1) (p0 : Fin.t n1) => t[@p0]) v p' end (b :: v2)a :: v1 = b :: v2reflexivity.A:TypeH:forall p1 p2 : Fin.t 0, p1 = p2 -> match p1 in (Fin.t m') return (t A m' -> A) with | @Fin.F1 n => caseS (fun (n0 : nat) (_ : t A (S n0)) => A) (fun (h : A) (n0 : nat) (_ : t A n0) => h) | @Fin.FS n p' => fun v : t A (S n) => caseS (fun (n0 : nat) (_ : t A (S n0)) => Fin.t n0 -> A) (fun (_ : A) (n0 : nat) (t : t A n0) (p0 : Fin.t n0) => t[@p0]) v p' end [] = match p2 in (Fin.t m') return (t A m' -> A) with | @Fin.F1 n => caseS (fun (n0 : nat) (_ : t A (S n0)) => A) (fun (h : A) (n0 : nat) (_ : t A n0) => h) | @Fin.FS n p' => fun v : t A (S n) => caseS (fun (n0 : nat) (_ : t A (S n0)) => Fin.t n0 -> A) (fun (_ : A) (n0 : nat) (t : t A n0) (p0 : Fin.t n0) => t[@p0]) v p' end [][] = []A:Typen:natv1, v2:t A nH:(forall p1 p2 : Fin.t n, p1 = p2 -> v1[@p1] = v2[@p2]) -> v1 = v2a, b:AH0:forall p1 p2 : Fin.t (S n), p1 = p2 -> match p1 in (Fin.t m') return (t A m' -> A) with | @Fin.F1 n0 => caseS (fun (n1 : nat) (_ : t A (S n1)) => A) (fun (h : A) (n1 : nat) (_ : t A n1) => h) | @Fin.FS n0 p' => fun v : t A (S n0) => caseS (fun (n1 : nat) (_ : t A (S n1)) => Fin.t n1 -> A) (fun (_ : A) (n1 : nat) (t : t A n1) (p0 : Fin.t n1) => t[@p0]) v p' end (a :: v1) = match p2 in (Fin.t m') return (t A m' -> A) with | @Fin.F1 n0 => caseS (fun (n1 : nat) (_ : t A (S n1)) => A) (fun (h : A) (n1 : nat) (_ : t A n1) => h) | @Fin.FS n0 p' => fun v : t A (S n0) => caseS (fun (n1 : nat) (_ : t A (S n1)) => Fin.t n1 -> A) (fun (_ : A) (n1 : nat) (t : t A n1) (p0 : Fin.t n1) => t[@p0]) v p' end (b :: v2)a :: v1 = b :: v2A:Typen:natv1, v2:t A nH:(forall p1 p2 : Fin.t n, p1 = p2 -> v1[@p1] = v2[@p2]) -> v1 = v2a, b:AH0:forall p1 p2 : Fin.t (S n), p1 = p2 -> match p1 in (Fin.t m') return (t A m' -> A) with | @Fin.F1 n0 => caseS (fun (n1 : nat) (_ : t A (S n1)) => A) (fun (h : A) (n1 : nat) (_ : t A n1) => h) | @Fin.FS n0 p' => fun v : t A (S n0) => caseS (fun (n1 : nat) (_ : t A (S n1)) => Fin.t n1 -> A) (fun (_ : A) (n1 : nat) (t : t A n1) (p0 : Fin.t n1) => t[@p0]) v p' end (a :: v1) = match p2 in (Fin.t m') return (t A m' -> A) with | @Fin.F1 n0 => caseS (fun (n1 : nat) (_ : t A (S n1)) => A) (fun (h : A) (n1 : nat) (_ : t A n1) => h) | @Fin.FS n0 p' => fun v : t A (S n0) => caseS (fun (n1 : nat) (_ : t A (S n1)) => Fin.t n1 -> A) (fun (_ : A) (n1 : nat) (t : t A n1) (p0 : Fin.t n1) => t[@p0]) v p' end (b :: v2)a = bA:Typen:natv1, v2:t A nH:(forall p1 p2 : Fin.t n, p1 = p2 -> v1[@p1] = v2[@p2]) -> v1 = v2a, b:AH0:forall p1 p2 : Fin.t (S n), p1 = p2 -> match p1 in (Fin.t m') return (t A m' -> A) with | @Fin.F1 n0 => caseS (fun (n1 : nat) (_ : t A (S n1)) => A) (fun (h : A) (n1 : nat) (_ : t A n1) => h) | @Fin.FS n0 p' => fun v : t A (S n0) => caseS (fun (n1 : nat) (_ : t A (S n1)) => Fin.t n1 -> A) (fun (_ : A) (n1 : nat) (t : t A n1) (p0 : Fin.t n1) => t[@p0]) v p' end (a :: v1) = match p2 in (Fin.t m') return (t A m' -> A) with | @Fin.F1 n0 => caseS (fun (n1 : nat) (_ : t A (S n1)) => A) (fun (h : A) (n1 : nat) (_ : t A n1) => h) | @Fin.FS n0 p' => fun v : t A (S n0) => caseS (fun (n1 : nat) (_ : t A (S n1)) => Fin.t n1 -> A) (fun (_ : A) (n1 : nat) (t : t A n1) (p0 : Fin.t n1) => t[@p0]) v p' end (b :: v2)v1 = v2A:Typen:natv1, v2:t A nH:(forall p1 p2 : Fin.t n, p1 = p2 -> v1[@p1] = v2[@p2]) -> v1 = v2a, b:AH0:forall p1 p2 : Fin.t (S n), p1 = p2 -> match p1 in (Fin.t m') return (t A m' -> A) with | @Fin.F1 n0 => caseS (fun (n1 : nat) (_ : t A (S n1)) => A) (fun (h : A) (n1 : nat) (_ : t A n1) => h) | @Fin.FS n0 p' => fun v : t A (S n0) => caseS (fun (n1 : nat) (_ : t A (S n1)) => Fin.t n1 -> A) (fun (_ : A) (n1 : nat) (t : t A n1) (p0 : Fin.t n1) => t[@p0]) v p' end (a :: v1) = match p2 in (Fin.t m') return (t A m' -> A) with | @Fin.F1 n0 => caseS (fun (n1 : nat) (_ : t A (S n1)) => A) (fun (h : A) (n1 : nat) (_ : t A n1) => h) | @Fin.FS n0 p' => fun v : t A (S n0) => caseS (fun (n1 : nat) (_ : t A (S n1)) => Fin.t n1 -> A) (fun (_ : A) (n1 : nat) (t : t A n1) (p0 : Fin.t n1) => t[@p0]) v p' end (b :: v2)v1 = v2intros p1 p2 H1; apply (H0 (Fin.FS p1) (Fin.FS p2) (f_equal (@Fin.FS n) H1)).A:Typen:natv1, v2:t A nH:(forall p1 p2 : Fin.t n, p1 = p2 -> v1[@p1] = v2[@p2]) -> v1 = v2a, b:AH0:forall p1 p2 : Fin.t (S n), p1 = p2 -> match p1 in (Fin.t m') return (t A m' -> A) with | @Fin.F1 n0 => caseS (fun (n1 : nat) (_ : t A (S n1)) => A) (fun (h : A) (n1 : nat) (_ : t A n1) => h) | @Fin.FS n0 p' => fun v : t A (S n0) => caseS (fun (n1 : nat) (_ : t A (S n1)) => Fin.t n1 -> A) (fun (_ : A) (n1 : nat) (t : t A n1) (p0 : Fin.t n1) => t[@p0]) v p' end (a :: v1) = match p2 in (Fin.t m') return (t A m' -> A) with | @Fin.F1 n0 => caseS (fun (n1 : nat) (_ : t A (S n1)) => A) (fun (h : A) (n1 : nat) (_ : t A n1) => h) | @Fin.FS n0 p' => fun v : t A (S n0) => caseS (fun (n1 : nat) (_ : t A (S n1)) => Fin.t n1 -> A) (fun (_ : A) (n1 : nat) (t : t A n1) (p0 : Fin.t n1) => t[@p0]) v p' end (b :: v2)forall p1 p2 : Fin.t n, p1 = p2 -> v1[@p1] = v2[@p2]intros; now f_equal. Qed.A:Typen:natv1, v2:t A nv1 = v2 -> forall p1 p2 : Fin.t n, p1 = p2 -> v1[@p1] = v2[@p2]A:Typeforall (n : nat) (v : t A (S n)) (H : n < S n), nth_order v H = last vunfold nth_order; refine (@rectS _ _ _ _); now simpl. Qed.A:Typeforall (n : nat) (v : t A (S n)) (H : n < S n), nth_order v H = last vA:Typea:An:natv:t A nk1, k2:Fin.t neq:k1 = k2(shiftin a v)[@Fin.L_R 1 k1] = v[@k2]A:Typea:An:natv:t A nk1, k2:Fin.t neq:k1 = k2(shiftin a v)[@Fin.L_R 1 k1] = v[@k2]A:Typea:An:natv:t A (S n)(shiftin a v)[@Fin.L_R 1 Fin.F1] = v[@Fin.F1]A:Typea:An:natv:t A (S n)k1:Fin.t nIHk1:forall v0 : t A n, (shiftin a v0)[@Fin.L_R 1 k1] = v0[@k1](shiftin a v)[@Fin.L_R 1 (Fin.FS k1)] = v[@Fin.FS k1]A:Typea:An:natv:t A (S n)(shiftin a v)[@Fin.L_R 1 Fin.F1] = v[@Fin.F1]A:Typea:Aforall (n : nat) (v : t A (S n)), (shiftin a v)[@Fin.L_R 1 Fin.F1] = v[@Fin.F1]now simpl.A:Typea, h:An:natt:VectorDef.t A n(shiftin a (h :: t))[@Fin.L_R 1 Fin.F1] = (h :: t)[@Fin.F1]A:Typea:An:natv:t A (S n)k1:Fin.t nIHk1:forall v0 : t A n, (shiftin a v0)[@Fin.L_R 1 k1] = v0[@k1](shiftin a v)[@Fin.L_R 1 (Fin.FS k1)] = v[@Fin.FS k1]A:Typea:Aforall (n : nat) (v : t A (S n)) (k1 : Fin.t n), (forall v0 : t A n, (shiftin a v0)[@Fin.L_R 1 k1] = v0[@k1]) -> (shiftin a v)[@Fin.L_R 1 (Fin.FS k1)] = v[@Fin.FS k1]now simpl. Qed.A:Typea, h:An:natt:VectorDef.t A nk1:Fin.t nIHk1:forall v : VectorDef.t A n, (shiftin a v)[@Fin.L_R 1 k1] = v[@k1](shiftin a (h :: t))[@Fin.L_R 1 (Fin.FS k1)] = (h :: t)[@Fin.FS k1]A:Typea:An:natv:t A nlast (shiftin a v) = ainduction v ;now simpl. Qed.A:Typea:An:natv:t A nlast (shiftin a v) = aA:Typeforall (n : nat) (k : Fin.t (S n)) (v : t A (S n)), (shiftrepeat v)[@Fin.L_R 1 k] = v[@k]A:Typeforall (n : nat) (k : Fin.t (S n)) (v : t A (S n)), (shiftrepeat v)[@Fin.L_R 1 k] = v[@k]A:Typen:natv:t A (S n)(shiftrepeat v)[@Fin.L_R 1 Fin.F1] = v[@Fin.F1]A:Typen:natp:Fin.t (S n)H:forall v0 : t A (S n), (shiftrepeat v0)[@Fin.L_R 1 p] = v0[@p]v:t A (S (S n))(shiftrepeat v)[@Fin.L_R 1 (Fin.FS p)] = v[@Fin.FS p]A:Typen:natv:t A (S n)(shiftrepeat v)[@Fin.L_R 1 Fin.F1] = v[@Fin.F1]now destruct t.A:Typeh:An:natt:VectorDef.t A n(match n as n0 return (VectorDef.t A n0 -> VectorDef.t A (S (S n0))) with | 0 => fun v : VectorDef.t A 0 => match v as v0 in (VectorDef.t _ n0) return (match n0 as x return (VectorDef.t A x -> Type) with | 0 => fun _ : VectorDef.t A 0 => VectorDef.t A 2 | S n1 => fun _ : VectorDef.t A (S n1) => False -> IDProp end v0) with | [] => [h; h] | _ :: _ => fun devil : False => False_ind IDProp devil end | S nn' => fun v : VectorDef.t A (S nn') => h :: shiftrepeat v end t)[@Fin.F1] = hA:Typen:natp:Fin.t (S n)H:forall v0 : t A (S n), (shiftrepeat v0)[@Fin.L_R 1 p] = v0[@p]v:t A (S (S n))(shiftrepeat v)[@Fin.L_R 1 (Fin.FS p)] = v[@Fin.FS p]A:Typen:natv:t A (S (S n))forall p : Fin.t (S n), (forall v0 : t A (S n), (shiftrepeat v0)[@Fin.L_R 1 p] = v0[@p]) -> (shiftrepeat v)[@Fin.L_R 1 (Fin.FS p)] = v[@Fin.FS p]A:Typen:natv:VectorDef.t A (S (S n))h:An0:natt:VectorDef.t A n0match n0 as n1 return (VectorDef.t A (S n1) -> Prop) with | 0 => fun _ : VectorDef.t A 1 => True | S n1 => fun v0 : VectorDef.t A (S (S n1)) => forall p : Fin.t (S n1), (forall v1 : VectorDef.t A (S n1), (shiftrepeat v1)[@Fin.L_R 1 p] = v1[@p]) -> (shiftrepeat v0)[@Fin.L_R 1 (Fin.FS p)] = v0[@Fin.FS p] end (h :: t)A:Typen:natv:VectorDef.t A (S (S n))h:At:VectorDef.t A 0TrueA:Typen:natv:VectorDef.t A (S (S n))h:An0:natt:VectorDef.t A (S n0)forall p : Fin.t (S n0), (forall v0 : VectorDef.t A (S n0), (shiftrepeat v0)[@Fin.L_R 1 p] = v0[@p]) -> (shiftrepeat (h :: t))[@Fin.L_R 1 (Fin.FS p)] = (h :: t)[@Fin.FS p]now simpl. Qed.A:Typen:natv:VectorDef.t A (S (S n))h:An0:natt:VectorDef.t A (S n0)forall p : Fin.t (S n0), (forall v0 : VectorDef.t A (S n0), (shiftrepeat v0)[@Fin.L_R 1 p] = v0[@p]) -> (shiftrepeat (h :: t))[@Fin.L_R 1 (Fin.FS p)] = (h :: t)[@Fin.FS p]A:Typeforall (n : nat) (v : t A (S n)), last (shiftrepeat v) = last vrefine (@rectS _ _ _ _); now simpl. Qed.A:Typeforall (n : nat) (v : t A (S n)), last (shiftrepeat v) = last vA:Typea:An:natp:Fin.t n(const a n)[@p] = anow induction p. Qed.A:Typea:An:natp:Fin.t n(const a n)[@p] = aA, B:Typef:A -> Bn:natv:t A np1, p2:Fin.t neq:p1 = p2(map f v)[@p1] = f v[@p2]A, B:Typef:A -> Bn:natv:t A np1, p2:Fin.t neq:p1 = p2(map f v)[@p1] = f v[@p2]A, B:Typef:A -> Bn:natv:t A (S n)(map f v)[@Fin.F1] = f v[@Fin.F1]A, B:Typef:A -> Bn:natv:t A (S n)p1:Fin.t nIHp1:forall v0 : t A n, (map f v0)[@p1] = f v0[@p1](map f v)[@Fin.FS p1] = f v[@Fin.FS p1]revert n v; refine (@caseS _ _ _); now simpl.A, B:Typef:A -> Bn:natv:t A (S n)(map f v)[@Fin.F1] = f v[@Fin.F1]revert n v p1 IHp1; refine (@caseS _ _ _); now simpl. Qed.A, B:Typef:A -> Bn:natv:t A (S n)p1:Fin.t nIHp1:forall v0 : t A n, (map f v0)[@p1] = f v0[@p1](map f v)[@Fin.FS p1] = f v[@Fin.FS p1]A, B, C:Typef:A -> B -> Cn:natv:t A nw:t B np1, p2, p3:Fin.t np1 = p2 -> p2 = p3 -> (map2 f v w)[@p1] = f v[@p2] w[@p3]A, B, C:Typef:A -> B -> Cn:natv:t A nw:t B np1, p2, p3:Fin.t np1 = p2 -> p2 = p3 -> (map2 f v w)[@p1] = f v[@p2] w[@p3]A, B, C:Typef:A -> B -> Cforall (n : nat) (v : t A n) (w : t B n) (p1 : Fin.t n), (map2 f v w)[@p1] = f v[@p1] w[@p1]A, B, C:Typef:A -> B -> Cforall p1 : Fin.t 0, match p1 in (Fin.t m') return (t C m' -> C) with | @Fin.F1 n => caseS (fun (n0 : nat) (_ : t C (S n0)) => C) (fun (h : C) (n0 : nat) (_ : t C n0) => h) | @Fin.FS n p' => fun v : t C (S n) => caseS (fun (n0 : nat) (_ : t C (S n0)) => Fin.t n0 -> C) (fun (_ : C) (n0 : nat) (t : t C n0) (p0 : Fin.t n0) => t[@p0]) v p' end [] = f (match p1 in (Fin.t m') return (t A m' -> A) with | @Fin.F1 n => caseS (fun (n0 : nat) (_ : t A (S n0)) => A) (fun (h : A) (n0 : nat) (_ : t A n0) => h) | @Fin.FS n p' => fun v : t A (S n) => caseS (fun (n0 : nat) (_ : t A (S n0)) => Fin.t n0 -> A) (fun (_ : A) (n0 : nat) (t : t A n0) (p0 : Fin.t n0) => t[@p0]) v p' end []) (match p1 in (Fin.t m') return (t B m' -> B) with | @Fin.F1 n => caseS (fun (n0 : nat) (_ : t B (S n0)) => B) (fun (h : B) (n0 : nat) (_ : t B n0) => h) | @Fin.FS n p' => fun v : t B (S n) => caseS (fun (n0 : nat) (_ : t B (S n0)) => Fin.t n0 -> B) (fun (_ : B) (n0 : nat) (t : t B n0) (p0 : Fin.t n0) => t[@p0]) v p' end [])A, B, C:Typef:A -> B -> Cforall (n : nat) (v1 : t A n) (v2 : t B n), (forall p1 : Fin.t n, (map2 f v1 v2)[@p1] = f v1[@p1] v2[@p1]) -> forall (a : A) (b : B) (p1 : Fin.t (S n)), match p1 in (Fin.t m') return (t C m' -> C) with | @Fin.F1 n0 => caseS (fun (n1 : nat) (_ : t C (S n1)) => C) (fun (h : C) (n1 : nat) (_ : t C n1) => h) | @Fin.FS n0 p' => fun v : t C (S n0) => caseS (fun (n1 : nat) (_ : t C (S n1)) => Fin.t n1 -> C) (fun (_ : C) (n1 : nat) (t : t C n1) (p0 : Fin.t n1) => t[@p0]) v p' end (f a b :: map2 f v1 v2) = f (match p1 in (Fin.t m') return (t A m' -> A) with | @Fin.F1 n0 => caseS (fun (n1 : nat) (_ : t A (S n1)) => A) (fun (h : A) (n1 : nat) (_ : t A n1) => h) | @Fin.FS n0 p' => fun v : t A (S n0) => caseS (fun (n1 : nat) (_ : t A (S n1)) => Fin.t n1 -> A) (fun (_ : A) (n1 : nat) (t : t A n1) (p0 : Fin.t n1) => t[@p0]) v p' end (a :: v1)) (match p1 in (Fin.t m') return (t B m' -> B) with | @Fin.F1 n0 => caseS (fun (n1 : nat) (_ : t B (S n1)) => B) (fun (h : B) (n1 : nat) (_ : t B n1) => h) | @Fin.FS n0 p' => fun v : t B (S n0) => caseS (fun (n1 : nat) (_ : t B (S n1)) => Fin.t n1 -> B) (fun (_ : B) (n1 : nat) (t : t B n1) (p0 : Fin.t n1) => t[@p0]) v p' end (b :: v2))exact (Fin.case0 _).A, B, C:Typef:A -> B -> Cforall p1 : Fin.t 0, match p1 in (Fin.t m') return (t C m' -> C) with | @Fin.F1 n => caseS (fun (n0 : nat) (_ : t C (S n0)) => C) (fun (h : C) (n0 : nat) (_ : t C n0) => h) | @Fin.FS n p' => fun v : t C (S n) => caseS (fun (n0 : nat) (_ : t C (S n0)) => Fin.t n0 -> C) (fun (_ : C) (n0 : nat) (t : t C n0) (p0 : Fin.t n0) => t[@p0]) v p' end [] = f (match p1 in (Fin.t m') return (t A m' -> A) with | @Fin.F1 n => caseS (fun (n0 : nat) (_ : t A (S n0)) => A) (fun (h : A) (n0 : nat) (_ : t A n0) => h) | @Fin.FS n p' => fun v : t A (S n) => caseS (fun (n0 : nat) (_ : t A (S n0)) => Fin.t n0 -> A) (fun (_ : A) (n0 : nat) (t : t A n0) (p0 : Fin.t n0) => t[@p0]) v p' end []) (match p1 in (Fin.t m') return (t B m' -> B) with | @Fin.F1 n => caseS (fun (n0 : nat) (_ : t B (S n0)) => B) (fun (h : B) (n0 : nat) (_ : t B n0) => h) | @Fin.FS n p' => fun v : t B (S n) => caseS (fun (n0 : nat) (_ : t B (S n0)) => Fin.t n0 -> B) (fun (_ : B) (n0 : nat) (t : t B n0) (p0 : Fin.t n0) => t[@p0]) v p' end [])intros n v1 v2 H a b p; revert n p v1 v2 H; refine (@Fin.caseS _ _ _); now simpl. Qed.A, B, C:Typef:A -> B -> Cforall (n : nat) (v1 : t A n) (v2 : t B n), (forall p1 : Fin.t n, (map2 f v1 v2)[@p1] = f v1[@p1] v2[@p1]) -> forall (a : A) (b : B) (p1 : Fin.t (S n)), match p1 in (Fin.t m') return (t C m' -> C) with | @Fin.F1 n0 => caseS (fun (n1 : nat) (_ : t C (S n1)) => C) (fun (h : C) (n1 : nat) (_ : t C n1) => h) | @Fin.FS n0 p' => fun v : t C (S n0) => caseS (fun (n1 : nat) (_ : t C (S n1)) => Fin.t n1 -> C) (fun (_ : C) (n1 : nat) (t : t C n1) (p0 : Fin.t n1) => t[@p0]) v p' end (f a b :: map2 f v1 v2) = f (match p1 in (Fin.t m') return (t A m' -> A) with | @Fin.F1 n0 => caseS (fun (n1 : nat) (_ : t A (S n1)) => A) (fun (h : A) (n1 : nat) (_ : t A n1) => h) | @Fin.FS n0 p' => fun v : t A (S n0) => caseS (fun (n1 : nat) (_ : t A (S n1)) => Fin.t n1 -> A) (fun (_ : A) (n1 : nat) (t : t A n1) (p0 : Fin.t n1) => t[@p0]) v p' end (a :: v1)) (match p1 in (Fin.t m') return (t B m' -> B) with | @Fin.F1 n0 => caseS (fun (n1 : nat) (_ : t B (S n1)) => B) (fun (h : B) (n1 : nat) (_ : t B n1) => h) | @Fin.FS n0 p' => fun v : t B (S n0) => caseS (fun (n1 : nat) (_ : t B (S n1)) => Fin.t n1 -> B) (fun (_ : B) (n1 : nat) (t : t B n1) (p0 : Fin.t n1) => t[@p0]) v p' end (b :: v2))A, B:Typef:A -> B -> Aassoc:forall (a : A) (b c : B), f (f a b) c = f (f a c) bn:natv:t B nforall a : A, fold_left f a v = fold_right (fun (x : B) (y : A) => f y x) v aA, B:Typef:A -> B -> Aassoc:forall (a : A) (b c : B), f (f a b) c = f (f a c) bn:natv:t B nforall a : A, fold_left f a v = fold_right (fun (x : B) (y : A) => f y x) v aA, B:Typef:A -> B -> Aassoc:forall (a : A) (b c : B), f (f a b) c = f (f a c) bn:natv:t B nforall (n0 : nat) (h : B) (v0 : t B n0) (a : A), fold_left f (f a h) v0 = f (fold_left f a v0) hA, B:Typef:A -> B -> Aassoc:forall (a : A) (b c : B), f (f a b) c = f (f a c) bn:natv:t B nH:forall (n0 : nat) (h : B) (v0 : t B n0) (a : A), fold_left f (f a h) v0 = f (fold_left f a v0) hforall a : A, fold_left f a v = fold_right (fun (x : B) (y : A) => f y x) v aA, B:Typef:A -> B -> Aassoc:forall (a : A) (b c : B), f (f a b) c = f (f a c) bn:natv:t B nforall (n0 : nat) (h : B) (v0 : t B n0) (a : A), fold_left f (f a h) v0 = f (fold_left f a v0) hA, B:Typef:A -> B -> Aassoc:forall (a : A) (b c : B), f (f a b) c = f (f a c) bn:natv:t B nh:Bforall a : A, fold_left f (f a h) [] = f (fold_left f a []) hA, B:Typef:A -> B -> Aassoc:forall (a : A) (b c : B), f (f a b) c = f (f a c) bn:natv:t B nh, h0:Bn0:natv0:t B n0IHv0:forall a : A, fold_left f (f a h) v0 = f (fold_left f a v0) hforall a : A, fold_left f (f a h) (h0 :: v0) = f (fold_left f a (h0 :: v0)) hnow simpl.A, B:Typef:A -> B -> Aassoc:forall (a : A) (b c : B), f (f a b) c = f (f a c) bn:natv:t B nh:Bforall a : A, fold_left f (f a h) [] = f (fold_left f a []) hA, B:Typef:A -> B -> Aassoc:forall (a : A) (b c : B), f (f a b) c = f (f a c) bn:natv:t B nh, h0:Bn0:natv0:t B n0IHv0:forall a : A, fold_left f (f a h) v0 = f (fold_left f a v0) hforall a : A, fold_left f (f a h) (h0 :: v0) = f (fold_left f a (h0 :: v0)) hA, B:Typef:A -> B -> Aassoc:forall (a0 : A) (b c : B), f (f a0 b) c = f (f a0 c) bn:natv:t B nh, h0:Bn0:natv0:t B n0IHv0:forall a0 : A, fold_left f (f a0 h) v0 = f (fold_left f a0 v0) ha:Afold_left f (f (f a h) h0) v0 = f (fold_left f (f a h0) v0) hnow f_equal.A, B:Typef:A -> B -> Aassoc:forall (a0 : A) (b c : B), f (f a0 b) c = f (f a0 c) bn:natv:t B nh, h0:Bn0:natv0:t B n0IHv0:forall a0 : A, fold_left f (f a0 h) v0 = f (fold_left f a0 v0) ha:Afold_left f (f (f a h0) h) v0 = fold_left f (f (f a h0) h) v0A, B:Typef:A -> B -> Aassoc:forall (a : A) (b c : B), f (f a b) c = f (f a c) bn:natv:t B nH:forall (n0 : nat) (h : B) (v0 : t B n0) (a : A), fold_left f (f a h) v0 = f (fold_left f a v0) hforall a : A, fold_left f a v = fold_right (fun (x : B) (y : A) => f y x) v aA, B:Typef:A -> B -> Aassoc:forall (a : A) (b c : B), f (f a b) c = f (f a c) bH:forall (n : nat) (h : B) (v : t B n) (a : A), fold_left f (f a h) v = f (fold_left f a v) hforall a : A, fold_left f a [] = fold_right (fun (x : B) (y : A) => f y x) [] aA, B:Typef:A -> B -> Aassoc:forall (a : A) (b c : B), f (f a b) c = f (f a c) bh:Bn:natv:t B nH:forall (n0 : nat) (h0 : B) (v0 : t B n0) (a : A), fold_left f (f a h0) v0 = f (fold_left f a v0) h0IHv:forall a : A, fold_left f a v = fold_right (fun (x : B) (y : A) => f y x) v aforall a : A, fold_left f a (h :: v) = fold_right (fun (x : B) (y : A) => f y x) (h :: v) areflexivity.A, B:Typef:A -> B -> Aassoc:forall (a : A) (b c : B), f (f a b) c = f (f a c) bH:forall (n : nat) (h : B) (v : t B n) (a : A), fold_left f (f a h) v = f (fold_left f a v) hforall a : A, fold_left f a [] = fold_right (fun (x : B) (y : A) => f y x) [] aA, B:Typef:A -> B -> Aassoc:forall (a : A) (b c : B), f (f a b) c = f (f a c) bh:Bn:natv:t B nH:forall (n0 : nat) (h0 : B) (v0 : t B n0) (a : A), fold_left f (f a h0) v0 = f (fold_left f a v0) h0IHv:forall a : A, fold_left f a v = fold_right (fun (x : B) (y : A) => f y x) v aforall a : A, fold_left f a (h :: v) = fold_right (fun (x : B) (y : A) => f y x) (h :: v) aintros; now rewrite<- (IHv). Qed.A, B:Typef:A -> B -> Aassoc:forall (a : A) (b c : B), f (f a b) c = f (f a c) bh:Bn:natv:t B nH:forall (n0 : nat) (h0 : B) (v0 : t B n0) (a : A), fold_left f (f a h0) v0 = f (fold_left f a v0) h0IHv:forall a : A, fold_left f a v = fold_right (fun (x : B) (y : A) => f y x) v aforall a : A, fold_left f (f a h) v = f (fold_right (fun (x : B) (y : A) => f y x) v a) hA:Typel:list Ato_list (of_list l) = lA:Typel:list Ato_list (of_list l) = lA:Typeto_list (of_list Datatypes.nil) = Datatypes.nilA:Typea:Al:list AIHl:to_list (of_list l) = lto_list (of_list (a :: l)) = (a :: l)%listreflexivity.A:Typeto_list (of_list Datatypes.nil) = Datatypes.nilA:Typea:Al:list AIHl:to_list (of_list l) = lto_list (of_list (a :: l)) = (a :: l)%listnow f_equal. Qed.A:Typea:Al:list AIHl:to_list (of_list l) = l(a :: (fix fold_right_fix (n : nat) (v : t A n) (b : list A) {struct v} : list A := match v with | [] => b | cons _ a0 n0 w => a0 :: fold_right_fix n0 w b end) (length l) (of_list l) Datatypes.nil)%list = (a :: l)%listforall (A : Type) (n : nat) (le : 0 <= n) (v : t A n), take 0 le v = []reflexivity. Qed.forall (A : Type) (n : nat) (le : 0 <= n) (v : t A n), take 0 le v = []forall (A : Type) (p n : nat) (v : t A n) (le : p <= n) (le' : p <= p), take p le' (take p le v) = take p le vforall (A : Type) (p n : nat) (v : t A n) (le : p <= n) (le' : p <= p), take p le' (take p le v) = take p le vA:Typen:natv:t A nle:0 <= nle':0 <= 0take 0 le' (take 0 le v) = take 0 le vA:Typep:natIHp:forall (n0 : nat) (v0 : t A n0) (le0 : p <= n0) (le'0 : p <= p), take p le'0 (take p le0 v0) = take p le0 v0n:natv:t A nle:S p <= nle':S p <= S ptake (S p) le' (take (S p) le v) = take (S p) le vauto.A:Typen:natv:t A nle:0 <= nle':0 <= 0take 0 le' (take 0 le v) = take 0 le vA:Typep:natIHp:forall (n0 : nat) (v0 : t A n0) (le0 : p <= n0) (le'0 : p <= p), take p le'0 (take p le0 v0) = take p le0 v0n:natv:t A nle:S p <= nle':S p <= S ptake (S p) le' (take (S p) le v) = take (S p) le vA:Typep:natIHp:forall (n : nat) (v : t A n) (le0 : p <= n) (le'0 : p <= p), take p le'0 (take p le0 v) = take p le0 vle:S p <= 0le':S p <= S ptake (S p) le' (take (S p) le []) = take (S p) le []A:Typep:natIHp:forall (n0 : nat) (v0 : t A n0) (le0 : p <= n0) (le'0 : p <= p), take p le'0 (take p le0 v0) = take p le0 v0h:An:natv:t A nle:S p <= S nle':S p <= S ptake (S p) le' (take (S p) le (h :: v)) = take (S p) le (h :: v)A:Typep:natIHp:forall (n0 : nat) (v0 : t A n0) (le0 : p <= n0) (le'0 : p <= p), take p le'0 (take p le0 v0) = take p le0 v0h:An:natv:t A nle:S p <= S nle':S p <= S ptake (S p) le' (take (S p) le (h :: v)) = take (S p) le (h :: v)A:Typep:natIHp:forall (n0 : nat) (v0 : t A n0) (le0 : p <= n0) (le'0 : p <= p), take p le'0 (take p le0 v0) = take p le0 v0h:An:natv:t A nle:S p <= S nle':S p <= S ph :: take p (Le.le_S_n p p le') (take p (Le.le_S_n p n le) v) = h :: take p (Le.le_S_n p n le) vapply IHp. Qed.A:Typep:natIHp:forall (n0 : nat) (v0 : t A n0) (le0 : p <= n0) (le'0 : p <= p), take p le'0 (take p le0 v0) = take p le0 v0h:An:natv:t A nle:S p <= S nle':S p <= S ptake p (Le.le_S_n p p le') (take p (Le.le_S_n p n le) v) = take p (Le.le_S_n p n le) vforall (A : Type) (n : nat) (v : t A n) (m : nat) (w : t A m) (le : n <= n + m), take n le (v ++ w) = vforall (A : Type) (n : nat) (v : t A n) (m : nat) (w : t A m) (le : n <= n + m), take n le (v ++ w) = vA:Typem:natw:t A mle:0 <= 0 + mtake 0 le ([] ++ w) = []A:Typeh:An:natv:t A nIHv:forall (m0 : nat) (w0 : t A m0) (le0 : n <= n + m0), take n le0 (v ++ w0) = vm:natw:t A mle:S n <= S n + mtake (S n) le ((h :: v) ++ w) = h :: vreflexivity.A:Typem:natw:t A mle:0 <= 0 + mtake 0 le ([] ++ w) = []A:Typeh:An:natv:t A nIHv:forall (m0 : nat) (w0 : t A m0) (le0 : n <= n + m0), take n le0 (v ++ w0) = vm:natw:t A mle:S n <= S n + mtake (S n) le ((h :: v) ++ w) = h :: vA:Typeh:An:natv:t A nIHv:forall (m0 : nat) (w0 : t A m0) (le0 : n <= n + m0), take n le0 (v ++ w0) = vm:natw:t A mle:S n <= S n + mh :: take n (Le.le_S_n n (n + m) le) (v ++ w) = h :: vapply IHv. Qed. (* Proof is irrelevant for [take] *)A:Typeh:An:natv:t A nIHv:forall (m0 : nat) (w0 : t A m0) (le0 : n <= n + m0), take n le0 (v ++ w0) = vm:natw:t A mle:S n <= S n + mtake n (Le.le_S_n n (n + m) le) (v ++ w) = vforall (A : Type) (p n : nat) (v : t A n) (le le' : p <= n), take p le v = take p le' vforall (A : Type) (p n : nat) (v : t A n) (le le' : p <= n), take p le v = take p le' vA:Typen:natv:t A nle, le':0 <= ntake 0 le v = take 0 le' vA:Typep:natIHp:forall (n0 : nat) (v0 : t A n0) (le0 le'0 : p <= n0), take p le0 v0 = take p le'0 v0n:natv:t A nle, le':S p <= ntake (S p) le v = take (S p) le' vreflexivity.A:Typen:natv:t A nle, le':0 <= ntake 0 le v = take 0 le' vA:Typep:natIHp:forall (n0 : nat) (v0 : t A n0) (le0 le'0 : p <= n0), take p le0 v0 = take p le'0 v0n:natv:t A nle, le':S p <= ntake (S p) le v = take (S p) le' vA:Typep:natIHp:forall (n : nat) (v : t A n) (le0 le'0 : p <= n), take p le0 v = take p le'0 vle, le':S p <= 0take (S p) le [] = take (S p) le' []A:Typep:natIHp:forall (n0 : nat) (v0 : t A n0) (le0 le'0 : p <= n0), take p le0 v0 = take p le'0 v0h:An:natv:t A nle, le':S p <= S ntake (S p) le (h :: v) = take (S p) le' (h :: v)A:Typep:natIHp:forall (n0 : nat) (v0 : t A n0) (le0 le'0 : p <= n0), take p le0 v0 = take p le'0 v0h:An:natv:t A nle, le':S p <= S ntake (S p) le (h :: v) = take (S p) le' (h :: v)A:Typep:natIHp:forall (n0 : nat) (v0 : t A n0) (le0 le'0 : p <= n0), take p le0 v0 = take p le'0 v0h:An:natv:t A nle, le':S p <= S nh :: take p (Le.le_S_n p n le) v = h :: take p (Le.le_S_n p n le') vapply IHp. Qed.A:Typep:natIHp:forall (n0 : nat) (v0 : t A n0) (le0 le'0 : p <= n0), take p le0 v0 = take p le'0 v0h:An:natv:t A nle, le':S p <= S ntake p (Le.le_S_n p n le) v = take p (Le.le_S_n p n le') vA:Typeforall (n : nat) (a : A) (v : t A n), uncons (a :: v) = (a, v)reflexivity. Qed.A:Typeforall (n : nat) (a : A) (v : t A n), uncons (a :: v) = (a, v)A:Typeforall (n m : nat) (v : t A n) (w : t A m) (a : A), a :: v ++ w = (a :: v) ++ wreflexivity. Qed.A:Typeforall (n m : nat) (v : t A n) (w : t A m) (a : A), a :: v ++ w = (a :: v) ++ wA:Typeforall (n m : nat) (v : t A n) (w : t A m), splitat n (v ++ w) = (v, w)A:Typeforall (n m : nat) (v : t A n) (w : t A m), splitat n (v ++ w) = (v, w)A:Typen, m:natv:t A nforall w : t A m, splitat n (v ++ w) = (v, w)A:Typen:natv:t A nforall (m : nat) (w : t A m), splitat n (v ++ w) = (v, w)rewrite IHv... Qed.A:Typeh:An:natv:t A nIHv:forall (m0 : nat) (w0 : t A m0), splitat n (v ++ w0) = (v, w0)m:natw:t A m(let (v1, v2) := splitat n (v ++ w) in (h :: v1, v2)) = (h :: v, w)A:Typeforall (n m : nat) (v : t A n) (w : t A m) (vw : t A (n + m)), splitat n vw = (v, w) -> vw = v ++ wA:Typeforall (n m : nat) (v : t A n) (w : t A m) (vw : t A (n + m)), splitat n vw = (v, w) -> vw = v ++ wA:Typen, m:natv:t A nforall (w : t A m) (vw : t A (n + m)), splitat n vw = (v, w) -> vw = v ++ wA:Typen:natv:t A nforall (m : nat) (w : t A m) (vw : t A (n + m)), splitat n vw = (v, w) -> vw = v ++ wA:Typeh:An:natv:t A nIHv:forall (m0 : nat) (w0 : t A m0) (vw0 : t A (n + m0)), splitat n vw0 = (v, w0) -> vw0 = v ++ w0m:natw:t A mvw:t A (S n + m)H:splitat (S n) vw = (h :: v, w)H1:(let (v1, v2) := splitat n (tl vw) in (hd vw :: v1, v2)) = (h :: v, w)vw = (h :: v) ++ wA:Typeh:An:natv:t A nIHv:forall (m0 : nat) (w0 : t A m0) (vw0 : t A (n + m0)), splitat n vw0 = (v, w0) -> vw0 = v ++ w0m:natw:t A mvw:t A (S n + m)H:splitat (S n) vw = (h :: v, w)v':t A nw':t A mHeq:splitat n (tl vw) = (v', w')H1:(hd vw :: v', w') = (h :: v, w)vw = (h :: v) ++ wA:Typeh:An:natv:t A nIHv:forall (m0 : nat) (w0 : t A m0) (vw0 : t A (n + m0)), splitat n vw0 = (v, w0) -> vw0 = v ++ w0m:natw:t A mvw:t A (S n + m)H:splitat (S n) vw = (h :: v, w)v':t A nw':t A mHeq:splitat n (tl vw) = (v', w')H1:hd vw :: v' = h :: v /\ w' = wvw = (h :: v) ++ wA:Typeh:An:natv:t A nIHv:forall (m0 : nat) (w0 : t A m0) (vw0 : t A (n + m0)), splitat n vw0 = (v, w0) -> vw0 = v ++ w0m:natw:t A mvw:t A (S n + m)H:splitat (S n) vw = (h :: v, w)v':t A nHeq:splitat n (tl vw) = (v', w)H0:hd vw :: v' = h :: vvw = (h :: v) ++ wA:Typeh:An:natv:t A nIHv:forall (m0 : nat) (w0 : t A m0) (vw0 : t A (n + m0)), splitat n vw0 = (v, w0) -> vw0 = v ++ w0m:natw:t A mvw:t A (S n + m)H:splitat (S n) vw = (h :: v, w)v':t A nHeq:splitat n (tl vw) = (v', w)H0:hd vw :: v' = h :: vvw = h :: v ++ wA:Typeh:An:natv:t A nIHv:forall (m0 : nat) (w0 : t A m0) (vw0 : t A (n + m0)), splitat n vw0 = (v, w0) -> vw0 = v ++ w0m:natw:t A mvw:t A (S n + m)H:splitat (S n) vw = (h :: v, w)v':t A nHeq:splitat n (tl vw) = (v', w)H0:hd vw :: v' = h :: vhd vw :: tl vw = h :: v ++ wA:Typeh:An:natv:t A nIHv:forall (m0 : nat) (w0 : t A m0) (vw0 : t A (n + m0)), splitat n vw0 = (v, w0) -> vw0 = v ++ w0m:natw:t A mvw:t A (S n + m)H:splitat (S n) vw = (h :: v, w)v':t A nHeq:splitat n (tl vw) = (v', w)H0:hd vw = h /\ v' = vhd vw :: tl vw = h :: v ++ wA:Typen:natv:t A nIHv:forall (m0 : nat) (w0 : t A m0) (vw0 : t A (n + m0)), splitat n vw0 = (v, w0) -> vw0 = v ++ w0m:natw:t A mvw:t A (S n + m)H:splitat (S n) vw = (hd vw :: v, w)Heq:splitat n (tl vw) = (v, w)hd vw :: tl vw = hd vw :: v ++ wapply IHv... Qed.A:Typen:natv:t A nIHv:forall (m0 : nat) (w0 : t A m0) (vw0 : t A (n + m0)), splitat n vw0 = (v, w0) -> vw0 = v ++ w0m:natw:t A mvw:t A (S n + m)H:splitat (S n) vw = (hd vw :: v, w)Heq:splitat n (tl vw) = (v, w)tl vw = v ++ w