Notation parity := (@fst nat (list mon)).(** * Well-formedness of polynomials *)

Definition pWF_pow (ar:nat)(xn:pow) : Prop :=
  fst xn < ar.Definition pWF_mon (ar:nat)(m:mon) : Prop :=
  andl (pWF_pow ar) (snd m).Definition pWF' (ar:nat)(ml:list mon) : Prop :=
  andl (pWF_mon ar) ml.(** * Tactic for well-formedness

  - The tactic [pWF] attempts to prove automatically goals of the form [pWF p] where
    [p] is a polynomial.
*)

Ltac pWF :=
  match goal with
  | |- pWF (pcst _ _) => apply pWF_pcst
  | |- pWF (pproj _ _) => apply pWF_pproj; try omega
  | |- pWF (pscalar _ _) => apply pWF_pscalar; pWF
  | |- pWF (pplus _ _) => apply pWF_pplus; pWF
  | |- pWF (pplusl _) => apply pWF_pplusl; rewrite <- forall_andl; intros; pWF
  | |- pWF (pmult _ _) => apply pWF_pmult; pWF
  | |- pWF (pmultl _) => apply pWF_pmultl; rewrite <- forall_andl; intros; pWF
  | |- pWF (ppower _ _) => apply pWF_ppower; pWF
  | |- pWF (pcomp _ _) => apply pWF_pcomp; rewrite <- forall_andl; intros; pWF
  | |- pWF (pshift _) => apply pWF_pshift; pWF
  | |- pWF (psum _ _) => apply pWF_psum
  | |- _ => idtac
  end.

(* Specifications: *)
Lemma pWF_mon_le : forall ar1 ar2 m, ar1 <= ar2 -> pWF_mon ar1 m -> pWF_mon ar2 m.
Lemma pWF'_le ar1 ar2 ml : ar1 <= ar2 -> pWF' ar1 ml -> pWF' ar2 ml.
Lemma pWF_mon_app : forall ar a1 xl1 a2 xl2, pWF_mon ar (a1, xl1) -> pWF_mon ar (a2, xl2) -> pWF_mon ar (a1*a2, xl1++xl2).
Lemma pWF'_app ar ml1 ml2 : pWF' ar ml1 -> pWF' ar ml2 -> pWF' ar (ml1++ml2).
Lemma pWF_nth i pl p0 : andl pWF pl -> pWF p0 -> pWF (nth i pl p0).
Lemma parity_mon_correct : forall ar m l l1 l2, pWF_mon ar m -> length l = ar -> peval_mon m (l++l1) = peval_mon m (l++l2).
Lemma parity_correct : forall p l l1 l2, pWF p -> length l = parity p -> peval p (l++l1) = peval p (l++l2).
Lemma parity_pcst ar a : parity (pcst ar a) = ar.
Lemma pWF_pcst ar a : pWF (pcst ar a).
Lemma pcst_correct : forall ar k l, peval (pcst ar k) l = k.
Lemma parity_pproj n i : parity (pproj n i) = n.
Lemma pWF_pproj ar i : i < ar -> pWF (pproj ar i).
Lemma pproj_correct : forall ar i l, peval (pproj ar i) l = nth i l 0.