(* Sizes *)
Fixpoint size_rec (proof_tree : cbv) : nat :=
match proof_tree with
| cbv_constr l c1 t c2 v => term_size t + value_size v + suml (map size_rec l)
| cbv_split l p c1 t c2 v => term_size t + value_size v + size_rec p + suml (map size_rec l)
| cbv_update _ _ p c1 t c2 v => size_rec p + term_size t + value_size v
| cbv_read c t v => term_size t + value_size v
end.
Definition size (proof_tree : cbv) : nat :=
size_rec proof_tree + cache_size (cache_left proof_tree).
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_update _ _ p _ t _ v => max (term_size t + value_size v) (max_active_size p)
| cbv_read c t v => 0
end.
Fixpoint max_judgement_size (proof_tree : cbv) : nat :=
match proof_tree with
| cbv_constr lp c1 t c2 v => max (term_size t + value_size v) (maxl (map max_judgement_size lp))
| cbv_split lp p c1 t c2 v => max (term_size t + value_size v) (max (max_judgement_size p) (maxl (map max_judgement_size lp)))
| cbv_update _ _ p c1 t c2 v => max (term_size t + value_size v) (max_judgement_size p)
| cbv_read c t v => term_size t + value_size v
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_update _ _ p _ _ _ _ => sub_trees p
| cbv_read _ _ _ => []
end ).

Lemma sub_trees_neq_nil : forall p, sub_trees p <> [].