theory Completeness imports Unify begin
section {* Lifting Lemma *}
lemma lifting:
assumes fin: "finite C ∧ finite D "
assumes apart: "vars⇩l⇩s C ∩ vars⇩l⇩s D = {}"
assumes inst⇩1: "instance_of⇩l⇩s C' C"
assumes inst⇩2: "instance_of⇩l⇩s D' D"
assumes appl: "applicable C' D' L' M' σ"
shows "∃L M τ. applicable C D L M τ ∧
instance_of⇩l⇩s (resolution C' D' L' M' σ) (resolution C D L M τ)"
proof -
let ?C'⇩1 = "C' - L'"
let ?D'⇩1 = "D' - M'"
from inst⇩1 obtain lmbd where lmbd_p: "C ⋅⇩l⇩s lmbd = C'" unfolding instance_of⇩l⇩s_def by auto
from inst⇩2 obtain μ where μ_p: "D ⋅⇩l⇩s μ = D'" unfolding instance_of⇩l⇩s_def by auto
from μ_p lmbd_p apart obtain η where η_p: "C ⋅⇩l⇩s η = C' ∧ D ⋅⇩l⇩s η = D'" using merge_sub by force
from η_p have "∃L ⊆ C. L ⋅⇩l⇩s η = L' ∧ (C - L) ⋅⇩l⇩s η = ?C'⇩1" using appl project_sub[of η C C' L'] unfolding applicable_def by auto
then obtain L where L_p: "L ⊆ C ∧ L ⋅⇩l⇩s η = L' ∧ (C - L) ⋅⇩l⇩s η = ?C'⇩1" by auto
let ?C⇩1 = "C - L"
from η_p have "∃M ⊆ D. M ⋅⇩l⇩s η = M' ∧ (D - M) ⋅⇩l⇩s η = ?D'⇩1" using appl project_sub[of η D D' M'] unfolding applicable_def by auto
then obtain M where M_p: "M ⊆ D ∧ M ⋅⇩l⇩s η = M' ∧ (D - M) ⋅⇩l⇩s η = ?D'⇩1" by auto
let ?D⇩1 = "D - M"
from appl have "mgu⇩l⇩s σ (L' ∪ M'⇧C)" unfolding applicable_def by auto
then have "mgu⇩l⇩s σ ((L ⋅⇩l⇩s η) ∪ (M ⋅⇩l⇩s η)⇧C)" using L_p M_p by auto
then have "mgu⇩l⇩s σ ((L ∪ M⇧C) ⋅⇩l⇩s η)" using compls_subls subls_union by auto
then have "unifier⇩l⇩s σ ((L ∪ M⇧C) ⋅⇩l⇩s η)" unfolding mgu⇩l⇩s_def by auto
then have ησuni: "unifier⇩l⇩s (η ⋅ σ) (L ∪ M⇧C)"
unfolding unifier⇩l⇩s_def using composition_conseq2l by auto
then obtain τ where τ_p: "mgu⇩l⇩s τ (L ∪ M⇧C)" using unification fin by (meson L_p M_p finite_UnI finite_imageI rev_finite_subset)
then obtain φ where φ_p: "τ ⋅ φ = η ⋅ σ" using ησuni unfolding mgu⇩l⇩s_def by auto
let ?E = "((C - L) ∪ (D - M)) ⋅⇩l⇩s τ"
have "?E ⋅⇩l⇩s φ = (?C⇩1 ∪ ?D⇩1 ) ⋅⇩l⇩s (τ ⋅ φ)" using subls_union composition_conseq2ls by auto
also have "... = (?C⇩1 ∪ ?D⇩1 ) ⋅⇩l⇩s (η ⋅ σ)" using φ_p by auto
also have "... = ((?C⇩1 ⋅⇩l⇩s η) ∪ (?D⇩1 ⋅⇩l⇩s η)) ⋅⇩l⇩s σ" using subls_union composition_conseq2ls by auto
also have "... = (?C'⇩1 ∪ ?D'⇩1) ⋅⇩l⇩s σ" using η_p L_p M_p by auto
finally have "?E ⋅⇩l⇩s φ = ((C' - L') ∪ (D' - M')) ⋅⇩l⇩s σ" by auto
then have inst: "instance_of⇩l⇩s (resolution C' D' L' M' σ) (resolution C D L M τ) "
unfolding resolution_def instance_of⇩l⇩s_def by blast
{
have "C' ≠ {}" using appl unfolding applicable_def by auto
then have "C ≠ {}" using η_p by auto
} moreover {
have "D' ≠ {}" using appl unfolding applicable_def by auto
then have "D ≠ {}" using η_p by auto
} moreover {
have "L' ≠ {}" using appl unfolding applicable_def by auto
then have "L ≠ {}" using L_p by auto
} moreover {
have "M' ≠ {}" using appl unfolding applicable_def by auto
then have "M ≠ {}" using M_p by auto
}
ultimately have appll: "applicable C D L M τ"
using apart L_p M_p τ_p unfolding applicable_def by auto
from inst appll show ?thesis by auto
qed
section {* Completeness *}
lemma falsifies⇩g_empty:
assumes "falsifies⇩g [] C"
shows "C = {}"
proof -
have "∀l ∈ C. False"
proof
fix l
assume "l∈C"
then have "falsifies⇩l [] l" using assms by auto
then show False unfolding falsifies⇩l_def by (cases l) auto
qed
then show ?thesis by auto
qed
lemma falsifies⇩c⇩s_empty:
assumes "falsifies⇩c [] C"
shows "C = {}"
proof -
from assms obtain C' where C'_p: "instance_of⇩l⇩s C' C ∧ falsifies⇩g [] C'" by auto
then have "C'= {}" using falsifies⇩g_empty by auto
then show "C = {}" using C'_p unfolding instance_of⇩l⇩s_def by auto
qed
lemma complements_do_not_falsify':
assumes l1C1': "l⇩1 ∈ C⇩1'"
assumes l⇩2C1': "l⇩2 ∈ C⇩1'"
assumes comp: "l⇩1 = l⇩2⇧c"
assumes falsif: "falsifies⇩g G C⇩1'"
shows "False"
proof (cases l⇩1)
case (Pos p ts)
let ?i1 = "nat_from_fatom (p, ts)"
from assms have gr: "ground⇩l l⇩1" unfolding falsifies⇩l_def by auto
then have Neg: "l⇩2 = Neg p ts" using comp Pos by (cases l⇩2) auto
from falsif have "falsifies⇩l G l⇩1" using l1C1' by auto
then have "G ! ?i1 = False" using l1C1' Pos unfolding falsifies⇩l_def by (induction "Pos p ts") auto
moreover
let ?i2 = "nat_from_fatom (get_atom l⇩2)"
from falsif have "falsifies⇩l G l⇩2" using l⇩2C1' by auto
then have "G ! ?i2 = (¬sign l⇩2)" unfolding falsifies⇩l_def by meson
then have "G ! ?i1 = (¬sign l⇩2)" using Pos Neg comp by simp
then have "G ! ?i1 = True" using Neg by auto
ultimately show ?thesis by auto
next
case (Neg p ts)
let ?i1 = "nat_from_fatom (p,ts)"
from assms have gr: "ground⇩l l⇩1" unfolding falsifies⇩l_def by auto
then have Pos: "l⇩2 = Pos p ts" using comp Neg by (cases l⇩2) auto
from falsif have "falsifies⇩l G l⇩1" using l1C1' by auto
then have "G ! ?i1 = True" using l1C1' Neg unfolding falsifies⇩l_def by (metis get_atom.simps(2) literal.disc(2))
moreover
let ?i2 = "nat_from_fatom (get_atom l⇩2)"
from falsif have "falsifies⇩l G l⇩2" using l⇩2C1' by auto
then have "G ! ?i2 = (¬sign l⇩2)" unfolding falsifies⇩l_def by meson
then have "G ! ?i1 = (¬sign l⇩2)" using Pos Neg comp by simp
then have "G ! ?i1 = False" using Pos using literal.disc(1) by blast
ultimately show ?thesis by auto
qed
lemma complements_do_not_falsify:
assumes l1C1': "l⇩1 ∈ C⇩1'"
assumes l⇩2C1': "l⇩2 ∈ C⇩1'"
assumes fals: "falsifies⇩g G C⇩1'"
shows "l⇩1 ≠ l⇩2⇧c"
using assms complements_do_not_falsify' by blast
lemma other_falsified:
assumes C1'_p: "ground⇩l⇩s C⇩1' ∧ falsifies⇩g (B@[d]) C⇩1'"
assumes l_p: "l ∈ C⇩1'" "nat_from_fatom (get_atom l) = length B"
assumes other: "lo ∈ C⇩1'" "lo ≠ l"
shows "falsifies⇩l B lo"
proof -
let ?i = "nat_from_fatom (get_atom lo)"
have ground_l⇩2: "ground⇩l l" using l_p C1'_p by auto
have ground_lo: "ground⇩l lo" using C1'_p other by auto
from C1'_p have "falsifies⇩g (B@[d]) (C⇩1' - {l})" by auto
then have loB⇩2: "falsifies⇩l (B@[d]) lo" using other by auto
then have "?i < length (B @ [d])" unfolding falsifies⇩l_def by meson
then have "nat_from_fatom (get_atom lo) < length B + 1" using undiag_diag_fatom by (cases lo) auto
moreover
have l_lo: "l≠lo" using other by auto
have lc_lo: "lo ≠ l⇧c" using C1'_p l_p other complements_do_not_falsify[of lo C⇩1' l "(B@[d])"] by auto
from l_lo lc_lo have "get_atom l ≠ get_atom lo" using sign_comp_atom by metis
then have "nat_from_fatom (get_atom lo) ≠ nat_from_fatom (get_atom l)"
using nat_from_fatom_bij ground_lo ground_l⇩2 ground⇩l_ground_fatom
unfolding bij_betw_def inj_on_def by metis
then have "nat_from_fatom (get_atom lo) ≠ length B" using l_p by auto
ultimately
have "nat_from_fatom (get_atom lo) < length B" by auto
then show "falsifies⇩l B lo" using loB⇩2 shorter_falsifies⇩l by blast
qed
theorem completeness':
shows "closed_tree T Cs ⟹ ∀C∈Cs. finite C ⟹ ∃Cs'. resolution_deriv Cs Cs' ∧ {} ∈ Cs'"
proof (induction T arbitrary: Cs rule: measure_induct_rule[of treesize])
fix T::tree
fix Cs :: "fterm clause set"
assume ih: "(⋀T' Cs. treesize T' < treesize T ⟹ closed_tree T' Cs ⟹ ∀C∈Cs. finite C ⟹
∃Cs'. resolution_deriv Cs Cs' ∧ {} ∈ Cs')"
assume clo: "closed_tree T Cs"
assume finite_Cs: "∀C∈Cs. finite C"
{
assume "treesize T = 0"
then have "T=Leaf" using treesize_Leaf by auto
then have "closed_branch [] Leaf Cs" using branch_inv_Leaf clo unfolding closed_tree_def by auto
then have "falsifies⇩c⇩s [] Cs" by auto
then have "{} ∈ Cs" using falsifies⇩c⇩s_empty by auto
then have "∃Cs'. resolution_deriv Cs Cs' ∧ {} ∈ Cs'" unfolding resolution_deriv_def by auto
}
moreover
{
assume "treesize T > 0"
then have "∃l r. T=Branching l r" by (cases T) auto
then obtain B where b_p: "internal B T ∧ branch (B@[True]) T ∧ branch (B@[False]) T"
using internal_branch[of _ "[]" _ T] Branching_Leaf_Leaf_Tree by fastforce
let ?B⇩1 = "B@[True]"
let ?B⇩2 = "B@[False]"
obtain C⇩1o where C⇩1o_p: "C⇩1o ∈ Cs ∧ falsifies⇩c ?B⇩1 C⇩1o" using b_p clo unfolding closed_tree_def by metis
obtain C⇩2o where C⇩2o_p: "C⇩2o ∈ Cs ∧ falsifies⇩c ?B⇩2 C⇩2o" using b_p clo unfolding closed_tree_def by metis
let ?C⇩1 = "std⇩1 C⇩1o"
let ?C⇩2 = "std⇩2 C⇩2o"
have C⇩1_p: "falsifies⇩c ?B⇩1 ?C⇩1" using std⇩1_falsifies C⇩1o_p by auto
have C⇩2_p: "falsifies⇩c ?B⇩2 ?C⇩2" using std⇩2_falsifies C⇩2o_p by auto
have fin: "finite ?C⇩1 ∧ finite ?C⇩2" using C⇩1o_p C⇩2o_p finite_Cs by auto
from C⇩1_p obtain C⇩1' where C⇩1'_p: "ground⇩l⇩s C⇩1' ∧ instance_of⇩l⇩s C⇩1' ?C⇩1 ∧ falsifies⇩g ?B⇩1 C⇩1'" by metis
have "¬falsifies⇩c B C⇩1o" using C⇩1o_p b_p clo unfolding closed_tree_def by metis
then have "¬falsifies⇩c B ?C⇩1" using std⇩1_falsifies using prod.exhaust_sel by blast
then have l_B: "¬falsifies⇩g B C⇩1'" using C⇩1'_p by auto
from C⇩1'_p l_B obtain l⇩1 where l⇩1_p: "l⇩1 ∈ C⇩1' ∧ falsifies⇩l (B@[True]) l⇩1 ∧ ¬(falsifies⇩l B l⇩1)" by auto
let ?i = "nat_from_fatom (get_atom l⇩1)"
have ground_l⇩1: "ground⇩l l⇩1" using C⇩1'_p l⇩1_p by auto
from l⇩1_p have "¬(?i < length B ∧ B ! ?i = (¬sign l⇩1))" using ground_l⇩1 unfolding falsifies⇩l_def by meson
then have "¬(?i < length B ∧ (B@[True]) ! ?i = (¬sign l⇩1))" by (metis nth_append)
moreover
from l⇩1_p have "?i < length (B @ [True]) ∧ (B @ [True]) ! ?i = (¬sign l⇩1)" unfolding falsifies⇩l_def by meson
ultimately
have l⇩1_sign_no: "?i = length B ∧ (B @ [True]) ! ?i = (¬sign l⇩1)" by auto
from l⇩1_sign_no have l⇩1_sign: "sign l⇩1 = False" by auto
from l⇩1_sign_no have l⇩1_no: "nat_from_fatom (get_atom l⇩1) = length B" by auto
from C⇩1'_p l⇩1_no l⇩1_p have B_C⇩1'l⇩1: "falsifies⇩g B (C⇩1' - {l⇩1})"
using other_falsified by blast
from C⇩2_p obtain C⇩2' where C⇩2'_p: "ground⇩l⇩s C⇩2' ∧ instance_of⇩l⇩s C⇩2' ?C⇩2 ∧ falsifies⇩g ?B⇩2 C⇩2'" by metis
have "¬falsifies⇩c B C⇩2o" using C⇩2o_p b_p clo unfolding closed_tree_def by metis
then have "¬falsifies⇩c B ?C⇩2" using std⇩2_falsifies using prod.exhaust_sel by blast
then have l_B: "¬falsifies⇩g B C⇩2'" using C⇩2'_p by auto
from C⇩2'_p l_B obtain l⇩2 where l⇩2_p: "l⇩2 ∈ C⇩2' ∧ falsifies⇩l (B@[False]) l⇩2 ∧ ¬falsifies⇩l B l⇩2" by auto
let ?i = "nat_from_fatom (get_atom l⇩2)"
have ground_l⇩2: "ground⇩l l⇩2" using C⇩2'_p l⇩2_p by auto
from l⇩2_p have "¬(?i < length B ∧ B ! ?i = (¬sign l⇩2))" using ground_l⇩2 unfolding falsifies⇩l_def by meson
then have "¬(?i < length B ∧ (B@[False]) ! ?i = (¬sign l⇩2))" by (metis nth_append)
moreover
from l⇩2_p have "?i < length (B @ [False]) ∧ (B @ [False]) ! ?i = (¬sign l⇩2)" unfolding falsifies⇩l_def by meson
ultimately
have l⇩2_sign_no: "?i = length B ∧ (B @ [False]) ! ?i = (¬sign l⇩2)" by auto
from l⇩2_sign_no have l⇩2_sign: "sign l⇩2 = True" by auto
from l⇩2_sign_no have l⇩2_no: "nat_from_fatom (get_atom l⇩2) = length B" by auto
from C⇩2'_p l⇩2_no l⇩2_p have B_C⇩2'l⇩2: "falsifies⇩g B (C⇩2' - {l⇩2})"
using other_falsified by blast
have l⇩2cisl⇩1: "l⇩2⇧c = l⇩1"
proof -
from l⇩1_no l⇩2_no ground_l⇩1 ground_l⇩2 have "get_atom l⇩1 = get_atom l⇩2"
using nat_from_fatom_bij ground⇩l_ground_fatom
unfolding bij_betw_def inj_on_def by metis
then show "l⇩2⇧c = l⇩1" using l⇩1_sign l⇩2_sign using sign_comp_atom by metis
qed
have "applicable C⇩1' C⇩2' {l⇩1} {l⇩2} Resolution.ε" unfolding applicable_def
using l⇩1_p l⇩2_p C⇩1'_p ground⇩l⇩s_vars⇩l⇩s l⇩2cisl⇩1 empty_comp2 unfolding mgu⇩l⇩s_def unifier⇩l⇩s_def by auto
then obtain L⇩1 L⇩2 τ where L⇩1L⇩2τ_p: "applicable ?C⇩1 ?C⇩2 L⇩1 L⇩2 τ ∧ instance_of⇩l⇩s (resolution C⇩1' C⇩2' {l⇩1} {l⇩2} Resolution.ε) (resolution ?C⇩1 ?C⇩2 L⇩1 L⇩2 τ)"
using std_apart_apart C⇩1'_p C⇩2'_p lifting[of ?C⇩1 ?C⇩2 C⇩1' C⇩2' "{l⇩1}" "{l⇩2}" Resolution.ε] fin by auto
obtain C where C_p: "C = resolution ?C⇩1 ?C⇩2 L⇩1 L⇩2 τ" by auto
obtain CsNext where CsNext_p: "CsNext = Cs ∪ {?C⇩1, ?C⇩2, C}" by auto
obtain T'' where T''_p: "T'' = delete B T" by auto
have "falsifies⇩g B ((C⇩1' - {l⇩1}) ∪ (C⇩2' - {l⇩2}))" using B_C⇩1'l⇩1 B_C⇩2'l⇩2 by cases auto
then have "falsifies⇩g B (resolution C⇩1' C⇩2' {l⇩1} {l⇩2} Resolution.ε)" unfolding resolution_def empty_subls by auto
then have falsifies_C: "falsifies⇩c B C" using C_p L⇩1L⇩2τ_p by auto
have T''_smaller: "treesize T'' < treesize T" using treezise_delete T''_p b_p by auto
have T''_bran: "anybranch T'' (λb. closed_branch b T'' CsNext)"
proof (rule allI; rule impI)
fix b
assume br: "branch b T''"
from br have "b = B ∨ branch b T" using branch_delete T''_p by auto
then show "closed_branch b T'' CsNext"
proof
assume "b=B"
then show "closed_branch b T'' CsNext" using falsifies_C br CsNext_p by auto
next
assume "branch b T"
then show "closed_branch b T'' CsNext" using clo br T''_p CsNext_p unfolding closed_tree_def by auto
qed
qed
then have T''_bran2: "anybranch T'' (λb. falsifies⇩c⇩s b CsNext)" by auto
obtain T' where T'_p: "T' = cutoff (λG. falsifies⇩c⇩s G CsNext) [] T''" by auto
have T'_smaller: "treesize T' < treesize T" using treesize_cutoff[of "λG. falsifies⇩c⇩s G CsNext" "[]" T''] T''_smaller unfolding T'_p by auto
from T''_bran2 have "anybranch T' (λb. falsifies⇩c⇩s b CsNext)" using cutoff_branch[of T'' "λb. falsifies⇩c⇩s b CsNext"] T'_p by auto
then have T'_bran: "anybranch T' (λb. closed_branch b T' CsNext)" by auto
have T'_intr: "anyinternal T' (λp. ¬falsifies⇩c⇩s p CsNext)" using T'_p cutoff_internal[of T'' "λb. falsifies⇩c⇩s b CsNext"] T''_bran2 by blast
have T'_closed: "closed_tree T' CsNext" using T'_bran T'_intr unfolding closed_tree_def by auto
have finite_CsNext: "∀C∈CsNext. finite C" unfolding CsNext_p C_p resolution_def using finite_Cs fin by auto
from T'_smaller T'_closed have "∃Cs''. resolution_deriv CsNext Cs'' ∧ {} ∈ Cs''" using ih[of T' CsNext] finite_CsNext by blast
then obtain Cs'' where Cs''_p: "resolution_deriv CsNext Cs'' ∧ {} ∈ Cs''" by auto
moreover
{
have "resolution_step Cs (Cs ∪ {?C⇩1})" using std⇩1_renames standardize_apart C⇩1o_p by (metis Un_insert_right prod.collapse)
moreover
have "resolution_step (Cs ∪ {?C⇩1}) (Cs ∪ {?C⇩1} ∪ {?C⇩2})" using std⇩2_renames[of C⇩2o] standardize_apart[of C⇩2o _ ?C⇩2] C⇩2o_p by auto
then have "resolution_step (Cs ∪ {?C⇩1}) (Cs ∪ {?C⇩1,?C⇩2})" by (simp add: insert_commute)
moreover
then have "resolution_step (Cs ∪ {?C⇩1,?C⇩2}) (Cs ∪ {?C⇩1,?C⇩2} ∪ {C})"
using L⇩1L⇩2τ_p resolution_rule[of ?C⇩1 "Cs ∪ {?C⇩1,?C⇩2}" ?C⇩2 L⇩1 L⇩2 τ ] using C_p by auto
then have "resolution_step (Cs ∪ {?C⇩1,?C⇩2}) CsNext" using CsNext_p by (simp add: Un_commute)
ultimately
have "resolution_deriv Cs CsNext" unfolding resolution_deriv_def by auto
}
ultimately have "resolution_deriv Cs Cs''" unfolding resolution_deriv_def by auto
then have "∃Cs'. resolution_deriv Cs Cs' ∧ {} ∈ Cs'" using Cs''_p by auto
}
ultimately show "∃Cs'. resolution_deriv Cs Cs' ∧ {} ∈ Cs'" by auto
qed
theorem completeness:
assumes finite_cs: "finite Cs" "∀C∈Cs. finite C"
assumes unsat: "∀(F::hterm fun_denot) (G::hterm pred_denot) . ¬eval⇩c⇩s F G Cs"
shows "∃Cs'. resolution_deriv Cs Cs' ∧ {} ∈ Cs'"
proof -
from unsat have "∀(G::hterm pred_denot) . ¬eval⇩c⇩s HFun G Cs" by auto
then obtain T where "closed_tree T Cs" using herbrand assms by blast
then show "∃Cs'. resolution_deriv Cs Cs' ∧ {} ∈ Cs'" using completeness' assms by auto
qed
end