(* similar remark apply here… *)

(* Specifications: *)
Proposition BC_to_TRS_rules_vars_defined bc n s st:
let trs := snd (BC_to_TRS bc st) in
arities bc = ok_arities n s →
Forall rule_vars_defined trs.(rules).
(*****************************************************************************)
(*                                                                           *)
(*                       Max arity is correct                                *)
(*                                                                           *)
(*****************************************************************************)
Lemma max_arity_prog_cons (r:rule) rl: (* => Syntax.v ? *)
max_arity_prog (r::rl) =
max (max_arity_rule r) (max_arity_prog rl).
Lemma max_arity_fapply_app f (l1 l2: list term): (* => Syntax.v ? *)
max_arity_term (fapply f (l1++l2)) =
max (length (l1++l2))
(max (maxl (map (@max_arity_term _ _ _) l1))
(maxl (map (@max_arity_term _ _ _) l2))).
Lemma max_arity_map_mk_call n (l: list trs_prog):
l ≠ [] → (maxl (map (@max_arity_term _ _ _) (map (mk_call_trs n) l))) = n.
Lemma max_arity_make_rec n s g h0 h1 f:
max_arity_prog (rules g) ≤ maxar g →
max_arity_prog (rules h0) ≤ maxar h0 →
max_arity_prog (rules h1) ≤ maxar h1 →
max_arity_prog (rules (make_rec (S n) s g h0 h1 f)) ≤
maxar (make_rec (S n) s g h0 h1 f).
Lemma max_arity_make_comp n s h gN gS f:
max_arity_prog (rules h) ≤ maxar h →
(max_arity_prog (concat (map rules gN))) ≤ maxl (map maxar gN) →
(max_arity_prog (concat (map rules gS))) ≤ maxl (map maxar gS) →
max_arity_prog (rules (make_comp n s h gN gS f)) ≤ maxar (make_comp n s h gN gS f).
Lemma max_arity_prog_forall l:
Forall (λ prg, max_arity_prog (rules prg) ≤ maxar prg) l →
(max_arity_prog (concat (map rules l))) ≤ maxl (map maxar l).
Proposition BC_to_TRS_arity bc n s st:
let trs := snd (BC_to_TRS bc st) in
arities bc = ok_arities n s →
max_arity_prog trs.(rules) ≤ trs.(maxar).
(*****************************************************************************)
(*                                                                           *)
(*                     Translation is well-formed                            *)
(*                                                                           *)
(*****************************************************************************)
Theorem BC_to_TRS_wf bc n s st:
let trs := snd (BC_to_TRS bc st) in
arities bc = ok_arities n s →
wf_prog trs.(maxar) trs.(rules).
(*****************************************************************************)
(*                                                                           *)
(*              Every function number is within the bounds                   *)
(*                                                                           *)
(*****************************************************************************)
(* first and last do save the monad state (before and after) *)
Lemma BC_to_TRS_state_bounds bc st:
let (st',trs) := BC_to_TRS bc st in
st+1 = trs.(first) ∧ trs.(last) = st'.
(* to allow rewrite *)
Lemma BC_to_TRS_first bc st:
(snd (BC_to_TRS bc st)).(first) = st+1.
Lemma BC_to_TRS_last bc st:
(snd (BC_to_TRS bc st)).(last) = fst (BC_to_TRS bc st).
Lemma BC_to_TRS_first_le_last bc st:
let trs := snd (BC_to_TRS bc st) in
trs.(first) ≤ trs.(last).
(* functions are within the bounds *)
Lemma funcs_bounds_aux bcl st st' f f_up:
fmono f_up →
(∀ bc, bc ∈ bcl → ∀ s f', f' ∈ all_lhs_funcs (snd (BC_to_TRS bc s)) →
s+1 <= f' <= f_up (fst (BC_to_TRS bc s))) →
st <= st' →
f ∈ map lhs_func (get_rules (snd (lm_to_ml (map BC_to_TRS bcl) st'))) →
st+1 <= f <= f_up (fst (lm_to_ml (map BC_to_TRS bcl) st')).
Proposition BC_to_TRS_func_bounds bc st f:
let trs := snd (BC_to_TRS bc st) in
f ∈ all_lhs_funcs trs → trs.(first) ≤ f ≤ trs.(last).
(* main is always the last function number *)
Lemma BC_to_TRS_main_is_last bc st:
let trs := snd (BC_to_TRS bc st) in
trs.(main) = trs.(last).
Lemma map_BC_to_TRS_func_bounds bcl st f:
let lm := map BC_to_TRS bcl in
let trsl := snd ((lm_to_ml lm) st) in
let lst := fst ((lm_to_ml lm) st) in
f ∈ flat_map all_lhs_funcs trsl → st+1 ≤ f ≤ lst.
(*****************************************************************************)
(*                                                                           *)
(*     the list of fun having an info is exactly the list of fun in lhs      *)
(*                                                                           *)
(*****************************************************************************)
Lemma BC_to_TRS_all_funs_have_info bc st f:
let trs := snd (BC_to_TRS bc st) in
f ∈ all_lhs_funcs trs → f ∈ map fst trs.(infos).
Lemma BC_to_TRS_only_funs_have_info bc st f:
let trs := snd (BC_to_TRS bc st) in
f ∈ map fst trs.(infos) → f ∈ all_lhs_funcs trs.
Proposition BC_to_TRS_infos_iff bc st f:
let trs := snd (BC_to_TRS bc st) in
f ∈ map fst trs.(infos) ↔ f ∈ all_lhs_funcs trs.
Lemma BC_to_TRS_info_explicit bc st f:
let trs := snd (BC_to_TRS bc st) in
f ∈ all_lhs_funcs (snd (BC_to_TRS bc st)) →
(f, get_info trs f) ∈ trs.(infos).
Lemma map_BC_to_TRS_infos_iff bcl st f:
f ∈ flat_map all_lhs_funcs (snd (lm_to_ml (map BC_to_TRS bcl) st)) ↔
f ∈ map fst (get_infos (snd (lm_to_ml (map BC_to_TRS bcl) st))).
(*****************************************************************************)
(*                                                                           *)
(*     fun in rhs are defined somewhere (ie, in at least one lhs)            *)
(*                                                                           *)
(*****************************************************************************)
(* main is defined *)
Lemma BC_to_TRS_main_defined bc st:
let trs := snd (BC_to_TRS bc st) in
trs.(main) ∈ all_lhs_funcs trs.
(* rhs fun. appear in some lhs *)
Lemma BC_to_TRS_rhs_funcs_defined bc st:
let trs := snd (BC_to_TRS bc st) in
incl (all_rhs_funcs trs.(rules)) (all_lhs_funcs trs).
Lemma map_BC_to_TRS_lhs_in bcl st r:
r ∈ get_rules (snd ((lm_to_ml (map BC_to_TRS bcl)) st)) →
(lhs_func r) ∈ flat_map all_lhs_funcs (snd (lm_to_ml (map BC_to_TRS bcl) st)).
(*****************************************************************************)
(*                                                                           *)
(*                            facts about rank                               *)
(*                                                                           *)
(*****************************************************************************)
Lemma BC_to_TRS_pos_maxrank bc st:
let trs := snd (BC_to_TRS bc st) in
0 < trs.(maxrank).
(* maxrank is indeed a bound on the ranks of fun *)
Lemma BC_to_TRS_maxrank bc st:
let trs := snd (BC_to_TRS bc st) in
maxl (map rank (map snd trs.(infos))) ≤ trs.(maxrank).
Lemma BC_to_TRS_maxrank_is_max_rank bc st:
let trs := snd (BC_to_TRS bc st) in
∀ f, f ∈ all_lhs_funcs trs →
get_rank trs f <= trs.(maxrank).
Lemma BC_to_TRS_maxrank_is_max_rank_error bc st:
let trs := snd (BC_to_TRS bc st) in
∀ f, get_rank trs f <= trs.(maxrank).
(* main always has the highest rank *)
Lemma BC_to_TRS_main_has_maxrank bc st n s:
let trs := snd (BC_to_TRS bc st) in
arities bc = ok_arities n s →
get_rank trs trs.(main) = trs.(maxrank).
Lemma BC_to_TRS_rank_main_aux f bc st inf n s:
let trs := snd (BC_to_TRS bc st) in
arities bc = ok_arities n s →
assoc Nat.eqb f trs.(infos) = Some inf →
rank inf ≤ rank_main trs.
Lemma BC_to_TRS_lm_to_ml_rank_aux f inf st bcl n s:
let trsl := snd (lm_to_ml (map BC_to_TRS bcl) st) in
(∀ bc : BC, bc ∈ bcl → arities bc = ok_arities n s) →
assoc Nat.eqb f (get_infos trsl) = Some inf →
rank inf ≤ maxl (map rank_main trsl).
(* main is the only function with maximum rank *)
Lemma BC_to_TRS_main_has_unique_max_rank bc n s:
arities bc = ok_arities n s → ∀ st f,
let trs := snd (BC_to_TRS bc st) in
f < trs.(main) → get_rank trs f < get_rank trs trs.(main).
(*****************************************************************************)
(*                                                                           *)
(*                 Fetching the correct info in various cases                *)
(*                                                                           *)
(*****************************************************************************)
Lemma get_info_in_list trs bcl st f:
let trsl:=snd (lm_to_ml (map BC_to_TRS bcl) st) in
trs ∈ trsl → f ∈ all_lhs_funcs trs →
get_info_l trsl f = get_info trs f.
Lemma get_info_main_list trs bcl st:
let trsl := snd (lm_to_ml (map BC_to_TRS bcl) st) in
trs ∈ trsl → get_info_l trsl trs.(main) = get_info trs trs.(main).
Lemma BC_to_TRS_infos_subst_rec_first g h0 h1 st n s f:
f ∈ all_lhs_funcs (snd (BC_to_TRS g st)) →
get_info (snd ((BC_to_TRS g >>+ BC_to_TRS h0 >>++ BC_to_TRS h1
>>+ Mnew_fun >>== Mmr (S n) s) st)) f =
get_info (snd (BC_to_TRS g st)) f.
Lemma BC_to_TRS_infos_subst_rec_second g h0 h1 st n s f:
f ∈ all_lhs_funcs (snd (BC_to_TRS h0 (fst (BC_to_TRS g st)))) →
get_info (snd ((BC_to_TRS g >>+ BC_to_TRS h0 >>++ BC_to_TRS h1
>>+ Mnew_fun >>== Mmr (S n) s) st)) f =
get_info (snd (BC_to_TRS h0 (fst (BC_to_TRS g st)))) f.
Lemma BC_to_TRS_infos_subst_rec_third g h0 h1 st n s f:
f ∈ all_lhs_funcs (snd (BC_to_TRS h1 (fst (BC_to_TRS h0 (fst (BC_to_TRS g st)))))) →
get_info (snd ((BC_to_TRS g >>+ BC_to_TRS h0 >>++ BC_to_TRS h1
>>+ Mnew_fun >>== Mmr (S n) s) st)) f =
get_info (snd (BC_to_TRS h1 (fst (BC_to_TRS h0 (fst (BC_to_TRS g st)))))) f.
Lemma BC_to_TRS_infos_subst_comp_first h rl tl st n s f:
f ∈ all_lhs_funcs (snd (BC_to_TRS h st)) →
get_info (snd ((BC_to_TRS h >>+ lm_to_ml (map BC_to_TRS rl) >>++
lm_to_ml (map BC_to_TRS tl) >>+ Mnew_fun >>== Mmc n s) st)) f =
get_info (snd (BC_to_TRS h st)) f.
Lemma BC_to_TRS_infos_subst_comp_second h rl tl st n s f:
f ∈ flat_map all_lhs_funcs (snd (lm_to_ml (map BC_to_TRS rl) (fst (BC_to_TRS h st)))) →
get_info (snd ((BC_to_TRS h >>+ lm_to_ml (map BC_to_TRS rl) >>++
lm_to_ml (map BC_to_TRS tl) >>+ Mnew_fun >>== Mmc n s) st)) f =
get_info_l (snd (lm_to_ml (map BC_to_TRS rl) (fst (BC_to_TRS h st)))) f.
Lemma BC_to_TRS_infos_subst_comp_third h rl tl st n s f:
let st' := fst (lm_to_ml (map BC_to_TRS rl) (fst (BC_to_TRS h st))) in
f ∈ flat_map all_lhs_funcs (snd (lm_to_ml (map BC_to_TRS tl) st')) →
get_info (snd ((BC_to_TRS h >>+ lm_to_ml (map BC_to_TRS rl) >>++
lm_to_ml (map BC_to_TRS tl) >>+ Mnew_fun >>== Mmc n s) st)) f =
get_info_l (snd (lm_to_ml (map BC_to_TRS tl) st')) f.