(* Base of k vector *)
Fixpoint base (n: nat) k:list (vect n) :=
match n return list (vect n) with
| O =>  match k with | O => 1%f::nil | _ => nil end
| S n1 =>
match k with | O =>
map (lift n1) (base n1 k) | S k1 =>
(map (dlift n1) (base n1 k1) ++
map (lift n1) (base n1 k))%list
end
end.

(* Specifications: *)
Lemma proj_base_length n (x: vect n) k :
length (proj n k x) = length (base n k).
Lemma base0 n : base n 0 = 'e_n::nil.
Lemma base_lt_nil m n : m < n -> base m n = nil.
Lemma base_n n : base n n = all n::nil.
Lemma base_length n k : length (base n k) = bin n k.
Lemma base_lift n k :  incl (map (lift n) (base n k)) (base n.+1 k).
Lemma base_hom n k v : k <= n -> In v (base n k) -> hom n k v.
Lemma proj_homk n (x: vect n) k :
hom n k x -> proj n k x *X* base n k = x.
Lemma base_free n k : free _ (base n k).
(* Each generator is in the base *)
Lemma e_in_base1 n i : i < n -> In 'e_i (base n 1).
(* An element of the base is a generator *)
Lemma e_in_base1_ex n v :
In v (base n 1) -> exists p1, p1 < n /\ v = 'e_p1.
(* The length of the base is n *)
Lemma base1_length n : length (base n 1) = n.
Lemma cbl1_hom1_equiv n (x: vect n) : cbl _ (base n 1) x <-> hom n 1 x.
Lemma cblk_homk_equiv n k (x: vect n): cbl _ (base n k) x <-> hom n k x.
Lemma cbl_base1_split n x :
cbl _ (base n.+1 1) x -> exists k, exists y, cbl _ (base n 1) y /\ x = ([k], y).
Lemma cbl_base1_list_split n l:
(forall x, In x l -> cbl _ (base n.+1 1) x) ->
exists lk, exists ly,
(forall i, In i lk -> (fst i) <> 0%f) /\
(forall i, In i lk -> cbl _ (base n 1) (snd i)) /\
(forall i, In i ly -> cbl _ (base n 1) i) /\
perm l ((map (fun x => ([fst x],(snd x))) lk) ++ map (lift n) ly).
(* Ad-hoc inductive principe for vectors of degree k *)
Lemma hom_induct n k (P: vect n -> Prop) :
P 0 -> (forall v, In v (base n k) -> P v) ->
(forall v1 v2, P v1 -> P v2 -> P (v1 + v2)) ->
(forall k v, P v -> P (k .* v)) ->
(forall v, hom n k v -> P v).