(*****************************************************************************************)
(*                        starting real proofs                                           *)
(*****************************************************************************************)

(* Specifications: *)
(* Les 2 lemmes suivants sont utilisés 2 fois par la suite. *)
Lemma qi_fapply_right_le_qi_fapply_left qic qif : forall proof_tree lp f c1,
monotonicity_qif qif ->
let l := map (proj_left (constructor:=constructor)) lp in
let l' := map term_from_value (map (proj_right (constructor:=constructor)) lp) in
let c := cache_left proof_tree in let v := proj_right proof_tree in
(forall p, In p lp -> cache_bounded qic qif (cache_left p) ->
value_assignment qic (proj_right p) <= term_assignment qic qif (proj_left p) /\
cache_bounded qic qif (cache_right p)) ->
cache_bounded qic qif c1 -> cache_path c1 c lp = true -> andl (map wf lp) ->
(term_assignment qic qif (fapply f l')) <= (term_assignment qic qif (fapply f l)).
Lemma qi_right_le_qi_fapply_left qic qif: forall proof_tree lp f c1,
monotonicity_qif qif -> wf proof_tree ->
let l := map (proj_left (constructor:=constructor)) lp in
let l' := map term_from_value (map (proj_right (constructor:=constructor)) lp) in
let c := cache_left proof_tree in let c' := cache_right proof_tree in
let v := proj_right proof_tree in
proj_left proof_tree = fapply f l' ->
(forall p, In p lp -> cache_bounded qic qif (cache_left p) -> wf p ->
value_assignment qic (proj_right p) <= term_assignment qic qif (proj_left p) /\
cache_bounded qic qif (cache_right p)) ->
(cache_bounded qic qif c -> value_assignment qic v <= term_assignment qic qif (fapply f l')) ->
cache_bounded qic qif c1 -> cache_bounded qic qif c' -> cache_path c1 c lp = true ->
andl (map wf lp) ->
value_assignment qic v <= term_assignment qic qif (fapply f l).
(* Lemma 68 *)
(* Lemme clé : pour chaque jugement de cache gauche borné, * le cache droit est aussi borné. * la QI de gauche est plus grande que la QI de droite *)
Lemma left_bound_to_right_bound qic qif cs:forall pi:cbv,
valid_QI qic qif cs -> (wf pi) ->
cache_bounded qic qif (cache_left pi) ->
(value_assignment qic (proj_right pi) <= term_assignment qic qif (proj_left pi)
/\ cache_bounded qic qif (cache_right pi)).