Theory Completeness
section ‹Lifting Lemma›
theory Completeness imports Resolution begin
locale unification =
assumes unification: "⋀σ L. finite L ⟹ unifier⇩l⇩s σ L ⟹ ∃θ. mgu⇩l⇩s θ L"
begin
text ‹
A proof of this assumption is available in @{file ‹Unification_Theorem.thy›} and used in
@{file ‹Completeness_Instance.thy›}.
›
lemma lifting:
assumes fin: "finite C⇩1 ∧ finite C⇩2"
assumes apart: "vars⇩l⇩s C⇩1 ∩ vars⇩l⇩s C⇩2 = {}"
assumes inst: "instance_of⇩l⇩s C⇩1' C⇩1 ∧ instance_of⇩l⇩s C⇩2' C⇩2"
assumes appl: "applicable C⇩1' C⇩2' L⇩1' L⇩2' σ"
shows "∃L⇩1 L⇩2 τ. applicable C⇩1 C⇩2 L⇩1 L⇩2 τ ∧
instance_of⇩l⇩s (resolution C⇩1' C⇩2' L⇩1' L⇩2' σ) (resolution C⇩1 C⇩2 L⇩1 L⇩2 τ)"
proof -
let ?R⇩1' = "C⇩1' - L⇩1'" and ?R⇩2' = "C⇩2' - L⇩2'"
from inst obtain γ μ where "C⇩1 ⋅⇩l⇩s γ = C⇩1' ∧ C⇩2 ⋅⇩l⇩s μ = C⇩2'"
unfolding instance_of⇩l⇩s_def by auto
then obtain η where η_p: "C⇩1 ⋅⇩l⇩s η = C⇩1' ∧ C⇩2 ⋅⇩l⇩s η = C⇩2'"
using apart merge_sub by force
from η_p obtain L⇩1 where L⇩1_p: "L⇩1 ⊆ C⇩1 ∧ L⇩1 ⋅⇩l⇩s η = L⇩1' ∧ (C⇩1 - L⇩1) ⋅⇩l⇩s η = ?R⇩1'"
using appl project_sub using applicable_def by metis
let ?R⇩1 = "C⇩1 - L⇩1"
from η_p obtain L⇩2 where L⇩2_p: "L⇩2 ⊆ C⇩2 ∧ L⇩2 ⋅⇩l⇩s η = L⇩2' ∧ (C⇩2 - L⇩2) ⋅⇩l⇩s η = ?R⇩2'"
using appl project_sub using applicable_def by metis
let ?R⇩2 = "C⇩2 - L⇩2"
from appl have "mgu⇩l⇩s σ (L⇩1' ∪ L⇩2'⇧C)" using applicable_def by auto
then have "mgu⇩l⇩s σ ((L⇩1 ⋅⇩l⇩s η) ∪ (L⇩2 ⋅⇩l⇩s η)⇧C)" using L⇩1_p L⇩2_p by auto
then have "mgu⇩l⇩s σ ((L⇩1 ∪ L⇩2⇧C) ⋅⇩l⇩s η)" using compls_subls subls_union by auto
then have "unifier⇩l⇩s σ ((L⇩1 ∪ L⇩2⇧C) ⋅⇩l⇩s η)" using mgu⇩l⇩s_def by auto
then have ησuni: "unifier⇩l⇩s (η ⋅ σ) (L⇩1 ∪ L⇩2⇧C)"
using unifier⇩l⇩s_def composition_conseq2l by auto
then obtain τ where τ_p: "mgu⇩l⇩s τ (L⇩1 ∪ L⇩2⇧C)"
using unification fin L⇩1_p L⇩2_p by (meson finite_UnI finite_imageI rev_finite_subset)
then obtain φ where φ_p: "τ ⋅ φ = η ⋅ σ" using ησuni mgu⇩l⇩s_def by auto
let ?C = "((C⇩1 - L⇩1) ∪ (C⇩2 - L⇩2)) ⋅⇩l⇩s τ"
have "?C ⋅⇩l⇩s φ = (?R⇩1 ∪ ?R⇩2 ) ⋅⇩l⇩s (τ ⋅ φ)"
using subls_union composition_conseq2ls by auto
also have "... = (?R⇩1 ∪ ?R⇩2 ) ⋅⇩l⇩s (η ⋅ σ)" using φ_p by auto
also have "... = ((?R⇩1 ⋅⇩l⇩s η) ∪ (?R⇩2 ⋅⇩l⇩s η)) ⋅⇩l⇩s σ"
using subls_union composition_conseq2ls by auto
also have "... = (?R⇩1' ∪ ?R⇩2') ⋅⇩l⇩s σ" using η_p L⇩1_p L⇩2_p by auto
finally have "?C ⋅⇩l⇩s φ = ((C⇩1' - L⇩1') ∪ (C⇩2' - L⇩2')) ⋅⇩l⇩s σ" by auto
then have ins: "instance_of⇩l⇩s (resolution C⇩1' C⇩2' L⇩1' L⇩2' σ) (resolution C⇩1 C⇩2 L⇩1 L⇩2 τ)"
using resolution_def instance_of⇩l⇩s_def by metis
have "C⇩1' ≠ {} ∧ C⇩2' ≠ {} ∧ L⇩1' ≠ {} ∧ L⇩2' ≠ {}"
using appl applicable_def by auto
then have "C⇩1 ≠ {} ∧ C⇩2 ≠ {} ∧ L⇩1 ≠ {} ∧ L⇩2 ≠ {}" using η_p L⇩1_p L⇩2_p by auto
then have appli: "applicable C⇩1 C⇩2 L⇩1 L⇩2 τ"
using apart L⇩1_p L⇩2_p τ_p applicable_def by auto
from ins appli 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_of_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_of_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_of_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_of_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_of_fatom (get_atom l) = length B"
assumes other: "lo ∈ C⇩1'" "lo ≠ l"
shows "falsifies⇩l B lo"
proof -
let ?i = "nat_of_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_of_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_of_fatom (get_atom lo) ≠ nat_of_fatom (get_atom l)"
using nat_of_fatom_bij ground_lo ground_l⇩2 ground⇩l_ground_fatom
unfolding bij_betw_def inj_on_def by metis
then have "nat_of_fatom (get_atom lo) ≠ length B" using l_p by auto
ultimately
have "nat_of_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':
assumes "closed_tree T Cs"
assumes "∀C∈Cs. finite C"
shows "∃Cs'. resolution_deriv Cs Cs' ∧ {} ∈ Cs'"
using assms 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_of_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_of_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_of_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_of_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_of_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)
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
definition E_conv :: "('a ⇒ 'b) ⇒ 'a var_denot ⇒ 'b var_denot" where
"E_conv b_of_a E ≡ λx. (b_of_a (E x))"
definition F_conv :: "('a ⇒ 'b) ⇒ 'a fun_denot ⇒ 'b fun_denot" where
"F_conv b_of_a F ≡ λf bs. b_of_a (F f (map (inv b_of_a) bs))"
definition G_conv :: "('a ⇒ 'b) ⇒ 'a pred_denot ⇒ 'b pred_denot" where
"G_conv b_of_a G ≡ λp bs. (G p (map (inv b_of_a) bs))"
lemma eval⇩t_bij:
assumes "bij (b_of_a::'a ⇒ 'b)"
shows"eval⇩t (E_conv b_of_a E) (F_conv b_of_a F) t = b_of_a (eval⇩t E F t)"
proof (induction t)
case (Fun f ts)
then have "map (inv b_of_a ∘ eval⇩t (E_conv b_of_a E) (F_conv b_of_a F)) ts = eval⇩t⇩s E F ts"
unfolding E_conv_def F_conv_def
using assms bij_is_inj by fastforce
then have "b_of_a (F f (map (inv b_of_a ∘ eval⇩t (E_conv b_of_a E) ((F_conv b_of_a F))) ts)) = b_of_a (F f (eval⇩t⇩s E F ts))" by metis
then show ?case using assms unfolding E_conv_def F_conv_def by auto
next
case (Var x)
then show ?case using assms unfolding E_conv_def by auto
qed
lemma eval⇩t⇩s_bij:
assumes "bij (b_of_a::'a ⇒ 'b)"
shows "G_conv b_of_a G p (eval⇩t⇩s (E_conv b_of_a E) (F_conv b_of_a F) ts) = G p (eval⇩t⇩s E F ts)"
using assms using eval⇩t_bij
proof -
have "map (inv b_of_a ∘ eval⇩t (E_conv b_of_a E) (F_conv b_of_a F)) ts = eval⇩t⇩s E F ts"
using eval⇩t_bij assms bij_is_inj by fastforce
then show ?thesis
by (metis (no_types) G_conv_def map_map)
qed
lemma eval⇩l_bij:
assumes "bij (b_of_a::'a ⇒ 'b)"
shows "eval⇩l (E_conv b_of_a E) (F_conv b_of_a F) (G_conv b_of_a G) l = eval⇩l E F G l"
using assms eval⇩t⇩s_bij
proof (cases l)
case (Pos p ts)
then show ?thesis
by (simp add: eval⇩t⇩s_bij assms)
next
case (Neg p ts)
then show ?thesis
by (simp add: eval⇩t⇩s_bij assms)
qed
lemma eval⇩c_bij:
assumes "bij (b_of_a::'a ⇒ 'b)"
shows "eval⇩c (F_conv b_of_a F) (G_conv b_of_a G) C = eval⇩c F G C"
proof -
{
fix E :: "char list ⇒ 'b"
assume bij_b_of_a: "bij b_of_a"
assume C_sat: "∀E :: char list ⇒ 'a. ∃l∈C. eval⇩l E F G l"
have E_p: "E = E_conv b_of_a (E_conv (inv b_of_a) E)"
unfolding E_conv_def using bij_b_of_a
using bij_betw_inv_into_right by fastforce
have "∃l∈C. eval⇩l (E_conv b_of_a (E_conv (inv b_of_a) E)) (F_conv b_of_a F) (G_conv b_of_a G) l"
using eval⇩l_bij bij_b_of_a C_sat by blast
then have "∃l∈C. eval⇩l E (F_conv b_of_a F) (G_conv b_of_a G) l" using E_p by auto
}
then show ?thesis
by (meson eval⇩l_bij assms eval⇩c_def)
qed
lemma eval⇩c⇩s_bij:
assumes "bij (b_of_a::'a ⇒ 'b)"
shows "eval⇩c⇩s (F_conv b_of_a F) (G_conv b_of_a G) Cs ⟷ eval⇩c⇩s F G Cs"
by (meson eval⇩c_bij assms eval⇩c⇩s_def)
lemma countably_inf_bij:
assumes inf_a_uni: "infinite (UNIV :: ('a ::countable) set)"
assumes inf_b_uni: "infinite (UNIV :: ('b ::countable) set)"
shows "∃b_of_a :: 'a ⇒ 'b. bij b_of_a"
proof -
let ?S = "UNIV :: (('a::countable)) set"
have "countable ?S" by auto
moreover
have "infinite ?S" using inf_a_uni by auto
ultimately
obtain nat_of_a where QWER: "bij (nat_of_a :: 'a ⇒ nat)" using countableE_infinite[of ?S] by blast
let ?T = "UNIV :: (('b::countable)) set"
have "countable ?T" by auto
moreover
have "infinite ?T" using inf_b_uni by auto
ultimately
obtain nat_of_b where TYUI: "bij (nat_of_b :: 'b ⇒ nat)" using countableE_infinite[of ?T] by blast
let ?b_of_a = "λa. (inv nat_of_b) (nat_of_a a)"
have bij_nat_of_b: "∀n. nat_of_b (inv nat_of_b n) = n"
using TYUI bij_betw_inv_into_right by fastforce
have "∀a. inv nat_of_a (nat_of_a a) = a"
by (meson QWER UNIV_I bij_betw_inv_into_left)
then have "inj (λa. inv nat_of_b (nat_of_a a))"
using bij_nat_of_b injI by (metis (no_types))
moreover
have "range (λa. inv nat_of_b (nat_of_a a)) = UNIV"
by (metis QWER TYUI bij_def image_image inj_imp_surj_inv)
ultimately
have "bij ?b_of_a"
unfolding bij_def by auto
then show ?thesis by auto
qed
lemma infinite_hterms: "infinite (UNIV :: hterm set)"
proof -
let ?diago = "λn. HFun (string_of_nat n) []"
let ?undiago = "λa. nat_of_string (case a of HFun f ts ⇒ f)"
have "∀n. ?undiago (?diago n) = n" using nat_of_string_string_of_nat by auto
moreover
have "∀n. ?diago n ∈ UNIV" by auto
ultimately show "infinite (UNIV :: hterm set)" using infinity[of ?undiago ?diago UNIV] by simp
qed
theorem completeness_countable:
assumes inf_uni: "infinite (UNIV :: ('u :: countable) set)"
assumes finite_cs: "finite Cs" "∀C∈Cs. finite C"
assumes unsat: "∀(F::'u fun_denot) (G::'u pred_denot). ¬eval⇩c⇩s F G Cs"
shows "∃Cs'. resolution_deriv Cs Cs' ∧ {} ∈ Cs'"
proof -
have "∀(F::hterm fun_denot) (G::hterm pred_denot) . ¬eval⇩c⇩s F G Cs"
proof (rule; rule)
fix F :: "hterm fun_denot"
fix G :: "hterm pred_denot"
obtain u_of_hterm :: "hterm ⇒ 'u" where p_u_of_hterm: "bij u_of_hterm"
using countably_inf_bij inf_uni infinite_hterms by auto
let ?F = "F_conv u_of_hterm F"
let ?G = "G_conv u_of_hterm G"
have "¬ eval⇩c⇩s ?F ?G Cs" using unsat by auto
then show "¬ eval⇩c⇩s F G Cs" using eval⇩c⇩s_bij using p_u_of_hterm by auto
qed
then show "∃Cs'. resolution_deriv Cs Cs' ∧ {} ∈ Cs'" using finite_cs completeness by auto
qed
theorem completeness_nat:
assumes finite_cs: "finite Cs" "∀C∈Cs. finite C"
assumes unsat: "∀(F::nat fun_denot) (G::nat pred_denot) . ¬eval⇩c⇩s F G Cs"
shows "∃Cs'. resolution_deriv Cs Cs' ∧ {} ∈ Cs'"
using assms completeness_countable by blast
end
end