(* We recover the usual mathematical notation *)
Definition K1 := K.Notation "'K'" := (K1 p) : g_scope.Notation "'kn'" := (kn p).Notation projk := (proj p).Ltac Kfold n :=
     change (Kn.add p n) with (addE (Kn.vn_eparams p n));
     change (Kn.scal p n) with (scalE (Kn.vn_eparams p n));
     change (Kn.genk p n 0%f) with (E0 (Kn.vn_eparams p n)).(* A vector is a full-binary tree of hight n *)
Fixpoint vect (n: nat): Set := 
  match n with O => K | S n1 => (vect n1 * vect n1)%type end.(* Adding two trees: adding its leaves *)
Fixpoint add (n : nat) : vect n -> vect n -> vect n :=
  match n return (vect n -> vect n -> vect n) with
  | 0%nat => fun a b => (a + b)%f
  | S n1 =>
      fun l1 l2 =>
      let (l3, l5) := l1 in
      let (l4, l6) := l2 in (add n1 l3 l4, add n1 l5 l6)
  end.Notation " [ k ] " := (genk _ k%f) (at level 9): g_scope.(* Multiplication by a scalar *)
Fixpoint scal (n : nat) (k: K) {struct n}: vect n -> vect n :=
  match n return (vect n -> vect n) with
  | 0%nat => fun a => (k * a)%f
  | S n1 =>
      fun l1 =>
      let (l2, l3) := l1 in (scal n1 k l2, scal n1 k l3)
  end.Definition fn n : vparamsProp (vn_eparams n).Ltac Vfold n :=
     change (add n) with (addE (vn_eparams n));
     change (scal n) with (scalE (vn_eparams n));
     change (genk n 0) with (E0 (vn_eparams n)).Ltac Grm0 := autorewrite with GRm0; auto.(* Subtraction  *)
Fixpoint sub (n : nat) : vect n -> vect n -> vect n :=
  match n return (vect n -> vect n -> vect n) with
  | 0%nat => fun a b => (a + (- b))%f
  | S n1 =>
      fun v1 v2 =>
      let (x1, y1) := v1 in
      let (x2, y2) := v2 in (sub n1 x1 x2, sub n1 y1 y2)
  end.Notation "x - y" := (sub _ x y): g_scope.

Lemma sub0r n (v: vect n) : v - 0 = v.