(* liens entre PPO et sous-terme *)
Fixpoint sub_terms (t: term) : list term :=
t :: match t with
| var _ => []
| capply _ lt => flat_map sub_terms lt
| fapply _ lt => flat_map sub_terms lt
end.
Definition sub_terms_strict (t: term) : list term :=
match t with
| var _ => []
| capply _ lt => flat_map sub_terms lt
| fapply _ lt => flat_map sub_terms lt
end.

(* Specifications: *)
Lemma sub_term_strict_incl (t: term) :
incl (sub_terms_strict t) (sub_terms t).
Lemma sub_term_eq_or_strict (t1 t2: term) :
In t1 (sub_terms t2) <-> t1 = t2 \/ In t1 (sub_terms_strict t2).
Lemma sub_term_le_size (t1 t2: term) :
In t1 (sub_terms t2) -> t2 = t1 \/ term_size t1 < term_size t2.
Lemma sub_terms_strict_strict (t: term) :
~ In t (sub_terms_strict t).
Lemma sub_term_strict_lt_size (t1 t2: term) :
In t1 (sub_terms_strict t2) -> term_size t1 < term_size t2.
Lemma PPO_value_is_sub_term (t v: term) :
@term_value _ _ _ v ->
(PPO rank t v <-> In t (sub_terms_strict v)).
Lemma PPO_value_lt_size (v v': value) :
PPO rank (@term_from_value variable function constructor v) (@term_from_value _ _ _ v') ->
value_size v < value_size v'.