# Library Coq.Vectors.VectorSpec

Proofs of specification for functions defined over Vector
Author: Pierre Boutillier Institution: PPS, INRIA 12/2010

Require Fin.
Require Import VectorDef PeanoNat Eqdep_dec.
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.

Lemma eta {A} {n} (v : 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

## Properties of nth and nth_order

Lemma eq_nth_iff A n (v1 v2: t A n):
(forall p1 p2, p1 = p2 -> v1 [@ p1 ] = v2 [@ p2 ]) <-> v1 = v2.

Lemma nth_order_hd A: forall n (v : t A (S n)) (H : 0 < S n),
nth_order v H = hd v.

Lemma nth_order_tl A: forall n k (v : t A (S n)) (H : k < n) (HS : S k < S n),
nth_order (tl v) H = nth_order v HS.

Lemma nth_order_last A: forall n (v: t A (S n)) (H: n < S n),
nth_order v H = last v.

Lemma nth_order_ext A: forall n k (v : t A n) (H1 H2 : k < n),
nth_order v H1 = nth_order v H2.

## Properties of shiftin and shiftrepeat

Lemma shiftin_nth A a n (v: t A n) k1 k2 (eq: k1 = k2):
nth (shiftin a v) (Fin.L_R 1 k1) = nth v k2.

Lemma shiftin_last A a n (v: t A n): last (shiftin a v) = a.

Lemma shiftrepeat_nth A: forall n k (v: t A (S n)),
nth (shiftrepeat v) (Fin.L_R 1 k) = nth v k.

Lemma shiftrepeat_last A: forall n (v: t A (S n)), last (shiftrepeat v) = last v.

## Properties of replace

Lemma nth_order_replace_eq A: forall n k (v : t A n) a (H1 : k < n) (H2 : k < n),
nth_order (replace v (Fin.of_nat_lt H2) a) H1 = a.

Lemma nth_order_replace_neq A: forall n k1 k2, k1 <> k2 ->
forall (v : t A n) a (H1 : k1 < n) (H2 : k2 < n),
nth_order (replace v (Fin.of_nat_lt H2) a) H1 = nth_order v H1.

Lemma replace_id A: forall n p (v : t A n),
replace v p (nth v p) = v.

Lemma replace_replace_eq A: forall n p (v : t A n) a b,
replace (replace v p a) p b = replace v p b.

Lemma replace_replace_neq A: forall n p1 p2 (v : t A n) a b, p1 <> p2 ->
replace (replace v p1 a) p2 b = replace (replace v p2 b) p1 a.

## Properties of const

Lemma const_nth A (a: A) n (p: Fin.t n): (const a n)[@ p] = a.

## Properties of map

Lemma map_id A: forall n (v : t A n),
map (fun x => x) v = v.

Lemma map_map A B C: forall (f:A->B) (g:B->C) n (v : t A n),
map g (map f v) = map (fun x => g (f x)) v.

Lemma map_ext_in A B: forall (f g:A->B) n (v : t A n),
(forall a, In a v -> f a = g a) -> map f v = map g v.

Lemma map_ext A B: forall (f g:A->B), (forall a, f a = g a) ->
forall n (v : t A n), map f v = map g v.

Lemma nth_map {A B} (f: A -> B) {n} v (p1 p2: Fin.t n) (eq: p1 = p2):
(map f v) [@ p1] = f (v [@ p2]).

Lemma nth_map2 {A B C} (f: A -> B -> C) {n} v w (p1 p2 p3: Fin.t n):
p1 = p2 -> p2 = p3 -> (map2 f v w) [@p1] = f (v[@p2]) (w[@p3]).

## Properties of fold_left

Lemma fold_left_right_assoc_eq {A B} {f: A -> B -> A}
(assoc: forall a b c, f (f a b) c = f (f a c) b)
{n} (v: t B n): forall a, fold_left f a v = fold_right (fun x y => f y x) v a.

## Properties of take

Lemma take_O : forall {A} {n} le (v:t A n), take 0 le v = [].

Lemma take_idem : forall {A} p n (v:t A n) le le',
take p le' (take p le v) = take p le v.

Lemma take_app : forall {A} {n} (v:t A n) {m} (w:t A m) le, take n le (append v w) = v.

Lemma take_prf_irr : forall {A} p {n} (v:t A n) le le', take p le v = take p le' v.

## Properties of uncons and splitat

Lemma uncons_cons {A} : forall {n : nat} (a : A) (v : t A n),
uncons (a::v) = (a,v).

Lemma append_comm_cons {A} : forall {n m : nat} (v : t A n) (w : t A m) (a : A),
a :: (v ++ w) = (a :: v) ++ w.

Lemma splitat_append {A} : forall {n m : nat} (v : t A n) (w : t A m),
splitat n (v ++ w) = (v, w).

Lemma append_splitat {A} : forall {n m : nat} (v : t A n) (w : t A m) (vw : t A (n+m)),
splitat n vw = (v, w) ->
vw = v ++ w.

## Properties of Forall and Forall2

Lemma Forall_impl A: forall (P Q : A -> Prop), (forall a, P a -> Q a) ->
forall n (v : t A n), Forall P v -> Forall Q v.

Lemma Forall_forall A: forall P n (v : t A n),
Forall P v <-> forall a, In a v -> P a.

Lemma Forall_nth_order A: forall P n (v : t A n),
Forall P v <-> forall i (Hi : i < n), P (nth_order v Hi).

Lemma Forall2_nth_order A: forall P n (v1 v2 : t A n),
Forall2 P v1 v2
<-> forall i (Hi1 : i < n) (Hi2 : i < n), P (nth_order v1 Hi1) (nth_order v2 Hi2).