Theory Calculus_Variations

(*  Title:       Variations on a Theme
 *  Author:      Sophie Tourret <stourret at mpi-inf.mpg.de>, 2018-2020 *)

section ‹Variations on a Theme›

text ‹In this section, section 2.4 of the report is covered, demonstrating
  that various notions of redundancy are equivalent.›

theory Calculus_Variations
  imports Calculus
begin

locale reduced_calculus = calculus Bot Inf entails Red_I Red_F
  for
    Bot :: "'f set" and
    Inf :: ‹'f inference set› and
    entails :: "'f set ⇒ 'f set ⇒ bool" (infix ‹⊨› 50) and
    Red_I :: "'f set ⇒ 'f inference set" and
    Red_F :: "'f set ⇒ 'f set"
 + assumes
   inf_in_red_inf: "Inf_between UNIV (Red_F N) ⊆ Red_I N"
begin

(* lem:reduced-rc-implies-sat-equiv-reduced-sat *)
lemma sat_eq_reduc_sat: "saturated N ⟷ reduc_saturated N"
proof
  fix N
  assume "saturated N"
  then show "reduc_saturated N"
    using Red_I_without_red_F saturated_without_red_F
    unfolding saturated_def reduc_saturated_def
    by blast
next
  fix N
  assume red_sat_n: "reduc_saturated N"
  show "saturated N" unfolding saturated_def
    using red_sat_n inf_in_red_inf unfolding reduc_saturated_def Inf_from_def Inf_between_def
    by blast
qed

end

locale reducedly_statically_complete_calculus = calculus +
  assumes reducedly_statically_complete:
    "B ∈ Bot ⟹ reduc_saturated N ⟹ N ⊨ {B} ⟹ ∃B'∈Bot. B' ∈ N"

locale reducedly_statically_complete_reduced_calculus = reduced_calculus +
  assumes reducedly_statically_complete:
    "B ∈ Bot ⟹ reduc_saturated N ⟹ N ⊨ {B} ⟹ ∃B'∈Bot. B' ∈ N"
begin

sublocale reducedly_statically_complete_calculus
  by (simp add: calculus_axioms reducedly_statically_complete
    reducedly_statically_complete_calculus_axioms.intro
    reducedly_statically_complete_calculus_def)

(* cor:reduced-rc-implies-st-ref-comp-equiv-reduced-st-ref-comp 1/2 *)
sublocale statically_complete_calculus
proof
  fix B N
  assume
    bot_elem: ‹B ∈ Bot› and
    saturated_N: "saturated N" and
    refut_N: "N ⊨ {B}"
  have reduc_saturated_N: "reduc_saturated N" using saturated_N sat_eq_reduc_sat by blast
  show "∃B'∈Bot. B' ∈ N" using reducedly_statically_complete[OF bot_elem reduc_saturated_N refut_N] .
qed

end

context reduced_calculus
begin

(* cor:reduced-rc-implies-st-ref-comp-equiv-reduced-st-ref-comp 2/2 *)
lemma stat_ref_comp_imp_red_stat_ref_comp:
  "statically_complete_calculus Bot Inf entails Red_I Red_F ⟹
   reducedly_statically_complete_calculus Bot Inf entails Red_I Red_F"
proof
  fix B N
  assume
    stat_ref_comp: "statically_complete_calculus Bot Inf (⊨) Red_I Red_F" and
    bot_elem: ‹B ∈ Bot› and
    saturated_N: "reduc_saturated N" and
    refut_N: "N ⊨ {B}"
  have reduc_saturated_N: "saturated N" using saturated_N sat_eq_reduc_sat by blast
  show "∃B'∈Bot. B' ∈ N"
    using statically_complete_calculus.statically_complete[OF stat_ref_comp
      bot_elem reduc_saturated_N refut_N] .
qed

end

context calculus
begin

definition Red_Red_I :: "'f set ⇒ 'f inference set" where
  "Red_Red_I N = Red_I N ∪ Inf_between UNIV (Red_F N)"

lemma reduced_calc_is_calc: "calculus Bot Inf entails Red_Red_I Red_F"
proof
  fix N
  show "Red_Red_I N ⊆ Inf"
    unfolding Red_Red_I_def Inf_between_def Inf_from_def using Red_I_to_Inf by auto
next
  fix B N
  assume
    b_in: "B ∈ Bot" and
    n_entails: "N ⊨ {B}"
  show "N - Red_F N ⊨ {B}"
    by (simp add: Red_F_Bot b_in n_entails)
next
  fix N N' :: "'f set"
  assume "N ⊆ N'"
  then show "Red_F N ⊆ Red_F N'" by (simp add: Red_F_of_subset)
next
  fix N N' :: "'f set"
  assume n_in: "N ⊆ N'"
  then have "Inf_from (UNIV - (Red_F N')) ⊆ Inf_from (UNIV - (Red_F N))"
    using Red_F_of_subset[OF n_in] unfolding Inf_from_def by auto
  then have "Inf_between UNIV (Red_F N) ⊆ Inf_between UNIV (Red_F N')"
    unfolding Inf_between_def by auto
  then show "Red_Red_I N ⊆ Red_Red_I N'"
    unfolding Red_Red_I_def using Red_I_of_subset[OF n_in] by blast
next
  fix N N' :: "'f set"
  assume "N' ⊆ Red_F N"
  then show "Red_F N ⊆ Red_F (N - N')" by (simp add: Red_F_of_Red_F_subset)
next
  fix N N' :: "'f set"
  assume np_subs: "N' ⊆ Red_F N"
  have "Red_F N ⊆ Red_F (N - N')" by (simp add: Red_F_of_Red_F_subset np_subs)
  then have "Inf_from (UNIV - (Red_F (N - N'))) ⊆ Inf_from (UNIV - (Red_F N))"
    by (metis Diff_subset Red_F_of_subset eq_iff)
  then have "Inf_between UNIV (Red_F N) ⊆ Inf_between UNIV (Red_F (N - N'))"
    unfolding Inf_between_def by auto
  then show "Red_Red_I N ⊆ Red_Red_I (N - N')"
    unfolding Red_Red_I_def using Red_I_of_Red_F_subset[OF np_subs] by blast
next
  fix ι N
  assume "ι ∈ Inf"
    "concl_of ι ∈ N"
  then show "ι ∈ Red_Red_I N"
    by (simp add: Red_I_of_Inf_to_N Red_Red_I_def)
qed

lemma inf_subs_reduced_red_inf: "Inf_between UNIV (Red_F N) ⊆ Red_Red_I N"
  unfolding Red_Red_I_def by simp

(* lem:red'-is-reduced-redcrit *)
text ‹The following is a lemma and not a sublocale as was previously used in similar cases.
  Here, a sublocale cannot be used because it would create an infinitely descending
  chain of sublocales. ›
lemma reduc_calc: "reduced_calculus Bot Inf entails Red_Red_I Red_F"
  using inf_subs_reduced_red_inf reduced_calc_is_calc
  by (simp add: reduced_calculus.intro reduced_calculus_axioms_def)

interpretation reduc_calc: reduced_calculus Bot Inf entails Red_Red_I Red_F
  by (fact reduc_calc)

(* lem:saturation-red-vs-red'-1 *)
lemma sat_imp_red_calc_sat: "saturated N ⟹ reduc_calc.saturated N"
  unfolding saturated_def reduc_calc.saturated_def Red_Red_I_def by blast

(* lem:saturation-red-vs-red'-2 1/2 (i) ⟷ (ii) *)
lemma red_sat_eq_red_calc_sat: "reduc_saturated N ⟷ reduc_calc.saturated N"
proof
  assume red_sat_n: "reduc_saturated N"
  show "reduc_calc.saturated N"
    unfolding reduc_calc.saturated_def
  proof
    fix ι
    assume i_in: "ι ∈ Inf_from N"
    show "ι ∈ Red_Red_I N"
      using i_in red_sat_n
      unfolding reduc_saturated_def Inf_between_def Inf_from_def Red_Red_I_def by blast
  qed
next
  assume red_sat_n: "reduc_calc.saturated N"
  show "reduc_saturated N"
    unfolding reduc_saturated_def
  proof
    fix ι
    assume i_in: "ι ∈ Inf_from (N - Red_F N)"
    show "ι ∈ Red_I N"
      using i_in red_sat_n
      unfolding Inf_from_def reduc_calc.saturated_def Red_Red_I_def Inf_between_def by blast
  qed
qed

(* lem:saturation-red-vs-red'-2 2/2 (i) ⟷ (iii) *)
lemma red_sat_eq_sat: "reduc_saturated N ⟷ saturated (N - Red_F N)"
  unfolding reduc_saturated_def saturated_def by (simp add: Red_I_without_red_F)

(* thm:reduced-stat-ref-compl 1/3 (i) ⟷ (iii) *)
theorem stat_is_stat_red: "statically_complete_calculus Bot Inf entails Red_I Red_F ⟷
  statically_complete_calculus Bot Inf entails Red_Red_I Red_F"
proof
  assume
    stat_ref1: "statically_complete_calculus Bot Inf entails Red_I Red_F"
  show "statically_complete_calculus Bot Inf entails Red_Red_I Red_F"
    using reduc_calc.calculus_axioms
    unfolding statically_complete_calculus_def statically_complete_calculus_axioms_def
  proof
    show "∀B N. B ∈ Bot ⟶ reduc_calc.saturated N ⟶ N ⊨ {B} ⟶ (∃B'∈Bot. B' ∈ N)"
    proof (clarify)
      fix B N
      assume
        b_in: "B ∈ Bot" and
        n_sat: "reduc_calc.saturated N" and
        n_imp_b: "N ⊨ {B}"
      have "saturated (N - Red_F N)" using red_sat_eq_red_calc_sat[of N] red_sat_eq_sat[of N] n_sat by blast
      moreover have "(N - Red_F N) ⊨ {B}" using n_imp_b b_in by (simp add: reduc_calc.Red_F_Bot)
      ultimately show "∃B'∈Bot. B'∈ N"
        using stat_ref1 by (meson DiffD1 b_in statically_complete_calculus.statically_complete)
    qed
  qed
next
  assume
    stat_ref3: "statically_complete_calculus Bot Inf entails Red_Red_I Red_F"
  show "statically_complete_calculus Bot Inf entails Red_I Red_F"
    unfolding statically_complete_calculus_def statically_complete_calculus_axioms_def
    using calculus_axioms
  proof
    show "∀B N. B ∈ Bot ⟶ saturated N ⟶ N ⊨ {B} ⟶ (∃B'∈Bot. B' ∈ N)"
    proof clarify
      fix B N
      assume
        b_in: "B ∈ Bot" and
        n_sat: "saturated N" and
        n_imp_b: "N ⊨ {B}"
      then show "∃B'∈ Bot. B' ∈ N"
        using stat_ref3 sat_imp_red_calc_sat[OF n_sat]
        by (meson statically_complete_calculus.statically_complete)
    qed
  qed
qed

(* thm:reduced-stat-ref-compl 2/3 (iv) ⟷ (iii) *)
theorem red_stat_red_is_stat_red:
  "reducedly_statically_complete_calculus Bot Inf entails Red_Red_I Red_F ⟷
   statically_complete_calculus Bot Inf entails Red_Red_I Red_F"
  using reduc_calc.stat_ref_comp_imp_red_stat_ref_comp
  by (metis reduc_calc.sat_eq_reduc_sat reducedly_statically_complete_calculus.axioms(2)
    reducedly_statically_complete_calculus_axioms_def reduced_calc_is_calc
    statically_complete_calculus.intro statically_complete_calculus_axioms.intro)

(* thm:reduced-stat-ref-compl 3/3 (ii) ⟷ (iii) *)
theorem red_stat_is_stat_red:
  "reducedly_statically_complete_calculus Bot Inf entails Red_I Red_F ⟷
   statically_complete_calculus Bot Inf entails Red_Red_I Red_F"
  using reduc_calc.calculus_axioms calculus_axioms red_sat_eq_red_calc_sat
  unfolding statically_complete_calculus_def statically_complete_calculus_axioms_def
    reducedly_statically_complete_calculus_def reducedly_statically_complete_calculus_axioms_def
  by blast

lemma sup_red_f_in_red_liminf:
  "chain derive Ns ⟹ Sup_llist (lmap Red_F Ns) ⊆ Red_F (Liminf_llist Ns)"
proof
  fix N
  assume
    deriv: "chain derive Ns" and
    n_in_sup: "N ∈ Sup_llist (lmap Red_F Ns)"
  obtain i0 where i_smaller: "enat i0 < llength Ns" and n_in: "N ∈ Red_F (lnth Ns i0)"
    using n_in_sup by (metis Sup_llist_imp_exists_index llength_lmap lnth_lmap)
  have "Red_F (lnth Ns i0) ⊆ Red_F (Liminf_llist Ns)"
    using i_smaller by (simp add: deriv Red_F_subset_Liminf)
  then show "N ∈ Red_F (Liminf_llist Ns)"
    using n_in by fast
qed

lemma sup_red_inf_in_red_liminf:
  "chain derive Ns ⟹ Sup_llist (lmap Red_I Ns) ⊆ Red_I (Liminf_llist Ns)"
proof
  fix ι
  assume
    deriv: "chain derive Ns" and
    i_in_sup: "ι ∈ Sup_llist (lmap Red_I Ns)"
  obtain i0 where i_smaller: "enat i0 < llength Ns" and n_in: "ι ∈ Red_I (lnth Ns i0)"
    using i_in_sup unfolding Sup_llist_def by auto
  have "Red_I (lnth Ns i0) ⊆ Red_I (Liminf_llist Ns)"
    using i_smaller by (simp add: deriv Red_I_subset_Liminf)
  then show "ι ∈ Red_I (Liminf_llist Ns)"
    using n_in by fast
qed

definition reduc_fair :: "'f set llist ⇒ bool" where
  "reduc_fair Ns ⟷
   Inf_from (Liminf_llist Ns - Sup_llist (lmap Red_F Ns)) ⊆ Sup_llist (lmap Red_I Ns)"

(* lem:red-fairness-implies-red-saturation *)
lemma reduc_fair_imp_Liminf_reduc_sat:
  "chain derive Ns ⟹ reduc_fair Ns ⟹ reduc_saturated (Liminf_llist Ns)"
  unfolding reduc_saturated_def
proof -
  fix Ns
  assume
    deriv: "chain derive Ns" and
    red_fair: "reduc_fair Ns"
  have "Inf_from (Liminf_llist Ns - Red_F (Liminf_llist Ns))
    ⊆ Inf_from (Liminf_llist Ns - Sup_llist (lmap Red_F Ns))"
    using sup_red_f_in_red_liminf[OF deriv] unfolding Inf_from_def by blast
  then have "Inf_from (Liminf_llist Ns - Red_F (Liminf_llist Ns)) ⊆ Sup_llist (lmap Red_I Ns)"
    using red_fair unfolding reduc_fair_def by simp
  then show "Inf_from (Liminf_llist Ns - Red_F (Liminf_llist Ns)) ⊆ Red_I (Liminf_llist Ns)"
    using sup_red_inf_in_red_liminf[OF deriv] by fast
qed

end

locale reducedly_dynamically_complete_calculus = calculus +
  assumes
    reducedly_dynamically_complete: "B ∈ Bot ⟹ chain derive Ns ⟹ reduc_fair Ns ⟹
      lhd Ns ⊨ {B} ⟹ ∃i ∈ {i. enat i < llength Ns}. ∃ B'∈Bot. B' ∈ lnth Ns i"
begin

sublocale reducedly_statically_complete_calculus
proof
  fix B N
  assume
    bot_elem: ‹B ∈ Bot› and
    saturated_N: "reduc_saturated N" and
    refut_N: "N ⊨ {B}"
  define Ns where "Ns = LCons N LNil"
  have[simp]: ‹¬ lnull Ns› by (auto simp: Ns_def)
  have deriv_D: ‹chain (⊳) Ns› by (simp add: chain.chain_singleton Ns_def)
  have liminf_is_N: "Liminf_llist Ns = N" by (simp add: Ns_def Liminf_llist_LCons)
  have head_D: "N = lhd Ns" by (simp add: Ns_def)
  have "Sup_llist (lmap Red_F Ns) = Red_F N" by (simp add: Ns_def)
  moreover have "Sup_llist (lmap Red_I Ns) = Red_I N" by (simp add: Ns_def)
  ultimately have fair_D: "reduc_fair Ns"
    using saturated_N liminf_is_N unfolding reduc_fair_def reduc_saturated_def
    by (simp add: reduc_fair_def reduc_saturated_def liminf_is_N)
  obtain i B' where B'_is_bot: ‹B' ∈ Bot› and B'_in: "B' ∈ lnth Ns i" and ‹i < llength Ns›
    using reducedly_dynamically_complete[of B Ns] bot_elem fair_D head_D saturated_N deriv_D refut_N
    by auto
  then have "i = 0"
    by (auto simp: Ns_def enat_0_iff)
  show ‹∃B'∈Bot. B' ∈ N›
    using B'_is_bot B'_in unfolding ‹i = 0› head_D[symmetric] Ns_def by auto
qed

end

sublocale reducedly_statically_complete_calculus ⊆ reducedly_dynamically_complete_calculus
proof
  fix B Ns
  assume
    bot_elem: ‹B ∈ Bot› and
    deriv: ‹chain (⊳) Ns› and
    fair: ‹reduc_fair Ns› and
    unsat: ‹lhd Ns ⊨ {B}›
    have non_empty: ‹¬ lnull Ns› using chain_not_lnull[OF deriv] .
    have subs: ‹lhd Ns ⊆ Sup_llist Ns›
      using lhd_subset_Sup_llist[of Ns] non_empty by (simp add: lhd_conv_lnth)
    have ‹Sup_llist Ns ⊨ {B}›
      using unsat subset_entailed[OF subs] entails_trans[of "Sup_llist Ns" "lhd Ns"] by auto
    then have Sup_no_Red: ‹Sup_llist Ns - Red_F (Sup_llist Ns) ⊨ {B}›
      using bot_elem Red_F_Bot by auto
    have Sup_no_Red_in_Liminf: ‹Sup_llist Ns - Red_F (Sup_llist Ns) ⊆ Liminf_llist Ns›
      using deriv Red_in_Sup by auto
    have Liminf_entails_Bot: ‹Liminf_llist Ns ⊨ {B}›
      using Sup_no_Red subset_entailed[OF Sup_no_Red_in_Liminf] entails_trans by blast
    have ‹reduc_saturated (Liminf_llist Ns)›
    using deriv fair reduc_fair_imp_Liminf_reduc_sat unfolding reduc_saturated_def
      by auto
   then have ‹∃B'∈Bot. B' ∈ Liminf_llist Ns›
     using bot_elem reducedly_statically_complete Liminf_entails_Bot
     by auto
   then show ‹∃i∈{i. enat i < llength Ns}. ∃B'∈Bot. B' ∈ lnth Ns i›
     unfolding Liminf_llist_def by auto
qed

context calculus
begin

lemma dyn_equiv_stat: "dynamically_complete_calculus Bot Inf entails Red_I Red_F =
  statically_complete_calculus Bot Inf entails Red_I Red_F"
proof
  assume "dynamically_complete_calculus Bot Inf entails Red_I Red_F"
  then interpret dynamically_complete_calculus Bot Inf entails Red_I Red_F
    by simp
  show "statically_complete_calculus Bot Inf entails Red_I Red_F"
    by (simp add: statically_complete_calculus_axioms)
next
  assume "statically_complete_calculus Bot Inf entails Red_I Red_F"
  then interpret statically_complete_calculus Bot Inf entails Red_I Red_F
    by simp
  show "dynamically_complete_calculus Bot Inf entails Red_I Red_F"
    by (simp add: dynamically_complete_calculus_axioms)
qed

lemma red_dyn_equiv_red_stat:
  "reducedly_dynamically_complete_calculus Bot Inf entails Red_I Red_F =
   reducedly_statically_complete_calculus Bot Inf entails Red_I Red_F"
proof
  assume "reducedly_dynamically_complete_calculus Bot Inf entails Red_I Red_F"
  then interpret reducedly_dynamically_complete_calculus Bot Inf entails Red_I Red_F
    by simp
  show "reducedly_statically_complete_calculus Bot Inf entails Red_I Red_F"
    by (simp add: reducedly_statically_complete_calculus_axioms)
next
  assume "reducedly_statically_complete_calculus Bot Inf entails Red_I Red_F"
  then interpret reducedly_statically_complete_calculus Bot Inf entails Red_I Red_F
    by simp
  show "reducedly_dynamically_complete_calculus Bot Inf entails Red_I Red_F"
    by (simp add: reducedly_dynamically_complete_calculus_axioms)
qed

interpretation reduc_calc: reduced_calculus Bot Inf entails Red_Red_I Red_F
  by (fact reduc_calc)

(* thm:reduced-dyn-ref-compl 1/3 (v) ⟷ (vii) *)
theorem dyn_ref_eq_dyn_ref_red:
  "dynamically_complete_calculus Bot Inf entails Red_I Red_F ⟷
   dynamically_complete_calculus Bot Inf entails Red_Red_I Red_F"
  using dyn_equiv_stat stat_is_stat_red reduc_calc.dyn_equiv_stat by meson

(* thm:reduced-dyn-ref-compl 2/3 (viii) ⟷ (vii) *)
theorem red_dyn_ref_red_eq_dyn_ref_red:
  "reducedly_dynamically_complete_calculus Bot Inf entails Red_Red_I Red_F ⟷
   dynamically_complete_calculus Bot Inf entails Red_Red_I Red_F"
  using red_dyn_equiv_red_stat dyn_equiv_stat red_stat_red_is_stat_red
  by (simp add: reduc_calc.dyn_equiv_stat reduc_calc.red_dyn_equiv_red_stat)

(* thm:reduced-dyn-ref-compl 3/3 (vi) ⟷ (vii) *)
theorem red_dyn_ref_eq_dyn_ref_red:
  "reducedly_dynamically_complete_calculus Bot Inf entails Red_I Red_F ⟷
   dynamically_complete_calculus Bot Inf entails Red_Red_I Red_F"
  using red_dyn_equiv_red_stat dyn_equiv_stat red_stat_is_stat_red
    reduc_calc.dyn_equiv_stat reduc_calc.red_dyn_equiv_red_stat
  by blast

end

end