Definition PPO_rule (r: rule) : Prop :=
  match r with
    | rule_intro f lp t => PPO t (fapply f (map (@term_from_pattern _ _ _) lp))
  end.Definition PPO_prog : Prop :=
  forall r, In r prog -> PPO_rule r.

(* Specifications: *)
Lemma value_PPO_function (v: value) (f: function) (lt: list term) : PPO (@term_from_value _ _ _ v) (fapply f lt).
Lemma product_trans (A: Type) (R : A -> A -> Prop) lt1 lt2 lt3 : (forall t1 t2 t3, In t1 lt1 -> In t2 lt2 -> In t3 lt3 -> R t1 t2 -> R t2 t3 -> R t1 t3) -> product R lt1 lt2 -> product R lt2 lt3 -> product R lt1 lt3.
Lemma PPO_trans t1 t2 t3 : PPO t1 t2 -> PPO t2 t3 -> PPO t1 t3.
Lemma PPO_trans_eq t1 t2 t3 : clos_refl PPO t1 t2 -> PPO t2 t3 -> PPO t1 t3.
Lemma PPO_trans_eq_r t1 t2 t3 : PPO t1 t2 -> clos_refl PPO t2 t3 -> PPO t1 t3.
Lemma PPO_asym t1 t2 : PPO t1 t2 -> ~ PPO t2 t1.
Lemma PPO_irrefl t : ~PPO t t.
Lemma PPO_term_pattern_subst p t s : PPO t (@term_from_pattern _ _ _ p) -> PPO (subst s t) (@term_from_value _ _ _ (psubst s p)).
Lemma fapply_not_PPO_value f lt v : term_value v -> ~ PPO (fapply f lt) v.
Lemma fapply_not_PPO_pattern f lt p : ~ PPO (fapply f lt) (@term_from_pattern _ _ _ p).
Lemma PPO_rule_PPO_instance s f lp t : PPO_rule (rule_intro f lp t) -> PPO (subst s t) (fapply f (map (@term_from_value _ _ _) (map (psubst s) lp))).
Lemma PPO_rule_instance i s p c1 t c2 v : PPO_prog -> wf (cbv_update i s p c1 t c2 v) -> PPO (proj_left p) t.