Definition is_base vs := free vs /\ forall e, cbl vs e.
Structure vparamsProp: Type := {
sProp : fparamsProp p;
eqE_dec: forall x y, if x ?= y then x = y else x <> y;
(* Boolean equality *)
addE_assoc: forall x y z, (x + y) + z = x + (y + z);
(* Associativity for + *)
addE_com: forall x y, x + y = y + x;
(* Commutativity for + *)
addE0l: forall x, 0 + x = x;
(* Left neutral  for + *)
scalE0l: forall x, 0 .* x = 0;
(* scalar 0 *)
scalE1: forall x, 1 .* x = x;
(* scalar 1 *)
scal_addEl: forall k1 k2 x, (k1 + k2) .* x = (k1.* x) + (k2 .* x);
(* scalar distributivity left *)
scal_addEr: forall k x y, k .* (x + y) = k .* x + k .* y;
(* scalar distributivity right *)
scal_multE: forall k1 k2 x, (k1 * k2) .* x = k1.* (k2 .* x)
(* scalar distributivity left *)
}.
Variable Hp: vparamsProp.

(* Specifications: *)
Lemma eqE_refl x: (x ?= x) = true.
Lemma addE0r: forall x, x + 0 = x.
Let sfP := sProp Hp.
Lemma addE_cancell x y z : z + x = z + y -> x = y.
Lemma addE_cancelr x y z : x + z = y + z -> x = y.
Lemma scalE0r k : k .* 0 = 0.
(* Opposite for  + *)
Lemma scal_addE0 x : x + (- (1)) .* x = 0.
Lemma addE_eq_opp x y : x + (-(1)) .* y = 0 -> x = y.
(* Recursive equation for multiple product *)
Lemma mprod_S k ks v vs : (k :: ks) *X* (v :: vs) = k .* v + ks *X* vs.
Lemma mprod0l vs : nil *X* vs = 0.
(* Concation for multiple product *)
Lemma mprod_app ks1 ks2 vs1 vs2 :
length ks1 = length vs1 ->
(ks1 ++ ks2) *X* (vs1 ++ vs2) = ks1 *X* vs1 + ks2 *X* vs2.
Lemma eqE_spec x y : eq_Spec x y (x ?= y).
(* Lemmas for free *)
Lemma free_nil : free nil.
Lemma free_cons v vs : free (v::vs) -> free vs.
Lemma free_perm vs1 vs2 : perm vs1 vs2 -> free vs2 -> free vs1.
Lemma uniq_free vs : free vs -> uniq vs.
Lemma free_incl vs1 vs2 : incl vs1 vs2 -> uniq vs1 -> free vs2 -> free vs1.
(* Lemmas for cbl *)
(* Linear combination  behaves well with inclusion *)
Lemma cbl_incl l1 l2 v : incl l1 l2 -> cbl l1 v -> cbl l2 v.
Lemma cbl0_inv x : cbl nil x -> x = 0.
(* Multiple products are linear combinations *)
Lemma mprod_cbl l ks : cbl l (ks *X* l).
(* Multiple product of a sum *)
Lemma addE_mprod ks1 ks2 vs : length ks1 = length ks2 ->
map2 (fun k1 k2 => (k1 + k2)%f) ks1 ks2 *X* vs = ks1 *X* vs + ks2 *X* vs.
(* Multiple production of a scalar product *)
Lemma scalE_mprod k ks vs :
map (fun k1 => (k * k1)%f) ks *X* vs = k .* (ks *X* vs).
Lemma mprod_perm l1 l2 lk1: perm l1 l2 -> length lk1 = length l1 ->
exists lk2, perm lk1 lk2 /\ lk1 *X* l1 = lk2 *X* l2.