(* Sizes *)

Fixpoint size (proof_tree : cbv) : nat :=
  match proof_tree with
  | cbv_constr l t v => term_size t + value_size v + suml (map size l)
  | cbv_split l p t v => term_size t + value_size v + size p + suml (map size l)
  | cbv_function _ _ p t v => size p + term_size t + value_size v
  end.Fixpoint max_active_size (proof_tree : cbv) : nat :=
  match proof_tree with
  | cbv_constr lp _ _ => maxl (map max_active_size lp)
  | cbv_split lp p _ _ => max (max_active_size p) (maxl (map max_active_size lp)) 
  | cbv_function _ _ p t v => max (term_size t + value_size v) (max_active_size p)
  end.Fixpoint max_judgement_size (proof_tree : cbv) : nat :=
  match proof_tree with
  | cbv_constr lp t v => max (term_size t + value_size v) (maxl (map max_judgement_size lp))
  | cbv_split lp p t v => max (term_size t + value_size v) (max (max_judgement_size p) (maxl (map max_judgement_size lp)))
  | cbv_function _ _ p t v => max (term_size t + value_size v) (max_judgement_size p)
  end.(* Sub-trees *)

Fixpoint sub_trees (proof_tree : cbv) : list cbv :=
  proof_tree :: (
    match proof_tree with
    | cbv_constr lp _ _ => flat_map sub_trees lp
    | cbv_split lp p _ _ => flat_map sub_trees (p :: lp)
    | cbv_function _ _ p _ _ => sub_trees p
    end ).

Lemma proj_left_size_le_max_gen default proof_trees proof_tree: In proof_tree proof_trees -> term_size (proj_left proof_tree) <= term_size (proj_left (proj_left_max_size_list default proof_trees)).