Fixpoint nb_judgements (proof_tree : cbv) : nat :=
  match proof_tree with
  | cbv_constr lp _ _ => 1 + suml (map nb_judgements lp)
  | cbv_split lp p _ _ => 1 + nb_judgements p + suml (map nb_judgements lp)
  | cbv_function _ _ p _ _ => 1 + nb_judgements p
  end.Fixpoint nb_judgements_sub_rec (proof_tree : cbv) : nat :=
  match proof_tree with
  | cbv_constr lp _ _ => 1 + suml (map nb_judgements_sub_rec lp)
  | cbv_split lp p _ _ => 1 + nb_judgements_sub_rec p + suml (map nb_judgements_sub_rec lp)
  | cbv_function _ _ _ _ _ => 0
  end.Definition nb_judgements_sub (proof_tree : cbv) : nat :=
  match proof_tree with
  | cbv_constr _ _ _ => 0
  | cbv_split _ _ _ _ => 0
  | cbv_function _ _ p _ _ => nb_judgements_sub_rec p
  end.

(* Specifications: *)
Lemma nb_judgements_bound i s p' t v : let p := cbv_function i s p' t v in nb_judgements p <= suml (map nb_judgements_sub (activations p)) + length (activations p).
Lemma nb_judgements_sub_rec_bound p : wf p -> nb_judgements_sub_rec p <= term_size (proj_left p).
Lemma nb_judgements_sub_bound i s p t v : wf (cbv_function i s p t v) -> nb_judgements_sub (cbv_function i s p t v) <= activation_bound prog (term_size t).
Lemma value_size_bounded_by_nb_judgements p : wf p -> value_size (proj_right p) <= nb_judgements p.
Lemma term_size_bound_constr lp t v : wf (cbv_constr lp t v) -> andl (map (fun p => term_size t >= term_size (proj_left p)) lp).
Lemma term_size_bound_split lp p t v : wf (cbv_split lp p t v) -> andl (map (fun p => term_size t >= term_size (proj_left p)) lp).
Lemma size_bounded_nb_size_judgements p : size p <= nb_judgements p * max_judgement_size p.
Lemma nb_judgements_sub_bound_gen : forall p p', let S := max_active_size p in wf p -> In p' (activations p) -> nb_judgements_sub p' <= activation_bound prog S.
Lemma nb_judgements_bound_gen : forall i s p' t v, let p := cbv_function i s p' t v in let A := length (activations p) in let S := max_active_size p in wf p -> nb_judgements p <= A * activation_bound prog S + A.
Lemma term_size_proj_left_bound : forall i s p' t v, let p := cbv_function i s p' t v in let S := max_active_size p in wf p -> forall p', InCBV p' p -> term_size (proj_left p') <= activation_bound prog S + S.
Lemma size_judgement : forall i s p' t v, let p := cbv_function i s p' t v in let A := length (activations p) in let S := max_active_size p in wf p -> max_judgement_size p <= activation_bound prog S + S + A * activation_bound prog S + A.
Theorem size_bound : forall i s p' t v, let p := cbv_function i s p' t v in let A := length (activations p) in let S := max_active_size p in wf p -> size p <= (A * activation_bound prog S + A) * (activation_bound prog S + S + A * activation_bound prog S + A).