Definition activation_rank (p : cbv) : nat :=
match p with
| cbv_update _ _ _ _ (fapply f _) _ _ => rank f
| _                                   => 0
end.

(* Specifications: *)
Lemma fapplies_rec_PPO t t': In t (fapplies_in_term t') -> clos_refl PPO t t'.
Lemma PPO_value_is_value t v : PPO t v -> term_value v -> term_value t.
Lemma PPO_activation_le_rank f1 lt1 f2 lv2 :
PPO (fapply f1 lt1) (fapply f2 (map (@term_from_value _ _ _) lv2)) -> rank f1 <= rank f2.
Lemma PPO_pattern_le_rank f1 lt1 f2 lp2 :
PPO (fapply f1 lt1) (fapply f2 (map (@term_from_pattern _ _ _) lp2)) -> rank f1 <= rank f2.
Lemma subfapplies_activation_le_rank i s p c1 f lt c2 v f' lt' :
let proof_tree := cbv_update i s p c1 (fapply f lt) c2 v in
PPO_prog -> wf proof_tree ->
In (fapply f' lt') (fapplies_in_term (proj_left p)) ->
rank f' <= rank f.
Lemma le_rank_first_activation i s p c1 t c2 v p' :
let proof_tree := cbv_update i s p c1 t c2 v in
PPO_prog -> wf proof_tree ->
In p' (first_activations proof_tree) ->
activation_rank p' <= activation_rank proof_tree.
Lemma PPO_first_activations i s p c1 t c2 v p' :
let proof_tree := cbv_update i s p c1 t c2 v in
PPO_prog -> wf proof_tree ->
In p' (first_activations proof_tree) ->
PPO (proj_left p') (proj_left proof_tree).
Lemma PPO_activations i s p c1 t c2 v p' :
let proof_tree := cbv_update i s p c1 t c2 v in
PPO_prog -> wf proof_tree ->
In p' (activations proof_tree) ->
p' = proof_tree \/ PPO (proj_left p') (proj_left proof_tree).