Library Kildall.lists.vector
Section Vector.
Require Export Eqdep.
Require Export Arith.
Require Export semilattices.
Variable A : Set.
Inductive vector : nat->Set:=
| vector_nil : (vector 0)
| vector_cons : forall (n:nat), A->vector n->(vector (S n)).
Definition eq_list:=(eq_dep nat vector).
Definition head':=
fun (n:nat) (v:(vector n)) =>
match v in (vector x) return (lt 0 x)-> A with
vector_nil => fun h:(lt O O) => (False_rec A (lt_irrefl O h)) |
(vector_cons n' h _) => fun H : (lt 0 (S n')) => h
end.
Definition head:=
fun (n:nat)(v:(vector (S n))) => (head' (S n) v (lt_O_Sn n)).
Definition tail:=
fun (n:nat)(v:vector n) =>
match v in (vector x) return (vector (pred x)) with
vector_nil => vector_nil|
(vector_cons n' h v')=> v' end.
Lemma empty_dep:forall (n:nat)(v:(vector n)), n=O->(eq_list O vector_nil n v).
Proof.
unfold eq_list; intros n v.
dependent inversion v; auto.
intro h; absurd ((S n0)=0); auto.
Save.
Hint Resolve empty_dep.
Lemma empty:forall (v:(vector O)), vector_nil=v.
Proof.
intro v.
apply (eq_dep_eq nat vector O).
apply empty_dep; auto.
Save.
Hint Resolve empty.
Remark non_empty_dep:
forall (n m : nat), m=(S n)->forall (v:(vector (S n))),
{h:A & {t:(vector n) | (eq_list (S n) v (S n) (vector_cons n h t))}}.
Proof.
intros.
generalize H.
dependent inversion_clear v with
(fun (n':nat)(v:(vector n')) =>
m=n'-> {a:A & {v':(vector n)|(eq_list n' v (S n) (vector_cons n a v'))}}).
unfold eq_list.
intro H'.
exists a.
exists v0.
constructor.
Qed.
Lemma non_empty:forall (n:nat)(v:(vector (S n))),
{a:A &{t:(vector n)|v=(vector_cons n a t)}}.
Proof.
intros n v.
cut (sigS (fun a:A=>
(sig (fun t:(vector n)=>(eq_list (S n) v (S n) (vector_cons n a t)))))).
intros H; elim H; clear H.
intros a H; elim H; clear H.
intros t H.
exists a; exists t.
apply (eq_dep_eq nat vector (S n)) .
unfold eq_list in H; auto.
apply (non_empty_dep n (S n)); auto.
Defined.
Lemma split_vector :forall (n:nat)(v:(vector (S n))),
v=(vector_cons n (head n v) (tail (S n) v)).
Proof.
intros n v.
elim (non_empty n v).
intros h H; elim H; clear H.
intros t e.
rewrite e; simpl.
auto.
Save.
Definition hd' := fun (n:nat)(v:(vector (S n))) =>
let (a, H):= (non_empty n v) in a.
Lemma Non_empty_Hd :
forall (n:nat)(a:A)(v:(vector n)), (hd' n (vector_cons n a v))=a.
Proof.
intros n a v; unfold hd'.
elim (non_empty n (vector_cons n a v)).
intros x H; elim H.
clear H; intros X H.
injection H; auto.
Save.
Inductive vector_pointwise (r:relation A):
forall n:nat, (vector n)->(vector n) -> Prop :=
| le_nil: vector_pointwise r 0 vector_nil vector_nil
| le_cons: forall (a a' : A) (n : nat) (v v' : (vector n)),
(r a a')->vector_pointwise r n v v'->vector_pointwise r (S n) (vector_cons n a v) (vector_cons n a' v').
Definition Vector_pointwise (r:relation A) (n:nat) : relation (vector n) :=
vector_pointwise r n.
Definition SI_vector_pointwise (r:relation A) (n:nat) : relation (vector n) :=
strict (inv (vector_pointwise r n)).
Fixpoint vector_replace (n:nat) (v:vector n) (i:nat) (a:A) {struct v}:
(vector n) :=
match v in vector n return vector n with
| vector_nil => vector_nil
| vector_cons n' h t =>
match i with
| 0 => vector_cons n' a t
| (S i') => vector_cons n' h (vector_replace n' t i' a)
end
end.
Fixpoint belong_element_vector (n:nat) (l : vector n) (a:A) {struct l} : Prop :=
match l in vector n return Prop with
| vector_nil => False
| vector_cons n' h t => h=a \/ belong_element_vector n' t a
end.
Fixpoint element_at (n:nat) (v : vector n) (i:nat) {struct v} :
(lt i n)->A :=
match v in vector n, i return (lt i n)->A with
| vector_nil, _ => fun x : (lt i 0) => (False_rec A (lt_n_O i x))
| (vector_cons p h t), 0 => fun (x : (lt 0 (S p)))=> h
| (vector_cons p h t), (S i') =>
fun (x : (lt (S i') (S p))) => (element_at p t i') (lt_S_n i' p x)
end.
Fixpoint element_at_unsafe (n : nat) (v : vector n) (i : nat) {struct v} : option A :=
match v with
| vector_nil => None
| vector_cons p h t =>
match i with
| 0 => Some h
| S i' => element_at_unsafe p t i'
end
end.
Fixpoint constant_list (n : nat) (a : A) {struct n} : vector n :=
match n return vector n with
| 0 => vector_nil
| (S p) => vector_cons p a (constant_list p a)
end.
End Vector.
Fixpoint vector_map (A B:Set) (g:A->B) (n:nat) (v:vector A n) {struct v} :
vector B n :=
match v in (vector _ n) return (vector _ n) with
| vector_nil => vector_nil B
| vector_cons p h t => vector_cons B p (g h) (vector_map A B g p t)
end.
Fixpoint map2 (A B C : Set) (f : A-> B -> C) (n : nat) {struct n}:
(vector A n)->(vector B n)-> (vector C n):=
match n return (vector _ n)->(vector _ n)-> (vector _ n) with
| 0 => (fun (v:(vector _ 0))(v':(vector _ 0)) => (vector_nil _))
| (S p)=> (fun (v:(vector _ (S p))) (v':(vector _ (S p))) =>
(vector_cons _ p (f (head A p v) (head B p v'))
(map2 _ _ _ f _ (tail _ _ v) (tail _ _ v'))))
end.
Definition Map2 (A : Set) (f : binop A) (n:nat):= map2 A A A f n.
Implicit Arguments vector_cons [A n].
Implicit Arguments vector_nil [A].
Implicit Arguments head [A n].
Implicit Arguments tail [A n].
Implicit Arguments empty [A].
Implicit Arguments split_vector [A n].
Implicit Arguments vector_replace [A n].
Implicit Arguments belong_element_vector [A n].
Implicit Arguments element_at [A n].
Implicit Arguments vector_map [A B n].
Implicit Arguments map2 [A B C n].
Implicit Arguments Map2 [A].
Implicit Arguments constant_list [A].
Implicit Arguments element_at_unsafe [A n].
Ltac Split x:= replace x with (vector_cons (head x) (tail x));
[trivial | symmetry; exact (split_vector x)].
Ltac CaseEq f:=generalize (refl_equal f); pattern f at -1 in |- *; case f.
Notation "v '[' p '<-' e ']'" := (vector_replace v p e) (at level 50).
Notation "e 'INv' v" := (belong_element_vector v e) (at level 50).
Notation "v '[' p '|' C ']'" := (element_at v p C) (at level 50).
Notation "v '[' p '|_]'" := (element_at_unsafe v p) (at level 50).
