(* Ad-hoc conjugate function in order to define the product *)
Fixpoint conj (n : nat) (b: bool) {struct n}: vect n -> vect n :=
match n return (vect n -> vect n) with
| 0%nat => fun a => if b then (- a)%f else a
| S n1 =>
fun l1 =>
let (l2, l3) := l1 in (conj n1 (negb b) l2, conj n1 b l3)
end.
Notation "x ^_ b" := (conj _ b x)  (at level 30).
Notation "x ^_'t" := (conj _ true x)  (at level 30).
Notation "x ^_'f" := (conj _ false x)  (at level 30).

(* Specifications: *)
(* Conjugate behave well with the sum *)
Lemma conj_add n b (x y: vect n) : (x + y) ^_ b = x ^_ b + y ^_ b.
(* Conjugate is involutive *)
Lemma conj_invo n b (x: vect n) : x ^_ b ^_ b = x.
(* Conjugate of 0 is 0 *)
Lemma conj0 n b : 0 ^_ b = (0 : vect n).
Hint Rewrite conj0: GRm0.
(* Conjugate of k is -k *)
Lemma conjk n b k : [k] ^_ b=  if b then [-k] else ([k]: vect n).
(* removing negation *)
Lemma conj_neg n b (v: vect n) : v ^_ (negb b) = (-(1)) .*  (v ^_ b).
(* removing conj_true *)
Lemma conjt n (v: vect n) : v ^_'t = (-(1)) .*  (v ^_'f).
(* Conjugate behaves well with scalar multiplication *)
Lemma conj_scal n b k (x: vect n) : (k .* x) ^_ b = k .* x ^_ b.
Lemma conj_hom n b k (x: vect n) : hom n k x -> hom n k (x ^_ b).
Hint Resolve conj_hom.
Lemma conjf_hom n k (M: vect n) : hom n k M -> M ^_'f = (- (1))^k .* M.
Lemma conjt_hom n k (M: vect n) : hom n k M -> M ^_'t = (- (1))^k.+1 .* M.
Lemma conj_const n b (x: vect n) : 'C[x ^_ b] = if b then (-'C[x])%f else 'C[x].
(* We can swap add-hoc conjugate *)
Lemma conj_swap n b1 b2 (x: vect n) : x ^_ b2 ^_ b1 =  x ^_ b1 ^_ b2.
(* Conjugate of 0 is 0 *)
Lemma conj_all n b: (E  ^_ b) =
(if b then (-((-(1))^ n))%f else ((-(1))^ n)%f) .* E :> vect n.