Vectors

This file defines operations on vectors and proves corresponding facts.

Require Import Vector.
Definition vec := t.

Require Import Util.

Require Import Equations.Equations Equations.Prop.DepElim.
Require Import Lia.

Definition Forall {X} (p : X Prop) := fix Forall {n} (v : vec X n) :=
  match v with
  | nil _ True
  | cons _ x _ v p x Forall v
  end.

Definition ForallT {X} (p : X Type) := fix ForallT {n} (v : vec X n) :=
  match v with
  | nil _ (unit : Type)
  | cons _ x _ v (p x * ForallT v)%type
  end.

Definition {X Y} (p : X Y Prop) := fix {n} (v1 : vec X n) (v2 : vec Y n) :=
  match in Vector.t _ n return vec Y n Prop with
  | nil _ _ True
  | cons _ x _ v2 p x (hd ) (tl )
  end .

Fixpoint Forall2T {X Y n} (p : X Y Type) (v1 : vec X n) (v2 : vec Y n) :=
  match in Vector.t _ n return vec Y n Type with
  | nil _ _ True
  | cons _ x _ v2 (p x (hd ) * Forall2T p (tl ))%type
  end .

Definition Any {X} (p : X Prop) := fix Forall {n} (v : vec X n) :=
  match v with
  | nil _ False
  | cons _ x _ v p x Forall v
  end.

Fixpoint In {X n} x (v : vec X n) :=
  match v with
  | nil _ False
  | cons _ y _ v x = y In x v
  end.

Lemma Forall2_Forall {X Y Z n} (p : Y Z Prop) (f1 : X Y) (f2 : X Z) v :
  @ Y Z p n (map v) (map v) @Forall X ( x p ( x) ( x)) n v.
Proof.
  induction v; firstorder.
Qed.


Lemma Forall2_identical {X n} (v : vec X n) (p : X X Prop) :
   p v v Forall ( x p x x) v.
Proof.
  induction v; firstorder.
Qed.


Lemma Forall2_move_forall {X Y Z n} (v1 : vec X n) (v2 : vec Y n) (p : X Y Z Prop) :
   ( x y z, p x y z) z, ( x y p x y z) .
Proof.
  induction ; dependent elimination ; firstorder. apply , H.
Qed.


Lemma Forall2_eq {X n} (v1 : vec X n) (v2 : vec X n) :
   eq = .
Proof.
  induction ; dependent elimination ; intros H. reflexivity. f_equal; firstorder.
Qed.


Lemma Forall_ext {X n} (p q : X Prop) (v : vec X n) :
  ( x, p x q x) Forall p v Forall q v.
Proof.
  induction v; firstorder.
Qed.


Lemma Forall_ext_Forall {X n} (p q : X Prop) (v : vec X n) :
  Forall ( x p x q x) v Forall p v Forall q v.
Proof.
  induction v; firstorder.
Qed.


Lemma Forall_ext_in {X n} (p q : X Prop) (v : vec X n) :
  ( x, In x v p x q x) Forall p v Forall q v.
Proof.
  induction v; firstorder.
Qed.


Lemma Forall_in {X n} (p : X Prop) (v : vec X n) :
  Forall p v x, In x v p x.
Proof.
  induction v. easy. split. intros x [|]; firstorder. firstorder.
Qed.


Lemma Forall_map {X Y n} (p : Y Prop) (f : X Y) (v : vec X n) :
  Forall p (map f v) Forall ( x p (f x)) v.
Proof.
  induction v; firstorder.
Qed.


Require Import Decidable.

Lemma Forall_dec {X n} (p : X Prop) (v : vec X n) :
  ForallT ( x dec (p x)) v dec (Forall p v).
Proof.
  induction v; firstorder.
Qed.


Lemma ForallT_translate {X Y n} (p : X Y Prop) (v : vec X n) :
  ForallT ( x { x' | p x x' }) v { v' : vec Y n | p v v'}.
Proof.
  intros H. induction v.
  - now exists (nil _).
  - destruct H as [[x' ] ]. destruct IHv as [v' IHv]. easy.
    now exists (cons _ x' _ v').
Qed.


Lemma ForallT_ext {X n} (p q : X Type) (v : vec X n) :
  ( x, p x q x) ForallT p v ForallT q v.
Proof.
  induction v; firstorder.
Qed.


Lemma ForallT_general {X n} (p : X Type) (v : vec X n) :
  ( x, p x) ForallT p v.
Proof.
  induction v; firstorder.
Qed.


Lemma map_ext {X Y Z : Type} {n} (v : vec X n) (v' : vec Y n) (f : X Z) (g : Y Z) :
   ( x x' f x = g x') v v' map f v = map g v'.
Proof.
  induction v; dependent elimination v'; cbn; intros H.
  - reflexivity.
  - f_equal. apply H. now apply IHv.
Qed.


Lemma map_ext_in {X Y n} (f g : X Y) (v : vec X n):
  ( x, In x v f x = g x) map f v = map g v.
Proof.
  induction v; cbn. reflexivity. intros. f_equal; firstorder.
Qed.


Lemma map_ext_forall {X Y n} (f g : X Y) (v : vec X n):
  Forall ( x f x = g x) v map f v = map g v.
Proof.
  induction v; cbn. reflexivity. intros. f_equal; firstorder.
Qed.


Lemma In_map {X Y n} (f : X Y) (v : vec X n) x :
  In x v In (f x) (map f v).
Proof.
  intros H. induction v; cbn. easy. destruct H as [|]. now left. right. now apply IHv.
Qed.


Lemma In_map_iff {X Y n} (f : X Y) (v : vec X n) y :
  In y (map f v) x, f x = y In x v.
Proof.
  induction v; cbn.
  - split. easy. now intros [].
  - split.
    + intros [|]. exists h. split. easy. now left. apply IHv in H as [x H]. exists x.
      split. apply H. now right.
    + intros [x [ [|]]]. now left. right. apply IHv. now exists x.
Qed.


Lemma In_compat {X n} x (v : vec X n) :
  In x v Vector.In x v.
Proof.
  induction v; cbn.
  - split. easy. intros H. inversion H.
  - split. intros [|]; constructor. now apply IHv. intros H.
    inversion H. now left. right. apply inj_pairT2 in as . now apply IHv.
    decide equality.
Qed.


Fixpoint tabulate {X} n (f : X) : vec X n :=
  match n with
  | 0 Vector.nil X
  | S n Vector.cons _ (f n) _ (tabulate n f)
  end.

Fixpoint fold_left {X Y} (f: X Y Y) y {n} (v : vec X n) : Y :=
  match v with
  | Vector.nil _ y
  | Vector.cons _ x _ v fold_left f (f x y) v
  end.

Fixpoint fold_two_left {X Y} (f: X Y Y) y {n} (v1 v2 : vec X n) : Y :=
  match in Vector.t _ n return vec X n Y with
  | Vector.nil _ _ y
  | Vector.cons _ x _ v2 fold_two_left f (f (hd ) (f x y)) (tl )
  end .

Fixpoint nth_error {X m} n (v : vec X m) err := match v with
  | Vector.nil _ err
  | Vector.cons _ x _ v match n with 0 x | S n nth_error n v err end
end.

Lemma map_tabulate {X Y} n (f : X Y) (g : X) :
  map f (tabulate n g) = tabulate n ( x f (g x)).
Proof.
  induction n; cbn; congruence.
Qed.


Lemma tabulate_ext {X} n (f : X) (g : X) :
  ( m, m < n f m = g m) tabulate n f = tabulate n g.
Proof.
  intros H. induction n; cbn. reflexivity. f_equal. apply H. lia.
  apply IHn. intros m H'. apply H. lia.
Qed.


Lemma tabulate_nth {X n} (v : vec X n) err :
  tabulate n ( x nth_error (n-S x) v err) = v.
Proof.
  induction v; cbn. reflexivity. f_equal. now replace (n-n) with 0 by lia.
  rewrite IHv at 1. apply tabulate_ext. intros x H. now replace (n - x) with (S (n - S x)) by lia.
Qed.


Lemma tabulate_Forall {X n} (f : X) (p : X Prop) :
  Forall p (tabulate n f) x, x < n p (f x).
Proof.
  induction n; cbn.
  - split; intros; lia.
  - split.
    + intros [] x ?. assert (x = n x < n) as [|] by lia. easy. now apply IHn.
    + intros H. split. apply H. lia. apply IHn. intros ? ?. apply H. lia.
Qed.


Lemma nth_tabulate {X} n m (f : X) err :
  m < n nth_error m (tabulate n f) err = f (n-S m).
Proof.
  revert m. induction n; intros m; cbn -[minus].
  - lia.
  - intros H. destruct m; cbn. f_equal; lia. apply IHn. lia.
Qed.