Theory Implicit_Exhaustive_Factorization

theory Implicit_Exhaustive_Factorization
  imports
    Exhaustive_Factorization
    Exhaustive_Resolution
begin

section ‹Function for implicit full factorization›

context simulation_SCLFOL_ground_ordered_resolution begin

definition iefac where
  "iefac  C = (if C |∈|  then efac C else C)"

lemma iefac_mempty[simp]:
  fixes  :: "'f gclause fset"
  shows "iefac  {#} = {#}"
  by (metis efac_mempty iefac_def)

lemma fset_mset_iefac[simp]: 
  fixes  :: "'f gclause fset" and C :: "'f gclause"
  shows "fset_mset (iefac  C) = fset_mset C"
proof (cases "C |∈| ")
  case True
  hence "iefac  C = efac C"
    unfolding iefac_def by simp
  thus ?thesis
    by auto
next
  case False
  hence "iefac  C = C"
    unfolding iefac_def by simp
  thus ?thesis by simp
qed

lemma atms_of_cls_iefac[simp]:
  fixes  :: "'f gclause fset" and C :: "'f gclause"
  shows "atms_of_cls (iefac  C) = atms_of_cls C"
  by (simp add: atms_of_cls_def)

lemma iefac_le:
  fixes  :: "'f gclause fset" and C :: "'f gclause"
  shows "iefac  C c C"
  by (metis efac_subset iefac_def reflclp_iff subset_implies_reflclp_multp)

lemma true_cls_iefac_iff[simp]:
  fixes  :: "'f gterm set" and  :: "'f gclause fset" and C :: "'f gclause"
  shows "  iefac  C    C"
  by (metis iefac_def true_cls_efac_iff)

(*
ifac |`| (N |∪| Uer) |⊆| (N |∪| Uer |∪| Uef) = (ifac |`| (N |∪| Uer)) |∪| N |∪| Uer
*)
lemma funion_funion_eq_funion_funion_fimage_iefac_if:
  assumes Uef_eq: "Uef = iefac  |`| {|C |∈| N |∪| Uer. iefac  C  C|}"
  shows "N |∪| Uer |∪| Uef = N |∪| Uer |∪| (iefac  |`| (N |∪| Uer))"
proof (intro fsubset_antisym fsubsetI)
  fix C :: "'f gterm clause"
  assume "C |∈| N |∪| Uer |∪| Uef"
  hence "C |∈| N |∪| Uer  C |∈| Uef"
    by simp
  thus "C |∈| N |∪| Uer |∪| (iefac  |`| (N |∪| Uer))"
  proof (elim disjE)
    assume "C |∈| N |∪| Uer"
    thus ?thesis
      by simp
  next
    assume "C |∈| Uef"
    hence "C |∈| iefac  |`| {|C |∈| N |∪| Uer. iefac  C  C|}"
      using Uef_eq by argo
    then obtain C0 :: "'f gterm clause" where
      "C0 |∈| N |∪| Uer" and "iefac  C0  C0" and "C = iefac  C0"
      by auto
    thus ?thesis
      by simp
  qed
next
  fix C :: "'f gterm clause"
  assume "C |∈| N |∪| Uer |∪| (iefac  |`| (N |∪| Uer))"
  hence "C |∈| N |∪| Uer  C |∈| iefac  |`| (N |∪| Uer)"
    by simp
  thus "C |∈| N |∪| Uer |∪| Uef"
  proof (elim disjE)
    assume "C |∈| N |∪| Uer"
    thus ?thesis
      by simp
  next
    assume "C |∈| iefac  |`| (N |∪| Uer)"
    then obtain C0 :: "'f gterm clause" where
      "C0 |∈| N |∪| Uer" and "C = iefac  C0"
      by auto

    show ?thesis
    proof (cases "iefac  C0 = C0")
      case True
      hence "C = C0"
        using C = iefac  C0 by argo
      thus ?thesis
        using C0 |∈| N |∪| Uer by simp
    next
      case False
      hence "C |∈| Uef"
        unfolding Uef_eq
        using C0 |∈| N |∪| Uer C = iefac  C0 by simp
      thus ?thesis
        by simp
    qed
  qed
qed


lemma clauses_for_iefac_are_unproductive:
  "C |∈| N |-| iefac  |`| N. U. ord_res.production U C = {}"
proof (intro ballI allI)
  fix C U
  assume "C |∈| N |-| iefac  |`| N"
  hence "C |∈| N" and "C |∉| iefac  |`| N"
    by simp_all
  hence "iefac  C  C"
    by (metis fimage_iff)
  hence "efac C  C"
    by (metis iefac_def)
  hence "L. is_pos L  ord_res.is_strictly_maximal_lit L C"
    using nex_strictly_maximal_pos_lit_if_neq_efac by metis
  thus "ord_res.production U C = {}"
    using unproductive_if_nex_strictly_maximal_pos_lit by metis
qed

lemma clauses_for_iefac_have_smaller_entailing_clause:
  "C |∈| N |-| iefac  |`| N. D |∈| iefac  |`| N. D c C  {D} ⊫e {C}"
proof (intro ballI allI)
  fix C
  assume "C |∈| N |-| iefac  |`| N"
  hence "C |∈| N" and "C |∉| iefac  |`| N"
    by simp_all
  hence "iefac  C  C"
    by (metis fimage_iff)
  hence "efac C  C"
    by (metis iefac_def)

  show "D |∈| iefac  |`| N. D c C  {D} ⊫e {C}"
  proof (intro bexI conjI)
    show "efac C c C" and "{efac C} ⊫e {C}"
      using efac_properties_if_not_ident[OF efac C  C] by simp_all
  next
    show "efac C |∈| iefac  |`| N"
      using C |∈| N iefac  C  C by (metis fimageI iefac_def)
  qed
qed

lemma is_least_false_clause_with_iefac_conv:
  "is_least_false_clause (N |∪| Uer |∪| iefac  |`| (N |∪| Uer)) =
    is_least_false_clause (iefac  |`| (N |∪| Uer))"
  using is_least_false_clause_funion_cancel_right_strong[OF clauses_for_iefac_are_unproductive
    clauses_for_iefac_have_smaller_entailing_clause]
  by (simp add: sup_commute)

lemma MAGIC4:
  fixes N  ℱ' Uer Uer'
  defines
    "N1  iefac  |`| (N |∪| Uer)" and
    "N2  iefac ℱ' |`| (N |∪| Uer')"
  assumes
    subsets_agree: "{|x |∈| N1. x c C|} = {|x |∈| N2. x c C|}" and
    "is_least_false_clause N1 D" and
    "is_least_false_clause N2 E" and
    "C c D"
  shows "C c E"
proof -
  have "¬ E c C"
  proof (rule notI)
    assume "E c C"

    have "is_least_false_clause N2 E  is_least_false_clause {|x |∈| N2. x c E|} E"
    proof (rule is_least_false_clause_swap_swap_compatible_fsets)
      show "{|x |∈| N2. (≺c)== x E|} = {|x |∈| {|x |∈| N2. (≺c)== x E|}. (≺c)== x E|}"
        using E c C by force
    qed

    also have "  is_least_false_clause {|x |∈| N1. x c E|} E"
    proof (rule is_least_false_clause_swap_swap_compatible_fsets)
      show "{|x |∈| {|x |∈| N2. (≺c)== x E|}. (≺c)== x E|} =
        {|x |∈| {|x |∈| N1. (≺c)== x E|}. (≺c)== x E|}"
        using subsets_agree E c C by fastforce
    qed

    also have "  is_least_false_clause N1 E"
    proof (rule is_least_false_clause_swap_swap_compatible_fsets)
      show "{|x |∈| {|x |∈| N1. (≺c)== x E|}. (≺c)== x E|} = {|x |∈| N1. (≺c)== x E|}"
        using E c C by fastforce
    qed

    finally have "is_least_false_clause N1 E"
      using is_least_false_clause N2 E by argo

    hence "D = E"
      using is_least_false_clause N1 D
      by (metis Uniq_is_least_false_clause the1_equality')

    thus False
      using E c C C c D by order
  qed
  thus "C c E"
    by order
qed

lemma atms_of_clss_fimage_iefac[simp]:
  "atms_of_clss (iefac  |`| N) = atms_of_clss N"
proof -
  have "atms_of_clss (iefac  |`| N) = ffUnion (atms_of_cls |`| iefac  |`| N)"
    unfolding atms_of_clss_def ..

  also have " = ffUnion ((atms_of_cls  iefac ) |`| N)"
    by simp

  also have " = ffUnion (atms_of_cls |`| N)"
    unfolding comp_def atms_of_cls_iefac ..

  also have " = atms_of_clss N"
    unfolding atms_of_clss_def ..

  finally show ?thesis .
qed

lemma atm_of_in_atms_of_clssI:
  assumes L_in: "L ∈# C" and C_in: "C |∈| iefac  |`| N"
  shows "atm_of L |∈| atms_of_clss N"
proof -
  have "atm_of L |∈| atms_of_cls C"
    unfolding atms_of_cls_def
    using L_in by simp

  hence "atm_of L |∈| atms_of_clss (iefac  |`| N)"
    unfolding atms_of_clss_def
    using C_in by (metis fmember_ffUnion_iff)

  thus "atm_of L |∈| atms_of_clss N"
    by simp
qed

lemma clause_almost_almost_definedI:
  fixes Γ D K
  assumes
    D_in: "D |∈| iefac  |`| (N |∪| Uer)" and
    D_max_lit: "ord_res.is_maximal_lit K D" and
    no_undef_atm: "¬ (A|∈|atms_of_clss (N |∪| Uer). A t atm_of K  A |∉| trail_atms Γ)"
  shows "trail_defined_cls Γ {#L ∈# D. L  K  L  - K#}"
  unfolding trail_defined_cls_def
proof (intro ballI)
  have "K ∈# D" and lit_in_D_le_K: "L. L ∈# D  L l K"
    using D_max_lit
    unfolding atomize_imp atomize_all atomize_conj linorder_lit.is_maximal_in_mset_iff
    using linorder_lit.leI by blast

  fix L :: "'f gterm literal"
  assume "L ∈# {#L ∈# D. L  K  L  - K#}"

  hence "L ∈# D" and "L  K" and "L  - K"
    by simp_all

  have "atm_of L |∈| atms_of_clss (N |∪| Uer)"
    using L ∈# D D_in by (metis atm_of_in_atms_of_clssI)

  hence "atm_of L t atm_of K  atm_of L |∈| trail_atms Γ"
    using no_undef_atm by metis

  moreover have "atm_of L t atm_of K"
    using lit_in_D_le_K[OF L ∈# D] L  K L  - K
    by (cases L; cases K) simp_all

  ultimately show "trail_defined_lit Γ L"
    using trail_defined_lit_iff_trail_defined_atm by auto
qed

lemma clause_almost_definedI:
  fixes Γ D K
  assumes
    D_in: "D |∈| iefac  |`| (N |∪| Uer)" and
    D_max_lit: "ord_res.is_maximal_lit K D" and
    no_undef_atm: "¬ (A|∈|atms_of_clss (N |∪| Uer). A t atm_of K  A |∉| trail_atms Γ)" and
    K_defined: "trail_defined_lit Γ K"
  shows "trail_defined_cls Γ {#Ka ∈# D. Ka  K#}"
  using clause_almost_almost_definedI[OF D_in D_max_lit no_undef_atm]
  using K_defined
  unfolding trail_defined_cls_def trail_defined_lit_def
  by (metis (mono_tags, lifting) mem_Collect_eq set_mset_filter uminus_lit_swap)

lemma eres_not_in_known_clauses_if_trail_false_cls:
  fixes
     :: "'f gclause fset" and
    Γ :: "('f gliteral × 'f gclause option) list"
  assumes
    Γ_consistent: "trail_consistent Γ" and
    clauses_lt_E_true: "C |∈| iefac  |`| (N |∪| Uer). C c E  trail_true_cls Γ C" and
    "eres D E c E" and
    "trail_false_cls Γ (eres D E)"
  shows "eres D E |∉| N |∪| Uer"
proof (rule notI)
  have "iefac  (eres D E) c eres D E"
    using iefac_le by metis
  hence "iefac  (eres D E) c E"
    using eres D E c E by order

  moreover assume "eres D E |∈| N |∪| Uer"

  ultimately have "trail_true_cls Γ (iefac  (eres D E))"
    using clauses_lt_E_true[rule_format, of "iefac  (eres D E)"]
    by (simp add: iefac_def linorder_lit.is_maximal_in_mset_iff)

  hence "trail_true_cls Γ (eres D E)"
    unfolding trail_true_cls_def
    by (metis fset_fset_mset fset_mset_iefac)

  thus False
    using Γ_consistent trail_false_cls Γ (eres D E)
    by (metis not_trail_true_cls_and_trail_false_cls)
qed

lemma no_undefined_atom_le_max_lit_of_false_clause:
  assumes
    Γ_lower_set: "linorder_trm.is_lower_fset (trail_atms Γ) (atms_of_clss (N |∪| Uer))" and
    D_in: "D |∈| iefac  |`| (N |∪| Uer)" and
    D_false: "trail_false_cls Γ D" and
    D_max_lit: "linorder_lit.is_maximal_in_mset D L"
  shows "¬ (A|∈|atms_of_clss (N |∪| Uer). A t atm_of L  A |∉| trail_atms Γ)"
proof -
  have "trail_false_lit Γ L"
    using D_false D_max_lit
    unfolding trail_false_cls_def linorder_lit.is_maximal_in_mset_iff by simp

  hence "trail_defined_lit Γ L"
    unfolding trail_false_lit_def trail_defined_lit_def by argo

  hence "atm_of L |∈| trail_atms Γ"
    unfolding trail_defined_lit_iff_trail_defined_atm .

  thus ?thesis
    using Γ_lower_set
    using linorder_trm.not_in_lower_setI by blast
qed

lemma trail_defined_if_no_undef_atom_le_max_lit:
  assumes
    C_in: "C |∈| iefac  |`| (N |∪| Uer)" and
    C_max_lit: "linorder_lit.is_maximal_in_mset C K" and
    no_undef_atom_le_K:
      "¬ (A|∈|atms_of_clss (N |∪| Uer). A t atm_of K  A |∉| trail_atms Γ)"
  shows "trail_defined_cls Γ C"
proof -

  have "x. x ∈# C  atm_of x t atm_of K"
    using C_in C_max_lit
    unfolding linorder_lit.is_maximal_in_mset_iff
    by (metis linorder_trm.le_cases linorder_trm.le_less_linear literal.exhaust_sel
        ord_res.less_lit_simps(1) ord_res.less_lit_simps(2) ord_res.less_lit_simps(3)
        ord_res.less_lit_simps(4))

  hence "x. x ∈# C  trail_defined_lit Γ x"
    using C_in no_undef_atom_le_K
    by (meson atm_of_in_atms_of_clssI trail_defined_lit_iff_trail_defined_atm)

  thus "trail_defined_cls Γ C"
    unfolding trail_defined_cls_def
    by metis
qed

lemma no_undef_atom_le_max_lit_if_lt_false_clause:
  assumes
    Γ_lower_set: "linorder_trm.is_lower_fset (trail_atms Γ) (atms_of_clss (N |∪| Uer))" and
    D_in: "D |∈| iefac  |`| (N |∪| Uer)" and
    D_false: "trail_false_cls Γ D" and
    D_max_lit: "linorder_lit.is_maximal_in_mset D L" and
    C_in: "C |∈| iefac  |`| (N |∪| Uer)" and
    C_max_lit: "linorder_lit.is_maximal_in_mset C K" and
    C_lt: "C c D"
  shows "¬ (A|∈|atms_of_clss (N |∪| Uer). A t atm_of K  A |∉| trail_atms Γ)"
proof -
  have "K l L"
    using C_lt C_max_lit D_max_lit
    using linorder_cls.less_imp_not_less linorder_lit.multp_if_maximal_less_that_maximal
      linorder_lit.nle_le by blast

  hence "atm_of K t atm_of L"
    by (cases K; cases L) simp_all

  thus "¬ (A|∈|atms_of_clss (N |∪| Uer). A t atm_of K  A |∉| trail_atms Γ)"
    using no_undefined_atom_le_max_lit_of_false_clause[OF assms(1,2,3,4)]
    by fastforce
qed

lemma bex_trail_false_cls_simp:
  fixes  N Γ
  shows "fBex (iefac  |`| N) (trail_false_cls Γ)  fBex N (trail_false_cls Γ)"
proof (rule iffI ; elim bexE)
  fix C :: "'f gclause"
  assume C_in: "C |∈| iefac  |`| N" and C_false: "trail_false_cls Γ C"
  thus "fBex N (trail_false_cls Γ)"
    by (smt (verit, ccfv_SIG) fimage_iff iefac_def set_mset_efac trail_false_cls_def)
next
  fix C :: "'f gclause"
  assume "C |∈| N" and "trail_false_cls Γ C"
  thus "fBex (iefac  |`| N) (trail_false_cls Γ)"
    by (metis fimageI iefac_def set_mset_efac trail_false_cls_def)
qed

end

end