HyPre.util.VectorExtra
(* CLN B *)
From Coq Require Vectors.Vector.
From Coq Require Export Lists.List.
From Coq Require Import Equality.
Import ListNotations.
From HyPre Require Export
Tac
ListExtra.
From Coq Require Vectors.Vector.
From Coq Require Export Lists.List.
From Coq Require Import Equality.
Import ListNotations.
From HyPre Require Export
Tac
ListExtra.
Facts about Vectors
Definition t_combine {A B : Type} {n : nat}
:= Vector.map2 (n:=n) (@pair A B).
Lemma t_combine_fst {k} {X Y : Type} (a : Vector.t X k) (b : Vector.t Y k)
: Vector.map fst (t_combine a b) = a.
Proof.
dependent induction a;dependent destruction b;cbn.
- reflexivity.
- f_equal.
eapply IHa.
Qed.
Lemma t_combine_snd {k} {X Y : Type} (a : Vector.t X k) (b : Vector.t Y k)
: Vector.map snd (t_combine a b) = b.
Proof.
dependent induction a;dependent destruction b;cbn.
- reflexivity.
- f_equal.
eapply IHa.
Qed.
Lemma t_combine_self {k} {X Y : Type} (a : Vector.t (X * Y) k)
: a = t_combine (Vector.map fst a) (Vector.map snd a).
Proof.
dependent induction a;cbn.
- reflexivity.
- f_equal.
+ eapply surjective_pairing.
+ eapply IHa.
Qed.
Definition map3 {A B C D : Type}
(f : A -> B -> C -> D) {n : nat}
: Vector.t A n -> Vector.t B n -> Vector.t C n -> Vector.t D n
:= fun att bt => Vector.map2 (fun (ab : A*B) => let (a,b) := ab in f a b) (t_combine att bt).
Fixpoint map4 {A B C D E : Type}
(f : A -> B -> C -> D -> E) {n : nat}
(a : Vector.t A n) (b : Vector.t B n) (c : Vector.t C n) (d : Vector.t D n)
: Vector.t E n.
Proof.
dependent destruction a;
dependent destruction b;
dependent destruction c;
dependent destruction d.
- econstructor.
- econstructor.
+ eapply f;eauto.
+ eapply map4;eauto.
Defined.
Lemma vec_map2_map2_map4 {A B C D X Y Z : Type}
(f1 : A -> B -> X)
(f2 : C -> D -> Y)
(g : X -> Y -> Z)
{n : nat}
(a : Vector.t A n) (b : Vector.t B n) (c : Vector.t C n) (d : Vector.t D n)
: Vector.map2 g (Vector.map2 f1 a b) (Vector.map2 f2 c d)
= map4 (fun a' b' c' d' => g (f1 a' b') (f2 c' d')) a b c d.
Proof.
dependent induction a;
dependent destruction b;
dependent destruction c;
dependent destruction d;
cbn.
- reflexivity.
- f_equal.
eapply IHa.
Qed.
Lemma vec_map4_ext {A B C D E : Type}
(f f' : A -> B -> C -> D -> E) {n : nat}
(H : forall a' b' c' d', f a' b' c' d' = f' a' b' c' d')
(a : Vector.t A n) (b : Vector.t B n) (c : Vector.t C n) (d : Vector.t D n)
: map4 f a b c d = map4 f' a b c d.
Proof.
dependent induction a;
dependent destruction b;
dependent destruction c;
dependent destruction d;
cbn.
- reflexivity.
- f_equal.
+ eapply H.
+ eapply IHa.
Qed.
Definition repl {X : Type} {k : nat} : Vector.t X k -> Vector.t X k -> Vector.t bool k -> Vector.t X k
:= map3 (fun x y (b : bool) => if b then y else x).
Fixpoint vb_zero (k:nat) : Vector.t bool k
:= match k with
| O => Vector.nil _
| S k' => Vector.cons _ false _ (vb_zero k')
end.
Lemma Vector_Forall_dec {X : Type} {n : nat} (xt : Vector.t X n) (f : X -> bool)
: {Vector.Forall (fun x => f x = true) xt} + {Vector.Exists (fun x => f x = false) xt}.
Proof.
dependent induction xt;cbn.
- left.
eapply Vector.Forall_nil.
- specialize (IHxt f).
destruct IHxt.
+ destruct (f h) eqn:E.
* left.
econstructor;eauto.
* right.
econstructor;eauto.
+ right.
eapply Vector.Exists_cons_tl.
assumption.
Qed.
Lemma Vector_Exists_nth {X : Type} {n : nat} (P : X -> Prop) (xt : Vector.t X n)
: Vector.Exists P xt -> exists (i : Fin.t n), P (Vector.nth xt i).
Proof.
intros.
dependent induction H.
- exists (Fin.F1).
cbn.
assumption.
- destruct IHExists.
exists (Fin.FS x0).
cbn.
assumption.
Qed.
Lemma vec_nth_nth_order {X : Type} {k} (xt : Vector.t X k) (i : Fin.t k)
: Vector.nth xt i = Vector.nth_order xt (proj2_sig (Fin.to_nat i)).
Proof.
unfold Vector.nth_order.
f_equal.
eapply Fin.to_nat_inj.
rewrite Fin.to_nat_of_nat.
cbn.
reflexivity.
Qed.
Lemma Vector_nth_replace {X : Type} {n : nat} (xt : Vector.t X n) (i : Fin.t n) (x : X)
: Vector.nth (Vector.replace xt i x) i = x.
Proof.
rewrite vec_nth_nth_order.
setoid_rewrite <-Vector.nth_order_replace_eq
with (a:=x) (v:=xt) (H1:=proj2_sig (Fin.to_nat i)) (H2:=proj2_sig (Fin.to_nat i)) at 2.
f_equal.
f_equal.
eapply Fin.to_nat_inj.
rewrite Fin.to_nat_of_nat.
cbn.
reflexivity.
Qed.
Notation "a [[ i ]]" := (Vector.nth a i) (at level 40).
Lemma Vec_Forall2_forall2 {k : nat} (X Y : Type) (P : X -> Y -> Prop) (xt : Vector.t _ k) yt
: Vector.Forall2 P xt yt <-> forall i, P (Vector.nth xt i) (Vector.nth yt i).
Proof.
split;intros.
- dependent induction H.
+ inversion i.
+ dependent destruction i;cbn;eauto.
- dependent induction xt;dependent destruction yt.
+ econstructor.
+ econstructor.
* specialize (H Fin.F1).
cbn in H.
assumption.
* eapply IHxt.
intros.
specialize (H (Fin.FS i)).
cbn in H.
assumption.
Qed.
Inductive Vec_Forall3 {A B C : Type} (P : A -> B -> C -> Prop)
: forall {n : nat}, Vector.t A n -> Vector.t B n -> Vector.t C n -> Prop
:=
| Forall3_nil : Vec_Forall3 P (Vector.nil A) (Vector.nil B) (Vector.nil C)
| Forall3_cons :
forall (m : nat) (x1 : A) (x2 : B) (x3 : C) (v1 : Vector.t A m) (v2 : Vector.t B m) (v3 : Vector.t C m),
P x1 x2 x3 -> Vec_Forall3 P v1 v2 v3
-> Vec_Forall3 P (Vector.cons A x1 m v1) (Vector.cons B x2 m v2) (Vector.cons C x3 m v3).
Lemma vec_0_nil {X : Type} (v : Vector.t X 0)
: v = Vector.nil X.
Proof.
revert v.
eapply Vector.case0.
reflexivity.
Qed.
Lemma vec_nil_eq {X : Type} (v v' : Vector.t X 0)
: v = v'.
Proof.
rewrite vec_0_nil. rewrite vec_0_nil at 1.
reflexivity.
Qed.
From Coq Require Import Lia.
Lemma le_inv_S (n m : nat)
: S n <= m -> S (m - S n) <= m.
Proof.
lia.
Qed.
Fixpoint vec_mapi' {k} {A B : Type} {n : nat} (H : n <= k) (f : Fin.t k -> A -> B) (a : Vector.t A n) : Vector.t B n :=
match a in (Vector.t _ n0) return (n0 <= k -> Vector.t B n0) with
| Vector.nil _ => fun _ : 0 <= k => Vector.nil B
| Vector.cons _ h n0 t =>
(fun (h0 : A) (n1 : nat) (a0 : Vector.t A n1) (H0 : S n1 <= k) =>
Vector.cons B (f (Fin.of_nat_lt (le_inv_S _ _ H0)) h0) n1 (vec_mapi' (Le.le_Sn_le_stt n1 k H0) f a0)) h n0 t
end H.
Definition vec_mapi {k} :
forall {A B : Type}, (Fin.t k -> A -> B) -> Vector.t A k -> Vector.t B k
:= (fun (A B : Type) (X : Fin.t k -> A -> B) (X0 : Vector.t A k) => vec_mapi' (le_n k) X X0).
Fixpoint vec_mapi2' {k} {A B C : Type} {n : nat} (H : n <= k)
(f : Fin.t k -> A -> B -> C) (a : Vector.t A n) (b : Vector.t B n) : Vector.t C n.
Proof.
remember n as n'.
rewrite Heqn' in a.
destruct a, b.
2,3:congruence.
- econstructor.
- econstructor.
+ eapply f;eauto.
eapply le_inv_S in H.
eapply (Fin.of_nat_lt H).
+ eapply vec_mapi2'.
2,4: eassumption.
* eapply Le.le_Sn_le_stt.
eassumption.
* erewrite eq_add_S;eauto.
Defined.
Definition vec_mapi2 {k} :
forall {A B C : Type}, (Fin.t k -> A -> B -> C) -> Vector.t A k -> Vector.t B k -> Vector.t C k
:= (fun (A B C : Type) (f : Fin.t k -> A -> B -> C) => vec_mapi2' (le_n k) f).
Lemma vec_fold_left_max_start {k} (a : Vector.t nat k)
: forall x y, x <= y -> x <= Vector.fold_left Nat.max y a.
Proof.
dependent induction a;cbn;intros.
- assumption.
- setoid_rewrite <-IHa;eauto.
lia.
Qed.
Lemma Vec_fold_left_max {k}
: forall (a : Vector.t nat k) i x, a [[i]] <= Vector.fold_left Nat.max x a.
Proof.
intros.
dependent induction a; dependent destruction i;cbn.
- setoid_rewrite <-vec_fold_left_max_start.
+ reflexivity.
+ lia.
- rewrite IHa.
reflexivity.
Qed.
Local Arguments Fin.F1 : clear implicits.
Local Arguments Fin.of_nat_lt : clear implicits.
Lemma of_nat_lt_eq_eq (k x y : nat) (Qx : x < k) (Qy : y < k) (H : x = y)
: Fin.of_nat_lt x k Qx = Fin.of_nat_lt y k Qy.
Proof.
revert k y Qx Qy H.
induction x;destruct y;intros;try congruence.
- eapply Fin.of_nat_ext.
- destruct k;cbn.
+ exfalso. lia.
+ match goal with |- _ = _ (_ _ _ ?Q) => rewrite IHx with (y:=y) (Qy:=Q) at 1 end.
* reflexivity.
* lia.
Qed.
Lemma vec_nth_mapi2' {A B C : Type} {k n} (Hle : n <= k)
(f : Fin.t k -> A -> B -> C) (a b : Vector.t _ n) (i : Fin.t n) (i' : Fin.t k)
(Heq : proj1_sig (Fin.to_nat i) + k - n = proj1_sig (Fin.to_nat i'))
: vec_mapi2' Hle f a b [[i]] = f i' (a [[i]]) (b [[i]]).
Proof.
dependent induction a; dependent destruction b;dependent destruction i;[cbn|].
- f_equal.
cbn in Heq.
rewrite <-Fin.of_nat_to_nat_inv with (p:=i').
eapply of_nat_lt_eq_eq;eauto.
- cbn. setoid_rewrite <-IHa. reflexivity.
cbn in Heq.
destruct (Fin.to_nat i).
cbn in Heq. cbn.
assumption.
Qed.
Lemma Vec_nth_mapi2 {A B C : Type} {k} (f : Fin.t k -> A -> B -> C) (a b : Vector.t _ k) (i : Fin.t k)
: vec_mapi2 f a b [[i]] = f i (a [[i]]) (b [[i]]).
Proof.
eapply vec_nth_mapi2'.
lia.
Qed.
Lemma vec_mapi_nth' {k} {X Y : Type} (f : Fin.t k -> X -> Y) n
(Hle : n <= k)
(x : Vector.t X n) (i : Fin.t n) (i' : Fin.t k)
(Heq : proj1_sig (Fin.to_nat i) + k - n = proj1_sig (Fin.to_nat i'))
: vec_mapi' Hle f x [[i]] = f i' (x [[i]]).
Proof.
dependent induction x; dependent destruction i;cbn.
- f_equal.
cbn in Heq.
rewrite <-Fin.of_nat_to_nat_inv with (p:=i').
eapply of_nat_lt_eq_eq;eauto.
- cbn. setoid_rewrite <-IHx. reflexivity.
cbn in Heq.
destruct (Fin.to_nat i).
cbn in Heq. cbn.
assumption.
Qed.
Lemma vec_mapi_nth {k} {X Y : Type} (f : Fin.t k -> X -> Y) (xt : Vector.t X k) (i : Fin.t k)
: vec_mapi f xt [[i]] = f i (xt [[i]]).
Proof.
eapply vec_mapi_nth'.
lia.
Qed.
Lemma Vec_nth_map2 {k} {A B C : Type} (f : A -> B -> C) (a b : Vector.t _ k) (i : Fin.t k)
: Vector.map2 f a b [[i]] = f (a [[i]]) (b [[i]]).
Proof.
dependent induction a; dependent destruction b; dependent destruction i;cbn.
- reflexivity.
- eapply IHa.
Qed.
Lemma vec_map_const {k} {X Y : Type} (f : X -> Y) x
: Vector.map f (Vector.const x k) = Vector.const (f x) k.
Proof.
clear.
induction k;cbn.
- reflexivity.
- rewrite IHk. reflexivity.
Qed.
Lemma vec_map_map2 {k} {W X Y Z : Type} (f : Z -> W) (g : X -> Y -> Z) (x y : Vector.t _ k)
: Vector.map f (Vector.map2 g x y) = Vector.map2 (fun x y => f (g x y)) x y.
Proof.
clear.
dependent induction x; dependent destruction y.
- cbn. reflexivity.
- cbn. rewrite IHx. reflexivity.
Qed.
Lemma vec_map2_ext {k} {X Y Z : Type} (f g : X -> Y -> Z)
: (forall x y, f x y = g x y) -> forall (xt yt : Vector.t _ k), Vector.map2 f xt yt = Vector.map2 g xt yt.
Proof.
clear.
intros.
dependent induction k;cbn.
- dependent destruction xt. dependent destruction yt.
cbn. reflexivity.
- dependent destruction xt. dependent destruction yt.
cbn. setoid_rewrite IHk. 2,3: eauto. rewrite H. reflexivity.
Qed.
Lemma vec_map2_fun_app {k} {X X1 Y Y1 Z : Type}
(fx : X -> X1) (fy : Y -> Y1) (g : X1 -> Y1 -> Z) (xt yt : Vector.t _ k)
: Vector.map2 (fun x y => g (fx x) (fy y)) xt yt = Vector.map2 g (Vector.map fx xt) (Vector.map fy yt).
Proof.
clear.
dependent induction xt; dependent destruction yt;cbn.
- reflexivity.
- rewrite IHxt. reflexivity.
Qed.
Definition vl_zero {X : Type} {k : nat} := Vector.const (@nil X) k.
Fixpoint vec_descending (k : nat) {struct k} : Vector.t (Fin.t k) k
:= match k with
| O => Vector.nil _
| (S k') => Vector.cons _ (@Fin.F1 k') _ (Vector.map Fin.FS (vec_descending k'))
end.
Lemma vec_descending_S (k : nat)
: vec_descending (S k) = Vector.cons _ (@Fin.F1 k) _ (Vector.map Fin.FS (vec_descending k)).
Proof.
reflexivity.
Qed.
Definition vec_ascending (k : nat) : Vector.t (Fin.t k) k
:= Vector.rev (vec_descending k).
Definition fin_pred_to_vec {X : Type} {k : nat} (f : Fin.t k -> X) : Vector.t X k
:= Vector.map f (vec_ascending k).
Require Import Lia.
From Coq Require Import NPeano.
Definition vec_k1_sk {X : Type} {k : nat} : Vector.t X (k + 1) -> Vector.t X (S k).
Proof.
intro xv.
remember (k+1).
revert dependent k.
induction xv.
- intros. rewrite Nat.add_1_r in Heqn. congruence.
- intros.
econstructor.
+ assumption.
+ destruct k;intros.
* cbn in Heqn.
destruct n;[|congruence].
assumption.
* eapply IHxv. lia.
Defined.
Definition vec_rcons {X : Type} {k : nat} (xv : Vector.t X k) (x : X)
: Vector.t X (S k)
:= vec_k1_sk (Vector.append xv (Vector.const x 1)).
Fixpoint vec_rev {k : nat} {X : Type} (xt : Vector.t X k)
: Vector.t X k
:= match xt with
| Vector.nil _ => Vector.nil X
| Vector.cons _ x n yt => vec_rcons (vec_rev yt) x
end.
Lemma list_eq_vec_eq {k : nat} {X : Type} (v v' : Vector.t X k)
: Vector.to_list v = Vector.to_list v' -> v = v'.
Proof.
match goal with |- ?g => enough (forall l, l = Vector.to_list v -> l = Vector.to_list v' -> g) as Q end.
{ intros;eapply Q;eauto. }
intros.
revert dependent l.
clear H1.
dependent induction v;dependent destruction v';intros.
- reflexivity.
- destruct l;[cbn in H,H0;congruence|].
rewrite Vector.to_list_cons in H, H0.
inversion H.
inversion H0.
f_equal.
+ subst h. subst h0.
reflexivity.
+ eapply IHv;eauto.
Qed.
Lemma vec_rev_rev {X : Type} {k : nat} (xv : Vector.t X k)
: Vector.rev (Vector.rev xv) = xv.
Proof.
eapply list_eq_vec_eq.
setoid_rewrite Vector.to_list_rev.
setoid_rewrite Vector.to_list_rev.
eapply rev_involutive.
Qed.
Lemma vec_rev_rev_eq {X : Type} {k : nat} (x y : Vector.t X k)
: Vector.rev x = Vector.rev y -> x = y.
Proof.
intros.
rewrite <-vec_rev_rev.
rewrite <-vec_rev_rev at 1.
rewrite H. reflexivity.
Qed.
Lemma vec_eq_rev_rev {X : Type} {k : nat} (x y : Vector.t X k)
: x = y -> Vector.rev x = Vector.rev y.
Proof.
intros.
subst. reflexivity.
Qed.
Lemma Vec_Forall3_eq {X Y : Type} {k : nat} (xt : Vector.t X k) (yt1 yt2 : Vector.t Y k)
: Vec_Forall3 (fun x y1 y2 => y1 = y2) xt yt1 yt2 -> yt1 = yt2.
Proof.
intros H.
induction H.
- reflexivity.
- f_equal;eauto.
Qed.
Lemma vector_forall_nth {X : Type} (k : nat) (a : Vector.t X k) P
: Vector.Forall P a -> forall i, P (a[[i]]).
Proof.
intros H i.
induction H.
- inversion i.
- dependent destruction i.
+ cbn.
eauto.
+ cbn.
eauto.
Qed.
Lemma vector_Forall2_cons_inv {X Y : Type} (x : X) (y : Y) (k : nat) a b P
: Vector.Forall2 P (Vector.cons X x k a) (Vector.cons Y y k b)
-> P x y /\ Vector.Forall2 P a b.
Proof.
intros.
dependent destruction H.
split;eauto.
Qed.
Lemma vec_append_const {k k'} {X : Type} (x : X)
: Vector.append (Vector.const x k) (Vector.const x k') = Vector.const x (k+k').
Proof.
dependent induction k;cbn.
- reflexivity.
- f_equal.
eapply IHk.
Qed.
Lemma vec_forall3_forall {k} {X Y Z : Type} (f : X -> Y -> Z -> Prop) (x y z : Vector.t _ k)
: Vec_Forall3 f x y z <-> (forall i, f (x[[i]]) (y[[i]]) (z[[i]])).
Proof.
split;intros.
- dependent induction H.
+ inversion i.
+ dependent destruction i;cbn;eauto.
- dependent induction x;dependent destruction y;dependent destruction z.
+ econstructor.
+ econstructor.
* specialize (H (@Fin.F1 ( n))).
cbn in H.
assumption.
* eapply IHx.
intros.
specialize (H (Fin.FS i)).
cbn in H.
assumption.
Qed.
Lemma vec_append_rev {k} {X : Type} (x : Vector.t X k) (y : Vector.t X k)
: Vector.append (Vector.rev x) (Vector.rev y) = Vector.rev (Vector.append y x).
Proof.
eapply list_eq_vec_eq.
rewrite Vector.to_list_append.
setoid_rewrite Vector.to_list_rev.
rewrite <-rev_app_distr.
rewrite Vector.to_list_append.
reflexivity.
Qed.
Lemma vec_const_cons {k : nat} {X : Type} (x : X)
: Vector.const x (S k) = Vector.cons _ x k (Vector.const x k).
Proof.
cbn.
reflexivity.
Qed.
Lemma vec_take_const {k k'} {X : Type} (x : X) (Hleq : k' <= k)
: Vector.take _ Hleq (Vector.const x k) = Vector.const x k'.
Proof.
revert dependent k.
dependent induction k';intros;cbn.
- reflexivity.
- dependent destruction k.
+ lia.
+ rewrite vec_const_cons.
f_equal.
specialize (IHk' _ x _ (le_S_n k' k Hleq)).
assumption.
Qed.
Lemma vec_rev_nil {X : Type}
: Vector.rev (Vector.nil X) = Vector.nil X.
Proof.
eapply list_eq_vec_eq.
rewrite Vector.to_list_rev.
cbn.
reflexivity.
Qed.
Lemma vec_rev_const {k} {X : Type} (x : X)
: Vector.rev (Vector.const x k) = Vector.const x k.
Proof.
eapply list_eq_vec_eq.
rewrite Vector.to_list_rev.
rewrite Vector.to_list_const.
eapply rev_repeat.
Qed.
Lemma vec_take_map2 {k n} {X Y Z : Type} (H : k <= n) (f : X -> Y -> Z) (x y : Vector.t _ n)
: Vector.take _ H (Vector.map2 f x y) = Vector.map2 f (Vector.take _ H x) (Vector.take _ H y).
Proof.
revert dependent k.
revert dependent y.
dependent induction x;dependent destruction y;intros;cbn.
- dependent destruction H. cbn.
reflexivity.
- dependent destruction k;cbn.
+ reflexivity.
+ rewrite IHx.
reflexivity.
Qed.
Lemma vec_to_list_map2 {k} {X Y Z : Type} (f : X -> Y -> Z) (x y : Vector.t _ k)
: Vector.to_list (Vector.map2 f x y) = map2 f (Vector.to_list x) (Vector.to_list y).
Proof.
dependent induction x; dependent destruction y.
- cbn.
reflexivity.
- rewrite Vector.to_list_cons.
match goal with |- _ ?x = _ => cbn_this x end.
setoid_rewrite Vector.to_list_cons.
cbn.
rewrite IHx.
reflexivity.
Qed.
Lemma vec_rev_map2 {k} {X Y Z : Type} (f : X -> Y -> Z) (x y : Vector.t _ k)
: Vector.rev (Vector.map2 f x y) = Vector.map2 f (Vector.rev x) (Vector.rev y).
Proof.
eapply list_eq_vec_eq.
rewrite Vector.to_list_rev.
setoid_rewrite vec_to_list_map2.
setoid_rewrite Vector.to_list_rev.
rewrite rev_map2.
- reflexivity.
- setoid_rewrite Vector.length_to_list.
reflexivity.
Qed.
Lemma vec_to_list_nth {k} {X : Type} (x : X) (a : Vector.t X k) (i : Fin.t k)
: a [[i]] = nth (proj1_sig (Fin.to_nat i)) (Vector.to_list a) x.
Proof.
dependent induction a.
- inversion i.
- dependent destruction i;[cbn;eauto|].
match goal with |- _ = nth ?x ?y ?z => cbn_this x end.
destruct (Fin.to_nat i) eqn:E.
match goal with |- _ = nth ?x ?y ?z => cbn_this x end.
rewrite Vector.to_list_cons.
cbn.
rewrite IHa.
rewrite E.
match goal with |- nth ?x ?y ?z = _ => cbn_this x end.
reflexivity.
Qed.
Lemma vec_rev_nth {k} {X : Type} (a : Vector.t X k) (i j : Fin.t k)
: k = S (proj1_sig (Fin.to_nat i) + proj1_sig (Fin.to_nat j)) -> (Vector.rev a) [[i]] = a [[j]].
Proof.
intros.
assert (x : X).
{
destruct a.
- inversion i.
- exact h.
}
setoid_rewrite vec_to_list_nth with (x:=x).
rewrite Vector.to_list_rev.
eapply rev_nth_eq.
rewrite Vector.length_to_list.
assumption.
Qed.
Lemma vec_map_app {k1 k2 : nat} {X Y : Type}
(f : X -> Y) (xt1 : Vector.t _ k1) (xt2 : Vector.t _ k2)
: Vector.map f (Vector.append xt2 xt1)
= Vector.append (Vector.map f xt2) (Vector.map f xt1).
Proof.
dependent induction xt2;cbn.
- reflexivity.
- f_equal.
eapply IHxt2.
Qed.
(*Lemma vec_map2_app_gen {k1 k2 : nat} {X Y : Type -> Type} {X1 X2 Y1 Y2 Z : Type}
(f : forall {V W}, X V -> Y W -> Z)
(xt1 : Vector.t (X X1) k1) (yt1 : Vector.t (Y Y1) k1)
(xt2 : Vector.t (X X2) k2) (yt2 : Vector.t (Y Y2) k2)
: Vector.map2 f (Vector.append xt2 xt1) (Vector.append yt2 yt1)
= Vector.append (Vector.map2 f xt2 yt2) (Vector.map2 f xt1 yt1).
Proof.
*)
Lemma vec_map2_app {k1 k2 : nat} {X Y Z : Type}
(f : X -> Y -> Z) (xt1 yt1 : Vector.t _ k1) (xt2 yt2 : Vector.t _ k2)
: Vector.map2 f (Vector.append xt2 xt1) (Vector.append yt2 yt1)
= Vector.append (Vector.map2 f xt2 yt2) (Vector.map2 f xt1 yt1).
Proof.
dependent induction xt2; dependent destruction yt2;cbn.
- reflexivity.
- f_equal.
eapply IHxt2.
Qed.
Lemma vec_map_cons {X Y : Type} {k : nat} (f : X -> Y) x (xv : Vector.t X k)
: Vector.map f (Vector.cons _ x _ xv) = Vector.cons _ (f x) _ (Vector.map f xv).
Proof.
reflexivity.
Qed.
Lemma vec_take_cons {k n} {X : Type} (H : S k <= S n) (xt : Vector.t X n) x
: Vector.take (S k) H (Vector.cons _ x n xt) = Vector.cons _ x k (Vector.take k (le_S_n _ _ H) xt).
Proof.
cbn.
reflexivity.
Qed.
Lemma vec_to_list_take {k n} {X : Type} (H : k <= n) (x : Vector.t X n)
: Vector.to_list (Vector.take k H x) = firstn k (Vector.to_list x).
Proof.
revert dependent k.
dependent induction x;intros.
- cbn.
inversion H.
subst k.
rewrite Vector.take_O.
cbn.
reflexivity.
- dependent destruction k.
+ cbn.
reflexivity.
+ rewrite vec_take_cons.
setoid_rewrite Vector.to_list_cons.
setoid_rewrite firstn_cons.
f_equal.
eapply IHx.
Qed.
Lemma vec_map2_map2_assoc {X Y Z : Type} {k} (f : X -> Y -> Y) (g : Y -> Z -> Y)
(Hassoc : forall x y z, f x (g y z) = g (f x y) z)
: forall (xt yt zt : Vector.t _ k), Vector.map2 f xt (Vector.map2 g yt zt) = Vector.map2 g (Vector.map2 f xt yt) zt.
Proof.
intro xt.
dependent induction xt;intros;
dependent destruction yt;
dependent destruction zt;
cbn.
- reflexivity.
- f_equal;eauto.
Qed.
Lemma vec_map2_const1 {X Y Z : Type} {k} (f : X -> Y -> Z)
: forall (yt : Vector.t _ k) x, Vector.map2 f (Vector.const x k) yt = Vector.map (f x) yt.
Proof.
intros yt.
dependent induction yt;
intros;cbn.
- reflexivity.
- f_equal;eauto.
Qed.
Lemma vec_map2_const2 {X Y Z : Type} {k} (f : X -> Y -> Z)
: forall (xt : Vector.t _ k) y, Vector.map2 f xt (Vector.const y k) = Vector.map (fun x => f x y) xt.
Proof.
intros xt.
dependent induction xt;
intros;cbn.
- reflexivity.
- f_equal;eauto.
Qed.
Lemma vec_forall2_nth {X Y : Type} (k : nat) (a : Vector.t X k) (b : Vector.t Y k) (P : X -> Y -> Prop)
: Vector.Forall2 P a b -> forall i : Fin.t k, P (a [[i]]) (b [[i]]).
Proof.
dependent induction a;
dependent destruction b;
dependent destruction i;
dependent destruction H;
cbn.
- assumption.
- eapply IHa.
eauto.
Qed.
Lemma vec_Forall_forall {k} {A : Type} (a : Vector.t A k) P
: Vector.Forall P a <-> (forall i, P (a[[i]])).
Proof.
split;[eapply vector_forall_nth|].
intros.
dependent induction a.
- econstructor.
- econstructor.
+ specialize (H (@Fin.F1 _)).
cbn in H.
assumption.
+ eapply IHa.
intros i.
specialize (H (Fin.FS i)).
cbn in H.
assumption.
Qed.
Lemma vec_forall2_map_eq {k} {X Y : Type} (f : X -> Y) (xl1 xl2 : Vector.t _ k)
: Vector.Forall2 (fun x y => f x = f y) xl1 xl2 -> Vector.map f xl1 = Vector.map f xl2.
Proof.
intros.
dependent induction H;eauto.
setoid_rewrite vec_map_cons.
f_equal;eauto.
Qed.
Lemma vec_forall2_impl {k} {X Y : Type} (P Q : X -> Y -> Prop) (xt yt : Vector.t _ k)
: (forall x y, P x y -> Q x y) -> Vector.Forall2 P xt yt -> Vector.Forall2 Q xt yt.
Proof.
intros.
induction H0;econstructor;eauto.
Qed.
Lemma vec_forall3_impl {k} {X Y Z : Type} (P Q : X -> Y -> Z -> Prop) (xt yt zt : Vector.t _ k)
: (forall x y z, P x y z -> forall x', Q x' y z) -> Vec_Forall3 P xt yt zt -> Vec_Forall3 Q xt yt zt.
Proof.
intros.
induction H0;econstructor;eauto.
Qed.
Lemma vec_forall3_forall2_1 {k : nat} {X Y Z : Type} (g : Y -> Z -> Prop) (xt yt zt : Vector.t _ k)
: Vec_Forall3 (fun (_ : X) y z => g y z) xt yt zt -> Vector.Forall2 g yt zt.
Proof.
intros.
dependent induction H;econstructor;eauto.
Qed.
Lemma vec_nth_eq {k : nat} {X : Type} (x y : Vector.t X k)
: x = y -> forall i, x [[i]] = y [[i]].
Proof.
clear.
intros.
subst x.
reflexivity.
Qed.
Lemma vec_nth_eq2 {X : Type} a
: a = Vector.cons _ (a [[@Fin.F1 _]]) _ (Vector.cons _ (a [[Fin.FS (@Fin.F1 _)]]) _ (Vector.nil X)).
Proof using.
clear.
dependent destruction a;cbn.
dependent destruction a;cbn.
dependent destruction a;cbn.
reflexivity.
Qed.