Variable ptime_zero ptime_succ ptime_pred ptime_cond: pol.
Variable ptime_proj : nat -> nat -> nat -> pol.
Hypothesis ptime_zero_spec :
snd (sem_cost zero nil nil) <= peval ptime_zero nil.
Hypothesis ptime_zero_wf : pWF ptime_zero.
Hypothesis ptime_zero_arity : parity ptime_zero = 0.
Hypothesis ptime_succ_spec : forall b,
snd (sem_cost (succ b) nil nil) <= peval ptime_succ nil.
Hypothesis ptime_succ_wf : pWF ptime_succ.
Hypothesis ptime_succ_arity : parity ptime_succ = 0.
Hypothesis ptime_proj_spec : forall n s i l,
length l = n ->
snd (sem_cost (proj n s i) l nil) <= peval (ptime_proj n s i) (map (@length _) l).
Hypothesis ptime_proj_wf : forall n s i, pWF (ptime_proj n s i).
Hypothesis ptime_proj_arity : forall n s i, parity (ptime_proj n s i) = n.
Hypothesis ptime_cond_spec :
snd (sem_cost cond nil nil) <= peval ptime_cond nil.
Hypothesis ptime_cond_wf : pWF ptime_cond.
Hypothesis ptime_cond_arity : parity ptime_cond = 0.
Hypothesis ptime_pred_spec :
snd (sem_cost pred nil nil) <= peval ptime_pred nil.
Hypothesis ptime_pred_wf : pWF ptime_pred.
Hypothesis ptime_pred_arity : parity ptime_pred = 0.
Fixpoint poly_time n (e:BC) : pol :=
match e with
| zero => ptime_zero
| succ _ => ptime_succ
| pred => ptime_pred
| cond  => ptime_cond
| proj n s i => ptime_proj n s i
| rec g h0 h1 =>
pplus (pshift (poly_time (n - 1) g))
(pmult (pproj n 0) (pplus (poly_time n h0) (poly_time n h1)))
| comp n0 s h rl tl =>
pplus (pplus (pcst n0 0) (pcomp (poly_time (length rl) h) (map (poly_BC n0) rl)))
(pplus (pplusl (map (poly_time n0) rl)) (pplusl (map (poly_time n0) tl)))
end.

(* Specifications: *)
Lemma poly_time_WF : forall e n s, arities e = ok_arities n s -> pWF (poly_time n e).
Lemma arity_poly_time : forall e n s,
arities e = ok_arities n s ->
parity (poly_time n e) = n.
Lemma sem_cost_bounded : forall e n s,
arities e = ok_arities n s ->
(forall vnl vsl,
length vnl = n ->
length vsl = s ->
snd (sem_cost e vnl vsl) <=
peval (poly_time n e) (List.map (@length _) vnl)).