Theory Standard_Redundancy

(*  Title:       The Standard Redundancy Criterion
    Author:      Jasmin Blanchette <j.c.blanchette at vu.nl>, 2014, 2017
    Author:      Dmitriy Traytel <traytel at inf.ethz.ch>, 2014
    Author:      Anders Schlichtkrull <andschl at dtu.dk>, 2017
    Maintainer:  Anders Schlichtkrull <andschl at dtu.dk>
*)

section ‹The Standard Redundancy Criterion›

theory Standard_Redundancy
  imports Proving_Process
begin

text ‹
This material is based on Section 4.2.2 (``The Standard Redundancy Criterion'') of Bachmair and
Ganzinger's chapter.
›

locale standard_redundancy_criterion =
  inference_system Γ for Γ :: "('a :: wellorder) inference set"
begin

definition redundant_infer :: "'a clause set  'a inference  bool" where
  "redundant_infer N γ 
   (DD. set_mset DD  N  (I. I ⊨m DD + side_prems_of γ  I  concl_of γ)
       (D. D ∈# DD  D < main_prem_of γ))"

definition Rf :: "'a clause set  'a clause set" where
  "Rf N = {C. DD. set_mset DD  N  (I. I ⊨m DD  I  C)  (D. D ∈# DD  D < C)}"

definition Ri :: "'a clause set  'a inference set" where
  "Ri N = {γ  Γ. redundant_infer N γ}"

lemma tautology_Rf:
  assumes "Pos A ∈# C"
  assumes "Neg A ∈# C"
  shows "C  Rf N"
proof -
  have "set_mset {#}  N  (I. I ⊨m {#}  I  C)  (D. D ∈# {#}  D < C)"
    using assms by auto
  then show "C  Rf N"
    unfolding Rf_def by blast
qed

lemma tautology_redundant_infer:
  assumes
    pos: "Pos A ∈# concl_of ι" and
    neg: "Neg A ∈# concl_of ι"
  shows "redundant_infer N ι"
  by (metis empty_iff empty_subsetI neg pos pos_neg_in_imp_true redundant_infer_def set_mset_empty)

lemma contradiction_Rf: "{#}  N  Rf N = UNIV - {{#}}"
  unfolding Rf_def by force

text ‹
The following results correspond to Lemma 4.5. The lemma wlog_non_Rf› generalizes the core of
the argument.
›

lemma Rf_mono: "N  N'  Rf N  Rf N'"
  unfolding Rf_def by auto

lemma wlog_non_Rf:
  assumes ex: "DD. set_mset DD  N  (I. I ⊨m DD + CC  I  E)  (D'. D' ∈# DD  D' < D)"
  shows "DD. set_mset DD  N - Rf N  (I. I ⊨m DD + CC  I  E)  (D'. D' ∈# DD  D' < D)"
proof -
  from ex obtain DD0 where
    dd0: "DD0  {DD. set_mset DD  N  (I. I ⊨m DD + CC  I  E)  (D'. D' ∈# DD  D' < D)}"
    by blast
  have "DD. set_mset DD  N  (I. I ⊨m DD + CC  I  E)  (D'. D' ∈# DD  D' < D) 
      (DD'. set_mset DD'  N  (I. I ⊨m DD' + CC  I  E)  (D'. D' ∈# DD'  D' < D) 
    DD  DD')"
    using wf_eq_minimal[THEN iffD1, rule_format, OF wf_less_multiset dd0]
    unfolding not_le[symmetric] by blast
  then obtain DD where
    dd_subs_n: "set_mset DD  N" and
    ddcc_imp_e: "I. I ⊨m DD + CC  I  E" and
    dd_lt_d: "D'. D' ∈# DD  D' < D" and
    d_min: "DD'. set_mset DD'  N  (I. I ⊨m DD' + CC  I  E)  (D'. D' ∈# DD'  D' < D) 
      DD  DD'"
    by blast

  have "Da. Da ∈# DD  Da  Rf N"
  proof clarify
    fix Da
    assume
      da_in_dd: "Da ∈# DD" and
      da_rf: "Da  Rf N"

    from da_rf obtain DD' where
      dd'_subs_n: "set_mset DD'  N" and
      dd'_imp_da: "I. I ⊨m DD'  I  Da" and
      dd'_lt_da: "D'. D' ∈# DD'  D' < Da"
      unfolding Rf_def by blast

    define DDa where
      "DDa = DD - {#Da#} + DD'"

    have "set_mset DDa  N"
      unfolding DDa_def using dd_subs_n dd'_subs_n
      by (meson contra_subsetD in_diffD subsetI union_iff)
    moreover have "I. I ⊨m DDa + CC  I  E"
      using dd'_imp_da ddcc_imp_e da_in_dd unfolding DDa_def true_cls_mset_def
      by (metis in_remove1_mset_neq union_iff)
    moreover have "D'. D' ∈# DDa  D' < D"
      using dd_lt_d dd'_lt_da da_in_dd unfolding DDa_def
      by (metis insert_DiffM2 order.strict_trans union_iff)
    moreover have "DDa < DD"
      unfolding DDa_def
      by (meson da_in_dd dd'_lt_da mset_lt_single_right_iff single_subset_iff union_le_diff_plus)
    ultimately show False
      using d_min unfolding less_eq_multiset_def by (auto intro!: antisym)
  qed
  then show ?thesis
    using dd_subs_n ddcc_imp_e dd_lt_d by auto
qed

lemma Rf_imp_ex_non_Rf:
  assumes "C  Rf N"
  shows "CC. set_mset CC  N - Rf N  (I. I ⊨m CC  I  C)  (C'. C' ∈# CC  C' < C)"
  using assms by (auto simp: Rf_def intro: wlog_non_Rf[of _ "{#}", simplified])

lemma Rf_subs_Rf_diff_Rf: "Rf N  Rf (N - Rf N)"
proof
  fix C
  assume c_rf: "C  Rf N"
  then obtain CC where
    cc_subs: "set_mset CC  N - Rf N" and
    cc_imp_c: "I. I ⊨m CC  I  C" and
    cc_lt_c: "C'. C' ∈# CC  C' < C"
    using Rf_imp_ex_non_Rf by blast
  have "D. D ∈# CC  D  Rf N"
    using cc_subs by (simp add: subset_iff)
  then have cc_nr:
    "C DD. C ∈# CC  set_mset DD  N  I. I ⊨m DD  I  C  D. D ∈# DD  ¬ D < C"
      unfolding Rf_def by auto metis
  have "set_mset CC  N"
    using cc_subs by auto
  then have "set_mset CC 
    N - {C. DD. set_mset DD  N  (I. I ⊨m DD  I  C)  (D. D ∈# DD  D < C)}"
    using cc_nr by blast
  then show "C  Rf (N - Rf N)"
    using cc_imp_c cc_lt_c unfolding Rf_def by auto
qed

lemma Rf_eq_Rf_diff_Rf: "Rf N = Rf (N - Rf N)"
  by (metis Diff_subset Rf_mono Rf_subs_Rf_diff_Rf subset_antisym)

text ‹
The following results correspond to Lemma 4.6.
›

lemma Ri_mono: "N  N'  Ri N  Ri N'"
  unfolding Ri_def redundant_infer_def by auto

lemma Ri_subs_Ri_diff_Rf: "Ri N  Ri (N - Rf N)"
proof
  fix γ
  assume γ_ri: "γ  Ri N"
  then obtain CC D E where γ: "γ = Infer CC D E"
    by (cases γ)
  have cc: "CC = side_prems_of γ" and d: "D = main_prem_of γ" and e: "E = concl_of γ"
    unfolding γ by simp_all
  obtain DD where
    "set_mset DD  N" and "I. I ⊨m DD + CC  I  E" and "C. C ∈# DD  C < D"
    using γ_ri unfolding Ri_def redundant_infer_def cc d e by blast
  then obtain DD' where
    "set_mset DD'  N - Rf N" and "I. I ⊨m DD' + CC  I  E" and "D'. D' ∈# DD'  D' < D"
    using wlog_non_Rf by atomize_elim blast
  then show "γ  Ri (N - Rf N)"
    using γ_ri unfolding Ri_def redundant_infer_def d cc e by blast
qed

lemma Ri_eq_Ri_diff_Rf: "Ri N = Ri (N - Rf N)"
  by (metis Diff_subset Ri_mono Ri_subs_Ri_diff_Rf subset_antisym)

lemma Ri_subset_Γ: "Ri N  Γ"
  unfolding Ri_def by blast

lemma Rf_indep: "N'  Rf N  Rf N  Rf (N - N')"
  by (metis Diff_cancel Diff_eq_empty_iff Diff_mono Rf_eq_Rf_diff_Rf Rf_mono)

lemma Ri_indep: "N'  Rf N  Ri N  Ri (N - N')"
  by (metis Diff_mono Ri_eq_Ri_diff_Rf Ri_mono order_refl)

lemma Rf_model:
  assumes "I ⊨s N - Rf N"
  shows "I ⊨s N"
proof -
  have "I ⊨s Rf (N - Rf N)"
    unfolding true_clss_def
    by (subst Rf_def, simp add: true_cls_mset_def, metis assms subset_eq true_clss_def)
  then have "I ⊨s Rf N"
    using Rf_subs_Rf_diff_Rf true_clss_mono by blast
  then show ?thesis
    using assms by (metis Un_Diff_cancel true_clss_union)
qed

lemma Rf_sat: "satisfiable (N - Rf N)  satisfiable N"
  by (metis Rf_model)

text ‹
The following corresponds to Theorem 4.7:
›

sublocale redundancy_criterion Γ Rf Ri
  by unfold_locales (rule Ri_subset_Γ, (elim Rf_mono Ri_mono Rf_indep Ri_indep Rf_sat)+)

end

locale standard_redundancy_criterion_reductive =
  standard_redundancy_criterion + reductive_inference_system
begin

text ‹
The following corresponds to Theorem 4.8:
›

lemma Ri_effective:
  assumes
    in_γ: "γ  Γ" and
    concl_of_in_n_un_rf_n: "concl_of γ  N  Rf N"
  shows "γ  Ri N"
proof -
  obtain CC D E where
    γ: "γ = Infer CC D E"
    by (cases γ)
  then have cc: "CC = side_prems_of γ" and d: "D = main_prem_of γ" and e: "E = concl_of γ"
    unfolding γ by simp_all
  note e_in_n_un_rf_n = concl_of_in_n_un_rf_n[folded e]

  {
    assume "E  N"
    moreover have "E < D"
      using Γ_reductive e d in_γ by auto
    ultimately have
      "set_mset {#E#}  N" and "I. I ⊨m {#E#} + CC  I  E" and "D'. D' ∈# {#E#}  D' < D"
      by simp_all
    then have "redundant_infer N γ"
      using redundant_infer_def cc d e by blast
  }
  moreover
  {
    assume "E  Rf N"
    then obtain DD where
      dd_sset: "set_mset DD  N" and
      dd_imp_e: "I. I ⊨m DD  I  E" and
      dd_lt_e: "C'. C' ∈# DD  C' < E"
      unfolding Rf_def by blast
    from dd_lt_e have "Da. Da ∈# DD  Da < D"
      using d e in_γ Γ_reductive less_trans by blast
    then have "redundant_infer N γ"
      using redundant_infer_def dd_sset dd_imp_e cc d e by blast
  }
  ultimately show "γ  Ri N"
    using in_γ e_in_n_un_rf_n unfolding Ri_def by blast
qed

sublocale effective_redundancy_criterion Γ Rf Ri
  unfolding effective_redundancy_criterion_def
  by (intro conjI redundancy_criterion_axioms, unfold_locales, rule Ri_effective)

lemma contradiction_Rf: "{#}  N  Ri N = Γ"
  unfolding Ri_def redundant_infer_def using Γ_reductive le_multiset_empty_right
  by (force intro: exI[of _ "{#{#}#}"] le_multiset_empty_left)

end

locale standard_redundancy_criterion_counterex_reducing =
  standard_redundancy_criterion + counterex_reducing_inference_system
begin

text ‹
The following result corresponds to Theorem 4.9.
›

lemma saturated_upto_complete_if:
  assumes
    satur: "saturated_upto N" and
    unsat: "¬ satisfiable N"
  shows "{#}  N"
proof (rule ccontr)
  assume ec_ni_n: "{#}  N"

  define M where
    "M = N - Rf N"

  have ec_ni_m: "{#}  M"
    unfolding M_def using ec_ni_n by fast

  have "I_of M ⊨s M"
  proof (rule ccontr)
    assume "¬ I_of M ⊨s M"
    then obtain D where
      d_in_m: "D  M" and
      d_cex: "¬ I_of M  D" and
      d_min: "C. C  M  C < D  I_of M  C"
      using ex_min_counterex by meson
    then obtain γ CC E where
      γ: "γ = Infer CC D E" and
      cc_subs_m: "set_mset CC  M" and
      cc_true: "I_of M ⊨m CC" and
      γ_in: "γ  Γ" and
      e_cex: "¬ I_of M  E" and
      e_lt_d: "E < D"
      using Γ_counterex_reducing[OF ec_ni_m] not_less by metis
    have cc: "CC = side_prems_of γ" and d: "D = main_prem_of γ" and e: "E = concl_of γ"
      unfolding γ by simp_all
    have "γ  Ri N"
      by (rule subsetD[OF satur[unfolded saturated_upto_def inferences_from_def infer_from_def]])
        (simp add: γ_in d_in_m cc_subs_m cc[symmetric] d[symmetric] M_def[symmetric])
    then have "γ  Ri M"
      unfolding M_def using Ri_indep by fast
    then obtain DD where
      dd_subs_m: "set_mset DD  M" and
      dd_cc_imp_d: "I. I ⊨m DD + CC  I  E" and
      dd_lt_d: "C. C ∈# DD  C < D"
      unfolding Ri_def redundant_infer_def cc d e by blast
    from dd_subs_m dd_lt_d have "I_of M ⊨m DD"
      using d_min unfolding true_cls_mset_def by (metis contra_subsetD)
    then have "I_of M  E"
      using dd_cc_imp_d cc_true by auto
    then show False
      using e_cex by auto
  qed
  then have "I_of M ⊨s N"
    using M_def Rf_model by blast
  then show False
    using unsat by blast
qed

theorem saturated_upto_complete:
  assumes "saturated_upto N"
  shows "¬ satisfiable N  {#}  N"
  using assms saturated_upto_complete_if true_clss_def by auto

end

end