(** * Representation of polynomials:

  - [pow] is the type of a variable identifier and its exponent.

  - [mon] is the type of a monomial, consisting of a coefficient and a list of variable identifiers with their exponents.

  - [pol] is the type of a polynomial, consisting of the number of variables and a list of monomials.
*)

Definition pow : Type := (nat*nat)%type.Definition mon : Type := (nat * list pow)%type.Definition pol : Type := (nat * list mon)%type.(** * Evaluation of polynomials

  - [peval p [v0, v1,...]] is the evaluation of the polynomial [p] with variables [0], [1]... respectively
    instantiated with the values [v0], [v1]...
    If a variable is not assigned a value, then it is assumed to be [0].
    Values that do not correspond to a variable are ignored.
*)

Definition peval_pow (xn:pow)(l:list nat) : nat :=
  power (nth (fst xn) l 0) (snd xn).Definition peval_mon (m:mon)(l:list nat) : nat :=
  (fst m) * multl (map (fun x => peval_pow x l) (snd m)).Definition peval (p:pol)(l:list nat) :=
  plusl (map (fun m => peval_mon m l) (snd p)).

(* Specifications: *)
Lemma peval_parity : forall ar p l, peval (ar, snd p) l = peval p l.
Lemma peval_pow_monotonic : forall xn l1 l2, (forall i, nth i l1 0 <= nth i l2 0) -> peval_pow xn l1 <= peval_pow xn l2.
Lemma peval_mon_monotonic : forall m l1 l2, (forall i, nth i l1 0 <= nth i l2 0) -> peval_mon m l1 <= peval_mon m l2.
Lemma peval_monotonic : forall p l1 l2, (forall i, nth i l1 0 <= nth i l2 0) -> peval p l1 <= peval p l2.
Lemma peval_nth i pl p l : peval (nth i pl p) l = nth i (map (fun p => peval p l) pl) (peval p l).