(*****************************************************************************************)
(*                  QI of function symbols / terms                                       *)
(*****************************************************************************************)
(* c'est cette forme qui est utilisée partout *)
Definition subterm (qif:assignment_function) := forall f l x, In x l -> x <= qif f l.
(*monotonicity*)
Definition monotonicity_qif (qif:assignment_function) :=
forall f lx ly, Forall2 le lx ly -> qif f lx <= qif f ly.
(* assignment of a term*)
Fixpoint term_assignment (qic:assignment_constructor) (qif:assignment_function)
(t:term) {struct t}:=
match t with
| var v=> 0 (* pas necessaire. Les QI sont toujours appliquées sur des termes clots. *)
| capply c lt => qic c (map (term_assignment qic qif) lt)
| fapply f lt=> qif f (map (term_assignment qic qif)  lt)
end.
(*Definition 12*)
Definition compatible_QI qic qif := forall f lp t, forall s:variable -> value,
let ru := rule_intro f lp t in (* f(p1, ..., pn) -> t *)
(In ru prog) ->
term_assignment qic qif (subst s t) <= term_assignment qic qif (subst s (lhs_of_rule ru)).
(* pour toute substitution, QI(t) <= QI(f(p1, ..., pn)) *)
Definition valid_QI qic qif cs :=
(additive qic cs) /\ (mcs_is_max_constructor_size cs) /\ (constructor_non_zero cs) /\
(subterm qif) /\ (monotonicity_qif qif) /\ (compatible_QI qic qif).
Definition cache_bounded qic qif (c:cache): Prop  :=
Forall (fun t => value_assignment qic (snd t) <= term_assignment qic qif (fst t)) c.

(* Specifications: *)
(* sous typage *)
Lemma value_as_term_assignment qic qif: forall v:value,
(term_assignment qic qif (term_from_value v)) = (value_assignment qic v).