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_update _ _ p _ _ _ _ => 1 + nb_judgements p
| cbv_read _ _ _=> 1
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_update _ _ _ _ _ _ _ => 0
| cbv_read _ _ _ => 0
end.
Definition nb_judgements_sub (proof_tree : cbv) : nat :=
match proof_tree with
| cbv_constr _ _ _ _ _ => 0
| cbv_split _ _ _ _ _ _ => 0
| cbv_update _ _ p _ _ _ _ => nb_judgements_sub_rec p
| cbv_read _ _ _ => 0
end.
Fixpoint nb_nodes (proof_tree : cbv) : nat :=
match proof_tree with
| cbv_constr [] _ _ _ _ => 0
| cbv_constr lp _ _ _ _ => 1 + suml (map nb_nodes lp)
| cbv_split lp p _ _ _ _ => 1 + nb_nodes p + suml (map nb_nodes lp)
| cbv_update _ _ p _ _ _ _ => 1 + nb_nodes p
| cbv_read _ _ _ => 0
end.
Fixpoint nb_read (proof_tree : cbv) : nat :=
match proof_tree with
| cbv_constr lp _ _ _ _ => suml (map nb_read lp)
| cbv_split lp p _ _ _ _ => nb_read p + suml (map nb_read lp)
| cbv_update _ _ p _ _ _ _ => nb_read p
| cbv_read _ _ _ => 1
end.
Definition arity_cbv (proof_tree : cbv) : nat :=
match proof_tree with
| cbv_constr lp _ _ _ _  => length lp
| cbv_split lp p _ _ _ _ => 1 + length lp
| cbv_update _ _ p _ _ _ _ => 1
| cbv_read _ _ _ => 0
end.

(* Specifications: *)
Lemma wf_arity p : wf p -> arity_cbv p <= S max_arity.
Lemma nb_read_bound : forall p,
wf p ->
nb_read p <= S (max_arity * nb_nodes p).