(** * Length-bounding polynomial for Cobham expressions

  - The lemma [poly_Cobham_correct] states that the output of an expression [e]
    is bounded by the polynomial [poly_Cobham e].
*)

Fixpoint poly_Cobham (e : Cobham) :=
  match e with
    | Zero => pcst 0 0
    | Proj n i => pproj n i
    | Succ b => pplus (pcst 0 1) (pproj 1 0)
    | Smash => pplus (pcst 0 1) (pmult (pproj 2 0) (pproj 2 1))
    | Rec g h0 h1 j => poly_Cobham j
    | Comp n h l => 
      pplus (pcst n 0) 
      (pcomp (poly_Cobham h) (map poly_Cobham l))
  end.

(* Specifications: *)
Lemma parity_poly_Cobham : forall (e : Cobham) n, arity e = ok_arity n -> parity (poly_Cobham e) = n.
Lemma pWF_poly_Cobham : forall (e : Cobham) n, arity e = ok_arity n -> pWF (poly_Cobham e).
Lemma poly_Cobham_correct : forall (e : Cobham) xl, rec_bounded e -> length (Sem e xl) <= peval (poly_Cobham e) (map (@length _) xl).