Hint Resolve lt_0_pow.
Hint Rewrite mult_1_l.
Fixpoint first_activations_at_given_rank (rk: nat) (proof_tree : cbv) : list cbv :=
match proof_tree with
| cbv_constr lp _ _ _ _ => flat_map (first_activations_at_given_rank rk) lp
| cbv_split lp p _ _ _ _ => first_activations_at_given_rank rk p ++ flat_map (first_activations_at_given_rank rk) lp
| cbv_update _ _ p _ (fapply f _) _ _ as p' => if eq_nat_dec rk (rank f)
then [ p' ]
else first_activations_at_given_rank rk p
| _ => [] (* cbv_read and ill-formed cbv_update *)
end.
Definition activation_function (function_default : function) (p: cbv) :=
match p with
| cbv_update _ _ _ _ (fapply f _) _ _ => f
| _                                   => function_default
end.

(* Specifications: *)
Lemma first_activations_at_given_rank_rank rk p p' :
In p' (first_activations_at_given_rank rk p) ->
rk = activation_rank rank p'.
Lemma first_activations_at_given_rank_sublist_activations rk p :
sublist (first_activations_at_given_rank rk p) (activations p).
Lemma NoDup_activations i s p c1 t c2 v :
PPO_prog ->
wf (cbv_update i s p c1 t c2 v) ->
NoDup (activations (cbv_update i s p c1 t c2 v)).
Lemma NoDup_first_activations_at_given_rank rk i s p c1 t c2 v :
PPO_prog ->
wf (cbv_update i s p c1 t c2 v) ->
NoDup (first_activations_at_given_rank rk (cbv_update i s p c1 t c2 v)).
Lemma first_activations_at_given_rank_activations rk p:
incl (first_activations_at_given_rank rk p) (activations p).
Lemma A_T_activation_rank (p p' : cbv) :
In p' (first_activations_at_given_rank (activation_rank rank p') p) ->
length (activations_at_rank (activation_rank rank p') p') <= A_T p.
Lemma activation_eq_dec p i s p0 c1 t c2 v:
let proof_tree := cbv_update i s p0 c1 t c2 v in
PPO_prog ->
wf proof_tree ->
In p (activations proof_tree) -> p = proof_tree \/ p <> proof_tree.
Lemma activations_trans p p' p'' : wf p'' ->
In p (activations p') -> In p' (activations p'') -> In p (activations p'').
Lemma first_activation_down p i s p0 c1 t c2 v:
let proof_tree := cbv_update i s p0 c1 t c2 v in
PPO_prog ->
wf proof_tree -> p <> proof_tree ->
In p (activations proof_tree) ->
exists p', In p' (activations proof_tree) /\ In p (first_activations p').