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.

Lemma parity_correct : forall p l l1 l2, pWF p -> length l = parity p -> peval p (l++l1) = peval p (l++l2).