Section tabulate_vec.
Variable X : Type.
Fixpoint tabulate (n : nat) (f : Fin.t n -> X) {struct n} : Vector.t X n.
End tabulate_vec.
(* Lemma vec_replace_nth X x n (t : Vector.t X n) (i : Fin.t n) : x = Vector.nth (Vector.replace t i x) i.  Lemma vec_replace_nth_nochange X x n (t : Vector.t X n) (i j : Fin.t n) : Fin.to_nat i <> Fin.to_nat j -> Vector.nth t i = Vector.nth (Vector.replace t j x) i. *)
Instance Vector_eq_dec n A: eq_dec A -> eq_dec (Vector.t A n).
(* Tactic for simplifying a hypothesis of the form [In x v] *)
Ltac simpl_vector_inv :=
repeat match goal with
| [ H : [| |] = (_ ::: _) |- _ ] => solve [discriminate H]
| [ H : (_ ::: _) = [| |]  |- _ ] => solve [discriminate H]
| [ H : Fin.F1 = Fin.FS _ |- _] => solve [discriminate H]
| [ H : Fin.FS _ = Fin.F1 |- _] => solve [discriminate H]
| [ H : Fin.FS ?i = Fin.FS ?j |- _] =>
simple apply Fin.FS_inj in H;
first [is_var i;move H at bottom;subst i | is_var j;move H at bottom;subst j | idtac]
end.
Ltac simpl_vector_in :=
repeat
match goal with
| _ => first
[ progress destruct_vector_in
| progress simpl_vector_inv
| progress auto
| congruence
]
| [ H : Vector.In _ (Vector.map _ _) |- _] =>
let x := fresh "x" in
eapply vect_in_map_iff in H as (x&<-&H)
| [ H : Vector.In _ (Vector.map _ _) |- _] =>
let x := fresh "x" in
let H' := fresh H in
eapply vect_in_map_iff in H as (x&H&H')
| [ H : Vector.In _ (tabulate _) |- _ ] =>
let i := fresh "i" in
apply in_tabulate in H as (i&->)
| [ H : Vector.In _ (tabulate _) |- _ ] =>
let i := fresh "i" in
let H := fresh "H" in
apply in_tabulate in H as (i&H)
end.
Ltac vector_not_in :=
let H := fresh "H" in
intros H; simpl_vector_in.
Goal Vector.In (Fin.F1 (n := 10)) [|Fin1; Fin2; Fin3 |] -> False.
Arguments Vector.eqb {_}  _ {_ _}.
Proof with try (constructor;congruence).
intros Hf x y.
apply iff_reflect. symmetry. apply Vector.eqb_eq. symmetry. apply reflect_iff. eauto.
Qed.

Lemma vector_rev_append_tail_to_list A (n m: nat) (v : Vector.t A n) (w : Vector.t A m):
Vector.to_list (Vector.rev_append_tail v w) = (List.rev (Vector.to_list v) ++ Vector.to_list w)%list.